Set WMI permissions for 'Domain users'

血红的双手。 提交于 2019-12-24 13:45:20

问题


I've created two functions in PowerShell, one that creates the Namespace ROOT\CustomCMClasses and one that creates the class Test. This piece works fine:

Param (
    $Namespace = 'CustomCMClasses',
    $Class     = 'Test'
)

Function New-WMINamespaceHC{
    if (Get-WmiObject -Namespace 'root' -Class '__NAMESPACE' | Where-Object {$_.Name -eq $Namespace}) {
        Write-Verbose "WMI Namespace 'root\$Namespace' exists"
    }
    else {
        Write-Verbose "Create WMI namespace 'root\$Namespace'"
        $Ns = [WMICLASS]'root:__Namespace' 
        $NewNamespace = $Ns.createInstance() 
        $NewNamespace.Name = $Namespace 
        $NewNamespace.Put() 
    }
}

Function New-WMIClassHC {
    if (Get-WmiObject -List -Namespace "root\$Namespace" | Where-Object {$_.Name -eq $Class}) {
        Write-Verbose "WMI Class '$Class' exists"
    }
    else {
        Write-Verbose "Create WMI Class '$Class'"
        $NewClass = New-Object System.Management.ManagementClass ("root\$Namespace", [String]::Empty, $Null); 
        $NewClass['__CLASS'] = $Class
        $NewClass.Qualifiers.Add('Static', $true)
        $NewClass.Properties.Add('Key', [System.Management.CimType]::String, $false)
        $NewClass.Properties['Key'].Qualifiers.Add('Key', $true)
        $NewClass.Properties.Add('Value1', [System.Management.CimType]::UInt32, $false)
        $NewClass.Properties.Add('Value2', [System.Management.CimType]::String, $false)
        $NewClass.Put()
    }
}

At this point I need to grant Domain users permissions on the new namespace, so they are able to write data to it on their local client (no remoting needed). This is the point where I find a lot of information but am now stuck.

On the Microsoft blog there is a script I tried to tweak, but it's overly complicated for my needs and it failed so I found and tweaked the following code:

Function Add-WMIPermissions {
    [CmdLetBinding()]
    Param (
        [String]$Principal = 'DOMAIN.NET\Domain users',
        [String]$Namespace = 'CustomCMClasses'
    )

    Function Get-Sid {
        Param (
            $DSIdentity
        )
         $ID = new-object System.Security.Principal.NTAccount($DSIdentity)
         Return $ID.Translate([System.Security.Principal.SecurityIdentifier]).toString()
    }

    $Sid = Get-Sid $Principal

    $WMISDDL = "A;CI;CCWP;;;$Sid" 
    $WMISDDLPartialMatch = "A;\w*;\w+;;;$Sid"

    $security = Get-WmiObject -Namespace root\$Namespace -Class __SystemSecurity
    $binarySD = @($null)
    $result = $security.PsBase.InvokeMethod('GetSD',$binarySD)

    $converter = New-Object system.management.ManagementClass Win32_SecurityDescriptorHelper
    $CurrentWMISDDL = $converter.BinarySDToSDDL($binarySD[0])

    if (($CurrentWMISDDL.SDDL -match $WMISDDLPartialMatch) -and ($CurrentWMISDDL.SDDL -notmatch $WMISDDL)) {
        $NewWMISDDL = $CurrentWMISDDL.SDDL -replace $WMISDDLPartialMatch, $WMISDDL
    }
    else {
        $NewWMISDDL = $CurrentWMISDDL.SDDL += '(' + $WMISDDL + ')'
    }

    $WMIbinarySD = $converter.SDDLToBinarySD($NewWMISDDL)
    $WMIconvertedPermissions = ,$WMIbinarySD.BinarySD

    if ($CurrentWMISDDL.SDDL -match $WMISDDL) {
        Write-Verbose 'Current WMI Permissions matches desired value'
    }
    else {
        $result = $security.PsBase.InvokeMethod('SetSD',$WMIconvertedPermissions) 
        if($result='0'){
            Write-Verbose 'WMI permissions applied'
        }
    }
}

Add-WMIPermissions -Verbose

It's clearly stating that the permissions are correctly applied but the user still can't write data to WMI. Working with WMI is new to me, so any help is greatly appreciated.

The test code to see if a regular user (Domain users) has permissions:

$WMIClass = [WMICLASS]('root\' + $Namespace + ':' + $Class)
$WMIInstance = $WMIClass.CreateInstance()
$WMIInstance.Key =  'Unique value identifier 5'
$WMIInstance.Value1 = 101
$WMIInstance.Value2 = 'Status Ok'
$WMIInstance.Put()

回答1:


Solved the problem for Partial Write:

Function Set-WMIPermissionsHC {
    Param (
        [String]$Namespace = 'CustomCMClasses',
        [String]$Class     = 'Test',
        [String]$Account   = 'DOMAIN\Domain users',
        [String]$Computer  = $env:COMPUTERNAME
    )

    Function Get-Sid {
        Param (
            $Account
        )
        $ID = New-Object System.Security.Principal.NTAccount($Account)
        Return $ID.Translate([System.Security.Principal.SecurityIdentifier]).toString()
    }

    $SID = Get-Sid $Account
    $SDDL = "A;CI;CCSWWP;;;$SID"
    $DCOMSDDL = "A;;CCDCRP;;;$SID"
    $Reg = [WMICLASS]"\\$Computer\root\default:StdRegProv"
    $DCOM = $Reg.GetBinaryValue(2147483650,'software\microsoft\ole','MachineLaunchRestriction').uValue
    $Security = Get-WmiObject -ComputerName $Computer -Namespace "root\$Namespace" -Class __SystemSecurity
    $Converter = New-Object System.Management.ManagementClass Win32_SecurityDescriptorHelper
    $BinarySD = @($null)
    $Result = $Security.PsBase.InvokeMethod('GetSD', $BinarySD)
    $OutSDDL = $Converter.BinarySDToSDDL($BinarySD[0])
    $OutDCOMSDDL = $Converter.BinarySDToSDDL($DCOM)
    $NewSDDL = $OutSDDL.SDDL += '(' + $SDDL + ')'
    $NewDCOMSDDL = $OutDCOMSDDL.SDDL += '(' + $DCOMSDDL + ')'
    $WMIbinarySD = $Converter.SDDLToBinarySD($NewSDDL)
    $WMIconvertedPermissions = ,$WMIbinarySD.BinarySD
    $DCOMbinarySD = $Converter.SDDLToBinarySD($NewDCOMSDDL)
    $DCOMconvertedPermissions = ,$DCOMbinarySD.BinarySD
    $Result = $Security.PsBase.InvokeMethod('SetSD', $WMIconvertedPermissions)
    $Result = $Reg.SetBinaryValue(2147483650,'software\microsoft\ole','MachineLaunchRestriction', $DCOMbinarySD.binarySD)
    Write-Verbose 'WMI Permissions set'
}

Thanks to this blog and the Microsoft blog for explaining the permissions



来源:https://stackoverflow.com/questions/36132700/set-wmi-permissions-for-domain-users

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!