2013-12-16 30 views
1

我試圖從PowerShell爲Windows服務上的用戶設置權限。但是WMI完全忽略了我的改變。我究竟做錯了什麼?Win32_Service:使用PowerShell中的SetSecurityDescriptor()

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

到目前爲止這項工作。我現在有一個很好的安全描述符。我可以顯示所有者。

現在,如果我改變任何東西,例如將ACE之一AccessMask,這個工程太:

$descriptor.Descriptor.DACL[0].AccessMask = 0 

我甚至可以寫這個修改的描述我win32_service時對象:

$service.InvokeMethod("SetSecurityDescriptor", $descriptor, $null) 

然而,前後

$service.Put() 

修改乾脆不露面的時候我創建一個新的$ service變量並在其上運行GetSecurityDesciptor()。

我在做什麼錯?

回答

4

經過一番嘗試,我找到了一個解決方案。

# 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 

新的ACE也可以通過將DACL替換爲不帶ACE的DACL來刪除。