I’ve talked about WMI before… WMI and the WBEMTEST – Zewwy’s Info Tech Talks however, in that blog post I simply stated “lets grant it the basic enable and remote access on the WMI object… so back on the server we want to be monitored via WMI…” and simply opened up wmimgmt (WMI Control MMC snapin), and expanded the root node under the security tab…
So easy.. until it’s not… duhh duuhhh duhhhhhh, Core Server. Now some of you might be snapping, like “duhhhh the WMI Control has connect to remote server, just use a management machine to remotely connect using it”. Until you realize that even though the connection appears fine:
Attempting to expand the Root node does nothing:
I don’t know about you, but that’s usually how I deal with this. Now server core doesn’t have this tool available to run locally, so you can’t do it directly at the server either. What do we do?
If you just need to audit a namespace specifically you can just call the systemsecurity class’s getSecurityDescriptor method via wmic:
wmic /namespace:\\root\cimv2 path __systemsecurity call getSecurityDescriptor
this is just a string output though, and you also kinda have to now what each “mask” is supposed to represent. If you need a quick one off to check between servers for differences, it works.
During my research into this I found an old Microsoft blog post from a “Principal Software Engineer” named Steve Lee. Dissecting the script I found you could manually iterate through each in a more proper object oriented manner using “invoke-WmiMethod”
((Invoke-WmiMethod -Name GetSecurityDescriptor -Namespace "root\cimv2" -path "__systemsecurity=@").Descriptor).DACL[0].Trustee.Name
and manually iterating the array “DACL[0…x]” in the powershell cmdlet. All his script does it build an object array of users and then spits them back out… here I tweaked it for simple local runage to verify that I had 4 objects with permissions on as I iterated above…
Param ( [parameter(Mandatory=$true,Position=0)][string] $namespace)
Process {
$ErrorActionPreference = "Stop"
Function Get-PermissionFromAccessMask($accessMask) {
$WBEM_ENABLE = 1
$WBEM_METHOD_EXECUTE = 2
$WBEM_FULL_WRITE_REP = 4
$WBEM_PARTIAL_WRITE_REP = 8
$WBEM_WRITE_PROVIDER = 0x10
$WBEM_REMOTE_ACCESS = 0x20
$READ_CONTROL = 0x20000
$WRITE_DAC = 0x40000
$WBEM_RIGHTS_FLAGS = $WBEM_ENABLE,$WBEM_METHOD_EXECUTE,$WBEM_FULL_WRITE_REP, $WBEM_PARTIAL_WRITE_REP,$WBEM_WRITE_PROVIDER,$WBEM_REMOTE_ACCESS, $WBEM_RIGHT_SUBSCRIBE,$WBEM_RIGHT_PUBLISH,$READ_CONTROL,$WRITE_DAC
$WBEM_RIGHTS_STRINGS = "Enable","MethodExecute","FullWrite","PartialWrite", "ProviderWrite","RemoteAccess","Subscribe","Publish","ReadSecurity","WriteSecurity"
$permission = @()
for ($i = 0; $i -lt $WBEM_RIGHTS_FLAGS.Length; $i++) {
if (($accessMask -band $WBEM_RIGHTS_FLAGS[$i]) -gt 0) {
$permission += $WBEM_RIGHTS_STRINGS[$i]
}
}
$permission
}
$INHERITED_ACE_FLAG = 0x10
$invokeparams = @{Namespace=$namespace;Path="__systemsecurity=@";Name="GetSecurityDescriptor"}
$output = Invoke-WmiMethod @invokeparams
if ($output.ReturnValue -ne 0) {
throw "GetSecurityDescriptor failed: $($output.ReturnValue)"
}
$acl = $output.Descriptor
foreach ($ace in $acl.DACL) {
$user = New-Object System.Management.Automation.PSObject
$user | Add-Member -MemberType NoteProperty -Name "Name" -Value "$($ace.Trustee.Domain)\$($ace.Trustee.Name)"
$user | Add-Member -MemberType NoteProperty -Name "Permission" -Value (Get-PermissionFromAccessMask($ace.AccessMask))
$user | Add-Member -MemberType NoteProperty -Name "Inherited" -Value (($ace.AceFlags -band $INHERITED_ACE_FLAG) -gt 0)
$user
}
}
and sure enough:
But, how do you add or delete? Here’s Graeme Bray updated version of Steve Lee’s set script.
It was a bit annoying noticing that permissions is set as an optional (not mandatory) parameter (for delete operation), so when called all mandatory ones get asked, but if you pick add, it just flops cause that parameter isn’t marked as mandatory, so you gotta shove it inline after all the other ones:
Can I set permissions without a third party script? in theory, yes, but have fun building each object manually (lines 148 – 169). I generally would love to pump out a oneliner but that would seem to be a little difficult considering the script is 200 lines of code.
And deleting via the script:
Or use the “official” PowerShell Gallery | WmiNamespaceSecurity 0.3.0 module.
Install-Module -Name WmiNamespaceSecurity
requires trusting the good ol PSGallery. Whatever it takes.
I unno, I’m not an expert at this DCS rubbish.. so, I couldn’t get the latest module to work for me. I’m not building a whole “configuration file”, a “MOF (Managed Object Format)” to run some BS “DSC (Desired State Configuration)” via some BS “Start-DSCConfiguration” or “mofcomp.exe” just cause this stupid ass fucking WMI security uses some BS “SDDL (Security Descriptor Definition Language)” of gobbly gook shit ACL design.
Fuck WMI… shits so annoying. Just use the old script which was simple and it worked, man over engineered shit these days… all this shit cause I couldn’t expand an object in an existing remote tool. Fuck me.


























