37

I'm writing a monitoring service that uses WMI to get information from remote machines. Having local admin rights on all these machines is not possible for political reasons.

Is this possible? What permissions/rights does my user require for this?

jpoh
  • 801
  • 1
  • 8
  • 13

9 Answers9

35

The following works on Window 2003 R2 SP 2, Windows Server 2012 R2

  1. Add the user(s) in question to the Performance Monitor Users group
  2. Under Services and Applications, bring up the properties dialog of WMI Control (or run wmimgmt.msc). In the Security tab, highlight Root/CIMV2, click Security; add Performance Monitor Users and enable the options : Enable Account and Remote Enable
  3. Run dcomcnfg. At Component Services > Computers > My Computer, in the COM security tab of the Properties dialog click "Edit Limits" for both Access Permissions and Launch and Activation Permissions. Add Performance Monitor Users and allow remote access, remote launch, and remote activation.
  4. Select Windows Management Instrumentation under Component Services > Computers > My Computer > DCOM Config and give Remote Launch and Remote Activation privileges to Performance Monitor Users Group.

Notes:

  • As an alternatively to step 3 and 4, one can assign the user to the group Distributed COM Users (Tested on Windows Server 2012 R2)
  • If the user needs access to all the namespaces, you can set the settings in 2. at the Root level, and recurse the permissions to the sub-namespaces via the Advanced window in Security
Thomas B in BDX
  • 147
  • 1
  • 1
  • 10
jpoh
  • 801
  • 1
  • 8
  • 13
  • 3
    I've found steps 2 and 3 aren't necessary if you add the user to Distributed COM Users. – Nexus Feb 12 '10 at 00:53
  • Working on WinXP and Win7, I was not able to add the "Distributed COM Users" group - maybe this group is only accessible on servers? It would not resolve during name lookup when trying to add to the permissions. Also, I found that I had to set permissions for WMI on "Root" as well as "Root/CIMV2" and that I had to go into advanced permissions and apply the permission for the subnamespaces as well as the namespace. – Shannon Wagner Aug 03 '12 at 20:26
  • Works also for Windows 8! Also, does somebody know how to do the same from powershell or some other shell? – Bunyk Mar 24 '14 at 09:02
  • 2
    In the case that you want a user to be able to access all the namespace, you can grant the permission to **Root** and all the sub-namespaces by selecting Root, opening **Security** then **Advanced** and setting up the recursion. By default these settings apply only to the selected object and **do not** cascade. – Thomas B in BDX Aug 22 '14 at 20:23
  • that doesn't work for MSCluster namespace – John Jan 13 '16 at 08:52
5

All I did on Windows 8 was added user to group "Remote Management Users", and remote WQL requests worked.

Bunyk
  • 1,314
  • 2
  • 11
  • 16
2

By default, only the local Administrators group has remote permissions to WMI. You will have to customise the WMI "Remote Enable" permissions.

ThatGraemeGuy
  • 15,314
  • 12
  • 51
  • 78
2

You may also have to grant "DCOM remote access permissions" and/or "DCOM remote launch and activation permissions" depending on what exactly you are trying to do. This MSDN article gives the step-by-step procedures.

KevinH
  • 644
  • 4
  • 7
1

The following worked for me in a 2012 r2 domain environment although I only managed to do it per server and not the entire domain:

1) Add user to Performance Log Users Group. 2) Run wmimgmt.msc, right click "WMI Control (LOCAL), goto Security tab and grant the appropriate user "Enable Account" and "Remote Enable" on the desired namespace (usualy CIMV2).

If I manage to get it done for the entire domain I'll come back and update.

JustAGuy
  • 629
  • 3
  • 18
  • 35
1

Based on the chosen answer, I modified the script from Microsoft to set the WMI security. My test user was a non-administrative domain user who was a member of the "Remote Management Users" on the local system for reasons not related to this issue. After granting my user the EnableAccount, RemoteEnable, and ExecuteMethods permissions on the target namespace, I was able to access WMI.

So, I did not add my user to the Performance Monitor Users or Distributed COM Users local groups.

A couple of notes regarding the script:

  1. You must specify the full path of the namespace. In my case, the namespace was Root/Microsoft/SqlServer
  2. Inheritance was wrong. Because there are no leaf objects you can't use $OBJECT_INHERIT_ACE_FLAG
  3. I got rid of the embedded function because it was too small and it was only used once.

The script is below. I named it Set-WMINamespaceSsecurity.ps1

Param ([Parameter(Mandatory=$true,Position=0)] [string]$Namespace,
       [Parameter(Mandatory=$true,Position=1)] [ValidateSet("Add","Remove")] [string]$Operation,
       [Parameter(Mandatory=$true,Position=2)] [string] $Account,
       [Parameter(Mandatory=$false,Position=3)] [ValidateSet("EnableAccount","ExecuteMethods","FullWrite","PartialWrite","ProviderWrite","RemoteEnable","ReadSecurity","WriteSecurity")] [string[]] $Permissions=$null,
       [Parameter(Mandatory=$false)] [switch]$AllowInherit,
       [Parameter(Mandatory=$false)] [switch]$Deny,
       [Parameter(Mandatory=$false)] [string]$ComputerName=".",
       [Parameter(Mandatory=$false)] [System.Management.Automation.PSCredential]$Credential=$null)

$OBJECT_INHERIT_ACE_FLAG    = 0x1
$CONTAINER_INHERIT_ACE_FLAG = 0x2
$ACCESS_ALLOWED_ACE_TYPE    = 0x0
$ACCESS_DENIED_ACE_TYPE     = 0x1

$WBEM_ENABLE            = 0x01
$WBEM_METHOD_EXECUTE    = 0x02
$WBEM_FULL_WRITE_REP    = 0x04
$WBEM_PARTIAL_WRITE_REP = 0x08
$WBEM_WRITE_PROVIDER    = 0x10
$WBEM_REMOTE_ACCESS     = 0x20
$WBEM_RIGHT_SUBSCRIBE   = 0x40
$WBEM_RIGHT_PUBLISH     = 0x80
$READ_CONTROL           = 0x20000
$WRITE_DAC              = 0x40000
$WBEM_S_SUBJECT_TO_SDS  = 0x43003

$ErrorActionPreference = "Stop"

$InvokeParams=@{Namespace=$Namespace;Path="__systemsecurity=@";ComputerName=$ComputerName}
if ($PSBoundParameters.ContainsKey("Credential")) { $InvokeParams+= @{Credential=$Credential}}

$output = Invoke-WmiMethod @InvokeParams -Name "GetSecurityDescriptor"
if ($output.ReturnValue -ne 0) { throw "GetSecurityDescriptor failed:  $($output.ReturnValue)" }

$ACL = $output.Descriptor

if ($Account.Contains('\')) {
  $Domain=$Account.Split('\')[0]
  if (($Domain -eq ".") -or ($Domain -eq "BUILTIN")) { $Domain = $ComputerName }
  $AccountName=$Account.Split('\')[1]
}
elseif ($Account.Contains('@')) {
  $Somain=$Account.Split('@')[1].Split('.')[0]
  $AccountName=$Account.Split('@')[0]
}
else {
  $Domain = $ComputerName
  $AccountName = $Account
}

$GetParams = @{Class="Win32_Account" ;Filter="Domain='$Domain' and Name='$AccountName'"}
$Win32Account = Get-WmiObject @GetParams
if ($Win32Account -eq $null) { throw "Account was not found: $Account" }

# Add Operation
if ($Operation -eq "Add") {
  if ($Permissions -eq $null) { throw "Permissions must be specified for an add operation" }

  # Construct AccessMask
  $AccessMask=0
  $WBEM_RIGHTS_FLAGS=$WBEM_ENABLE,$WBEM_METHOD_EXECUTE,$WBEM_FULL_WRITE_REP,$WBEM_PARTIAL_WRITE_REP,$WBEM_WRITE_PROVIDER,$WBEM_REMOTE_ACCESS,$READ_CONTROL,$WRITE_DAC
  $WBEM_RIGHTS_STRINGS="EnableAccount","ExecuteMethods","FullWrite","PartialWrite","ProviderWrite","RemoteEnable","ReadSecurity","WriteSecurity"
  $PermissionTable=@{}
  for ($i=0; $i -lt $WBEM_RIGHTS_FLAGS.Count; $i++) { $PermissionTable.Add($WBEM_RIGHTS_STRINGS[$i].ToLower(), $WBEM_RIGHTS_FLAGS[$i]) }
  foreach ($Permission in $Permissions) { $AccessMask+=$PermissionTable[$Permission.ToLower()] }

  $ACE=(New-Object System.Management.ManagementClass("Win32_Ace")).CreateInstance()
  $ACE.AccessMask=$AccessMask
  # Do not use $OBJECT_INHERIT_ACE_FLAG.  There are no leaf objects here.
  if ($AllowInherit.IsPresent) { $ACE.AceFlags=$CONTAINER_INHERIT_ACE_FLAG }
  else { $ACE.AceFlags=0 }

  $Trustee=(New-Object System.Management.ManagementClass("Win32_Trustee")).CreateInstance()
  $Trustee.SidString = $Win32Account.SID
  $ACE.Trustee=$Trustee

  if ($Deny.IsPresent) { $ACE.AceType = $ACCESS_DENIED_ACE_TYPE } else { $ACE.AceType = $ACCESS_ALLOWED_ACE_TYPE }
  $ACL.DACL+=$ACE
}
#Remove Operation
else {
  if ($Permissions -ne $null) { Write-Warning "Permissions are ignored for a remove operation" }
  [System.Management.ManagementBaseObject[]]$newDACL = @()
  foreach ($ACE in $ACL.DACL) {
    if ($ACE.Trustee.SidString -ne $Win32Account.SID) { $newDACL+=$ACE }
  }
  $ACL.DACL = $newDACL
}

$SetParams=@{Name="SetSecurityDescriptor"; ArgumentList=$ACL}+$InvokeParams

$output = Invoke-WmiMethod @SetParams
if ($output.ReturnValue -ne 0) { throw "SetSecurityDescriptor failed: $($output.ReturnValue)" }
0

Nothing here worked for me. I found a YT vid in conjunction with an arbitrary comment that solved it for me (& hopefully for you, too), but only when using invoke-command (ex. invoke-command -ComputerName MyRemoteComputer -ScriptBlock {Get-Process -Name explorer}).

On the PC you want to remotely access (on same domain):

  1. [Right-click Start] > Run > lusrmgr.msc (on Domain Controllers: dsa.msc)
  2. [Select the Groups folder] (on Domain Controllers: Builtin folder)
  3. [Right-click Distributed COM Users] > Add to [a] group... > Add...
  4. [Search the user/group you want to grant WMI access to] > Check Names (to confirm it's the right group/user) > OK

Why does adding the user/group to the Distributed COM Users group help? Well, that group has privileges to launch applications & objects remotely under COM Security settings. You can view these privileges with: [Right-click Start] > Run > DCOMcnfg > Component Services > Computers > [Right-click My Computer] > Properties > COM Security > Edit Limits...

  1. In an elevated PowerShell: Set-PSSessionConfiguration -ShowSecurityDescriptorUI -Name Microsoft.PowerShell
  2. Add... > [Search the user/group you want to grant WMI access to] > Check Names (to confirm it's the right group/user) > OK
  3. Under the Allow column under Permissions for MyUser, I only selected the Read(Get,Enumerate,Subscribe) and Execute(Invoke) options (since I was granting these privileges to all Domain Users).
  4. Apply > OK
  5. [Right-click Start] > Run > services.msc
  6. [Right-click] > Restart both Windows Management Instrumentation and Windows Remote Management (WS-Management).
  • (Set each of these services' Startup types to Automatic--if not already--in [Right-click] > Properties.)
  1. (If still doesn't work) Open Windows Defender Firewall with Advanced Security and [Right-click] > Enable each Windows Management Instrumentation Inbound Rule.
velkoon
  • 101
  • 2
0

If you are trying to access WMI there are two protocols available: DCOM and WinRM. Which protocol you are using will depend on the tools or API used. For example, when you are using PowerShell, the 'older' Get-WmiObject cmdlet uses DCOM, whereas the 'newer' Get-CimInstance cmdlet uses WinRM.

To access WMI as a non-administrator using DCOM you need the following groups / permissions

  1. Distributed COM Users
  2. 'Remote Enable' permissions under WMI control for the namespace you want to access (manual steps or with a script and Group Policy)
  3. Performance Monitor Users (for accessing certain performance metrics via WMI e.g. CPU usage via the Win32_Processor LoadPercentage value)

To access WMI as a non-administrator using WinRM you need the following groups / permissions

  1. Remote Management Users OR WinRMRemoteWMIUsers_ (notwithstanding the Microsoft official documentation they seem to function the same - and in later versions of Windows only the first is available)
  2. 'Remote Enable' permissions under WMI control for the namespace you want to access (manual steps or with a script and Group Policy)
  3. Performance Monitor Users (for accessing certain performance metrics via WMI e.g. CPU usage via the Win32_Processor LoadPercentage value)

Hopefully it goes without saying that to do this remotely you need the 'Windows Management Instrumentation' rules enabled in Windows Defender Firewall.

(You can also use the 'Performance Log Users' group to assign DCOM and WMI performance metric permissions in place of 'Distributed COM Users' and 'Performance Monitor Users', but this group has additional privileges that may not be appropriate for it to grant, or set up the DCOM Remote Launch and Activation Permissions manually as suggested in other answers, but that seems an overly complicated process.)

Minkus
  • 278
  • 2
  • 9
-1

We did this for PRTG: We created a new domain user: Created a GPO Dit to put his user in the group "Performnce Log Users" and used a powershell script to add this user to WMI Control. thanks to:

https://live.paloaltonetworks.com/t5/Management-Articles/PowerShell-Script-for-setting-WMI-Permissions-for-User-ID/ta-p/53646

  • Please include relevant information directly in your answers. Answers posted should be able to stand alone, and just use links for reference. – Cory Knutson Jun 02 '17 at 18:47