我似乎无法通过Power
shell设置WMI ACL.调用
- Invoke-WmiMethod -Name "SetSecurityDescriptor" -Path "__systemsecurity=@" -ArgumentList $acl.psobject.immediateBaSEObject
返回此异常:
- Invoke-WmiMethod : Invalid method Parameter(s)
- At line:1 char:17.
- + Invoke-WmiMethod <<<< -Name "SetSecurityDescriptor" -Path "__systemsecurity=@" -ArgumentList $acl.psobject.immediateBaSEObject
- + CategoryInfo : InvalidOperation: (:) [Invoke-WmiMethod],ManagementException
- + FullyQualifiedErrorId : InvokeWMIManagementException,Microsoft.PowerShell.Commands.InvokeWmiMethod
SetSecurityDescriptor只接受__SecurityDescriptor类型的一个参数,而我在-Arguments中使用的$acl对象本身似乎没问题:
- PS C:\Windows\system32> $acl | gm
- TypeName: System.Management.ManagementBaSEObject#\__SecurityDescriptor
- Name MemberType Definition
- ---- ---------- ----------
- ControlFlags Property System.UInt32 ControlFlags {get;set;}
- DACL Property System.Management.ManagementObject#__ACE[] DACL ...
- Group Property System.Management.ManagementObject#__ACE Group {...
- Owner Property System.Management.ManagementObject#__ACE Owner {...
- SACL Property System.Management.ManagementObject#__ACE[] SACL ...
- TIME_CREATED Property System.UInt64 TIME_CREATED {get;set;}
- __CLASS Property System.String __CLASS {get;set;}
- __DERIVATION Property System.String[] __DERIVATION {get;set;}
- __DYNASTY Property System.String __DYNASTY {get;set;}
- __GENUS Property System.Int32 __GENUS {get;set;}
- __NAMESPACE Property System.String __NAMESPACE {get;set;}
- __PATH Property System.String __PATH {get;set;}
- __PROPERTY_COUNT Property System.Int32 __PROPERTY_COUNT {get;set;}
- __RELPATH Property System.String __RELPATH {get;set;}
- __SERVER Property System.String __SERVER {get;set;}
- __SUPERCLASS Property System.String __SUPERCLASS {get;set;}
从I can get off the docs开始,我调用参数集:路径重载,因此参数集似乎不会缺少必需的参数.
我基本上是在this MSDN blog post on the very same topic上删除代码,而使用类似调用的GetSecurityDescriptor会提供所需的结果:
- $output = Invoke-WmiMethod -Path "__systemsecurity=@" -Name GetSecurityDescriptor
SetSecurityDescriptor不断向我抛出异常.我如何让它工作?
上下文中的代码,供参考:
- # connect to SystemSecurity
- $invokeparams = @{Path="__systemsecurity=@"}
- # get SecurityDescriptor with ACL
- $output = Invoke-WmiMethod @invokeparams -Name GetSecurityDescriptor
- if ($output.ReturnValue -ne 0) {
- throw "GetSecurityDescriptor Failed: $($output.ReturnValue)"
- }
- # ACL object reference is in the .Descriptor property
- $acl = $output.Descriptor
- $ace = (New-Object System.Management.ManagementClass("win32_Ace")).CreateInstance()
- # AccessMask is WBEM_ENABLE,$WBEM_METHOD_EXECUTE,$WBEM_WRITE_PROVIDER,$WBEM_REMOTE_ACCESS
- $ace.AccessMask = 1 + 2 + 0x10 + 0x20
- # AceFlags are $OBJECT_INHERIT_ACE_FLAG,$CONTAINER_INHERIT_ACE_FLAG
- $ace.AceFlags = 0x01 + 0x2
- # AceType is ACCESS_ALLOWED_ACE_TYPE
- $ace.AceType = 0x1
- # get user SID
- $getparams = @{Class="Win32_Account";Filter="Domain='MYDOMAIN' and Name='SERVER$'"}
- $win32account = Get-WmiObject @getparams
- # and build a new Trustee object
- $trustee = (New-Object System.Management.ManagementClass("win32_Trustee")).CreateInstance()
- $trustee.SidString = $win32account.Sid
- $ace.Trustee = $trustee
- # Add ACE to ACL
- $acl.DACL += $ace.psobject.immediateBaSEObject
- # apply new ACL
- $setparams = @{Name="SetSecurityDescriptor";ArgumentList=$acl.psobject.immediateBaSEObject} + $invokeParams
- $output = Invoke-WmiMethod @setparams
- if ($output.ReturnValue -ne 0) {
- throw "SetSecurityDescriptor Failed: $($output.ReturnValue)"
- }
我也已经尝试过播放aforementioned blog post by Steve Lee评论中建议的.AceFlags属性 – 无济于事.