sviluppo-web-qa.it

Quali autorizzazioni / diritti deve avere un utente per avere accesso WMI su macchine remote?

Sto scrivendo un servizio di monitoraggio che utilizza WMI per ottenere informazioni da macchine remote. Avere diritti di amministratore locale su tutte queste macchine non è possibile per motivi politici.

È possibile? Quali autorizzazioni/diritti richiede il mio utente per questo?

34
jpoh

Quanto segue funziona su Windows 2003 R2 SP 2, Windows Server 2012 R2

  1. Aggiungi gli utenti in questione al gruppo Performance Monitor Users
  2. In Servizi e applicazioni, visualizza la finestra di dialogo delle proprietà di Controllo WMI (o esegui wmimgmt.msc). Nella scheda Sicurezza, evidenzia Root/CIMV2, fare clic su Sicurezza; aggiungi Performance Monitor Users e abilita le opzioni: Enable Account e Remote Enable
  3. Esegui dcomcnfg. In Servizi componenti> Computer> Risorse del computer, nella scheda Sicurezza COM della finestra di dialogo Proprietà fai clic su "Modifica limiti" per entrambi Access Permissions e Launch and Activation Permissions. Aggiungi utenti Performance Monitor e consenti l'accesso remoto, l'avvio remoto e l'attivazione remota.
  4. Seleziona Strumentazione gestione Windows in Servizi componenti> Computer> Risorse del computer> Configurazione DCOM e inserisci Remote Launch e Remote Activation privilegi a Performance Monitor Users Group.

Appunti:

  • In alternativa ai passaggi 3 e 4, è possibile assegnare l'utente al gruppo tenti COM distribuiti (Testato su Windows Server 2012 R2)
  • Se l'utente ha bisogno di accedere a tutti gli spazi dei nomi, è possibile impostare le impostazioni in 2. al livello Root e richiedere le autorizzazioni agli spazi dei nomi secondari tramite la finestra Advanced in Security
32
jpoh

Tutto ciò che ho fatto su Windows 8 è stato l'aggiunta dell'utente al gruppo "Utenti di gestione remota" e le richieste WQL remote hanno funzionato.

4
Bunyk

Per impostazione predefinita, solo il gruppo Administrators locale dispone delle autorizzazioni remote per WMI. Dovrai personalizzare le autorizzazioni WMI "Abilitazione remota".

1
ThatGraemeGuy

Potrebbe inoltre essere necessario concedere "Autorizzazioni di accesso remoto DCOM" e/o "Autorizzazioni di avvio e attivazione remote DCOM" a seconda di ciò che si sta tentando di fare. Questo articolo MSDN fornisce le procedure dettagliate.

1
KevinH

Quanto segue ha funzionato per me in un ambiente di dominio r2 2012 anche se sono riuscito a farlo solo per server e non per l'intero dominio:

1) Aggiungi utente al gruppo Utenti registro prestazioni. 2) Esegui wmimgmt.msc, fai clic con il pulsante destro del mouse su "Controllo WMI (LOCAL), vai alla scheda Sicurezza e concedi all'utente appropriato" Abilita account "e" Abilita remoto "sullo spazio dei nomi desiderato (di solito CIMV2).

Se riesco a farlo per l'intero dominio tornerò e aggiornerò.

0
JustAGuy

Sulla base della risposta scelta, ho modificato lo script di Microsoft per impostare la sicurezza WMI. Il mio utente di prova era un utente di dominio non amministrativo che era un membro degli "Utenti di gestione remota" sul sistema locale per motivi non correlati a questo problema . Dopo aver concesso al mio utente le autorizzazioni EnableAccount, RemoteEnable ed ExecuteMethods sullo spazio dei nomi di destinazione, sono stato in grado di accedere a WMI.

Quindi, non non ho aggiunto il mio utente a tenti Performance Monitor o tenti COM distribuiti locale gruppi.

Un paio di note riguardanti la sceneggiatura:

  1. È necessario specificare il percorso completo dello spazio dei nomi. Nel mio caso, lo spazio dei nomi era Root/Microsoft/SqlServer
  2. L'ereditarietà era sbagliata. Perché non ci sono oggetti foglia che non puoi usare $OBJECT_INHERIT_ACE_FLAG
  3. Mi sono liberato della funzione incorporata perché era troppo piccola e veniva utilizzata solo una volta.

Lo script è sotto. L'ho chiamato 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"

[email protected]{Namespace=$Namespace;Path="[email protected]";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"
  [email protected]{}
  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
}

[email protected]{Name="SetSecurityDescriptor"; ArgumentList=$ACL}+$InvokeParams

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