为“域用户”

时间:2016-03-21 13:45:01

标签: powershell permissions wmi

我在PowerShell中创建了两个函数,一个用于创建命名空间ROOT\CustomCMClasses,另一个用于创建类Test。这件作品很好:

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()
    }
}

此时我需要对新命名空间授予Domain users权限,以便他们能够在本地客户端上向其写入数据(无需远程处理)。这是我发现很多信息但我现在陷入困境的地方。

在Microsoft博客上有一个script我尝试调整,但它的过于复杂,我的需求却失败了所以我发现并调整了following代码:

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

明确说明权限已正确应用但用户仍无法将数据写入WMI。使用WMI对我来说是新的,所以非常感谢任何帮助。

用于查看普通用户(Domain users)是否具有权限的测试代码:

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

1 个答案:

答案 0 :(得分:0)

解决了部分写入

的问题
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'
}

感谢this blogMicrosoft blog解释权限