# Create local "WMI Remote Readers" group and grant read only permissions to WMI for it. # NOTE: "Distributed COM Users" group membership is also needed. $groupName = "WMI Remote Readers" $groupDescription = "Members of this group can remotely read WMI" $group = Get-LocalGroup -Name $groupName -ErrorAction SilentlyContinue if ($group) { return } New-LocalGroup -Name $groupName -Description $groupDescription # Get current ACL Write-Host "Get Security Descriptor from WMI" $sd = Invoke-WmiMethod -Namespace "root" -Class "__systemsecurity" -Name "GetSecurityDescriptor" $acl = $sd.Descriptor # Get target account WMI object Write-Host "Finding Win32 account" $Win32Account = Get-WmiObject -Class Win32_Account -Filter "Domain='$env:COMPUTERNAME' and Name='$groupName'" if (-not $Win32Account) { Write-Error "Win32 account $env:COMPUTERNAME\$groupName not found" return } # Create access control entry Write-Host "Creating new access control entry" $ace=(New-Object System.Management.ManagementClass("Win32_Ace")).CreateInstance() $ace.AccessMask = 0x20 # RemoteEnable $ace.AceFlags = 0x2 # Inherit to sub objects $ace.AceType = 0x0 # Allow # The TRUSTEE structure identifies the group account to which an access control entry (ACE) applies. # The structure can use a name or a security identifier (SID) to identify the trustee. Write-Host "Creating new trustee" $trustee=(New-Object System.Management.ManagementClass("Win32_Trustee")).CreateInstance() $trustee.SidString = $Win32Account.SID $ace.Trustee=$trustee # Add new ACE to ACL and apply it $acl.DACL += $ace Write-Host "Set Security Descriptor to WMI" Invoke-WmiMethod -Namespace "root" -Path "__systemsecurity=@" -Name "SetSecurityDescriptor" -ArgumentList $acl # Force refresh by querying the namespace (optional step) Get-WmiObject -Namespace $namespace -Class "__namespace" | Out-Null