Win32_Service:使用 PowerShell 中的 SetSecurityDescriptor()

And*_*ehm 2 powershell wmi

我正在尝试从 PowerShell 为 Windows 服务的用户设置权限。但 WMI 完全忽略我的更改。我究竟做错了什么?

$service = Get-WmiObject -EnableAllPrivileges Win32_Service | Where-Object {$_.Name -eq "HubertService"}
$descriptor = $service.GetSecurityDescriptor()
$descriptor.Descriptor.Owner
Run Code Online (Sandbox Code Playgroud)

到目前为止这有效。我现在有了一个很好的安全描述符。我可以显示所有者。

现在,如果我更改任何内容,例如其中一个 ACE 的 AccessMask,这也有效:

$descriptor.Descriptor.DACL[0].AccessMask = 0
Run Code Online (Sandbox Code Playgroud)

我什至可以将此修改后的描述符写入我的 Win32_Service 对象:

$service.InvokeMethod("SetSecurityDescriptor", $descriptor, $null)
Run Code Online (Sandbox Code Playgroud)

然而,之前和之后

$service.Put()
Run Code Online (Sandbox Code Playgroud)

当我创建新的 $service 变量并对其运行 GetSecurityDeciptor() 时,修改根本不会显示。

我究竟做错了什么?

And*_*ehm 5

经过一番尝试,我找到了解决方案。

# Get service object and its security descriptor
$service = Get-WmiObject -EnableAllPrivileges Win32_Service | Where-Object {$_.Name -eq "HubertService"}
$sd = ($service.GetSecurityDescriptor()).Descriptor
$adacl = $sd.DACL
$adacl.Count # Shows current number of ACEs in the DACL

# Create new ACE for new user to add
$ace = ([WMIClass]"Win32_ACE").CreateInstance()
$trustee = ([WMIClass]"Win32_Trustee").CreateInstance()
$account = New-Object System.Security.Principal.NTAccount("mydomain","hubert")
$sid = $account.Translate([System.Security.Principal.SecurityIdentifier])

# Fill in trustee and add trustee to ACE
$trustee.Domain = "mydomain"
$trustee.Name = "hubert"
$trustee.SIDString = $sid.Value # Don't need byte array
$ace.Trustee = $trustee

# Add ACE to DACL and replace DACL in security descriptor
$adacl += $ace
$sd.DACL = $adacl
$service.SetSecurityDescriptor($sd) # This appears to work just like that
Run Code Online (Sandbox Code Playgroud)

还可以通过将 DACL 替换为不删除 ACE 的 DACL 来再次删除新的 ACE。