J'écris un service de surveillance qui utilise WMI pour obtenir des informations à partir de machines distantes. Il n'est pas possible d'avoir des droits d'administrateur local sur toutes ces machines pour des raisons politiques.
Est-ce possible? De quelles autorisations/droits mon utilisateur a-t-il besoin pour cela?
Les éléments suivants fonctionnent sur Windows 2003 R2 SP 2, Windows Server 2012 R2
wmimgmt.msc
). Dans l'onglet Sécurité, mettez en surbrillance Root/CIMV2
, cliquez sur Sécurité; ajoutez tilisateurs de l'Analyseur de performances et activez les options: Enable Account
et Remote Enable
dcomcnfg
. Dans Services de composants> Ordinateurs> Poste de travail, dans l'onglet Sécurité COM de la boîte de dialogue Propriétés, cliquez sur "Modifier les limites" pour les deux Access Permissions
et Launch and Activation Permissions
. Ajoutez des utilisateurs de l'Analyseur de performances et autorisez l'accès à distance, le lancement à distance et l'activation à distance.Remote Launch
et Remote Activation
privilèges pour tilisateurs de l'Analyseur de performances Groupe.Remarques:
Root
, et récupérer les autorisations des sous-espaces de noms via la fenêtre Advanced
dans Security
Tout ce que j'ai fait sur Windows 8 a été ajouté utilisateur au groupe "Utilisateurs de gestion à distance", et les requêtes WQL distantes ont fonctionné.
Par défaut, seul le groupe Administrateurs local dispose d'autorisations distantes sur WMI. Vous devrez personnaliser les autorisations WMI "Remote Enable".
Vous devrez peut-être également accorder des "autorisations d'accès à distance DCOM" et/ou des "autorisations de lancement et d'activation à distance DCOM" en fonction de ce que vous essayez de faire. Cet article MSDN donne les procédures étape par étape.
Les éléments suivants ont fonctionné pour moi dans un environnement de domaine 2012 r2, bien que je ne réussisse qu'à le faire par serveur et non par l'ensemble du domaine:
1) Ajouter un utilisateur au groupe d'utilisateurs du journal des performances. 2) Exécutez wmimgmt.msc, cliquez avec le bouton droit sur "Contrôle WMI (LOCAL), accédez à l'onglet Sécurité et accordez à l'utilisateur approprié" Activer le compte "et" Activer à distance "sur l'espace de noms souhaité (habituellement CIMV2).
Si je parviens à le faire pour l'ensemble du domaine, je reviendrai et mettrai à jour.
Sur la base de la réponse choisie, j'ai modifié le script de Microsoft pour définir la sécurité WMI. Mon utilisateur de test était un utilisateur de domaine non administratif qui était membre des "utilisateurs de gestion à distance" sur le système local pour des raisons non liées à ce problème . Après avoir accordé à mon utilisateur les autorisations EnableAccount, RemoteEnable et ExecuteMethods sur l'espace de noms cible, j'ai pu accéder à WMI.
Donc, j'ai pas ajouté mon utilisateur aux tilisateurs de l'Analyseur de performances ou tilisateurs COM distribués local groupes.
Quelques notes concernant le script:
$OBJECT_INHERIT_ACE_FLAG
Le script est ci-dessous. Je l'ai nommé 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)" }