Active Directory : comment obtenir la liste des administrateurs locaux de tous les ordinateurs ?

I. Présentation

Vous travaillez en environnement Active Directory avec des machines sous Windows et vous ne savez plus trop qui est administrateur local de quelle machine ? Autrement dit, vous cherchez à obtenir la liste des administrateurs locaux de chaque machine de votre domaine Active Directory ? Cela tombe bien, c'est ce que nous allons voir dans ce tutoriel où nous allons utiliser PowerShell !

Vous avez également la possibilité de déployer une stratégie de groupe pour uniformiser la configuration sur vos machines :

II. Lister les comptes Administrateurs locaux d'une machine

Tout d'abord, nous allons voir comment obtenir cette information sur une seule machine, en étant en local. Vous pouvez regarder dans la console "Gestion de l'ordinateur" afin de regarder les membres du groupe "Administrateurs". Dans cet exemple, nous pouvons voir qu'il y a le compte "Administrateur" local de la machine, ainsi que le groupe de sécurité "IT-CONNECT\GDL-Admins-PC" (dans l'Active Directory).

Windows - Membres du groupe Administrateurs

Ma volonté étant plutôt de vous expliquer comment procéder avec PowerShell, voici la commande à utiliser :

Get-LocalGroupMember -Group "Administrateurs"

Elle retournera la même liste que l'interface graphique. La propriété "PrincipalSource" permet de savoir s'il s'agit d'un utilisateur/groupe stocké dans la base SAM locale ou dans l'Active Directory.

PowerShell - Get-LocalGroupMember Administrateurs

Ainsi, nous pourrions filtrer cette liste pour avoir uniquement les objets (utilisateur/groupe) appartenant à l'Active Directory :

Get-LocalGroupMember -Group Administrateurs | Where-Object {$_.PrincipalSource -eq "ActiveDirectory"}

Si le module Active Directory de PowerShell était installé sur le poste de travail, nous pourrions récupérer la liste des membres des groupes Active Directory, en l'occurrence ici les membres du groupe "IT-CONNECT\GDL-Admins-PC". Toutefois, ce module n'est généralement pas installé sur les postes de travail (à quelques exceptions près...). Nous verrons comment récupérer automatiquement cette liste via l'interrogation à distance.

III. Récupérer la liste des administrateurs locaux à distance

Nous allons commencer à récupérer l'information à distance, ce qui permettra d'obtenir la liste des administrateurs locaux de n'importe quelle machine du domaine Active Directory actuellement allumé et connecté au réseau.

Avec PowerShell, nous allons utiliser le cmdlet "Invoke-Command" qui va permettre d'exécuter une commande sur la machine distante : nous allons exécuter la commande "Get-LocalGroupMember" que nous avons vue précédemment. Pour que cela fonctionne, la gestion à distance via WinRM doit être activée sur les machines cibles et ce flux doit être autorisé dans le pare-feu Windows.

Le fait d'agir à distance depuis un contrôleur de domaine Active Directory ou une machine d'administration va nous permettre d'utiliser le module Active Directory de PowerShell à partir d'une seule machine.

Pour récupérer la liste des administrateurs locaux à distance sur une machine nommée "PC-01", voici la commande à exécuter :

Invoke-Command -ComputerName PC-01 -ScriptBlock { Get-LocalGroupMember -Group Administrateurs }

Nous obtenons le même résultat :

récupérer la liste des administrateurs locaux à distance

Ensuite, nous pouvons aller plus loin en nous intéressant aux administrateurs locaux correspondants à des comptes du domaine Active Directory.

  • S'il s'agit d'un utilisateur, on récupère son identifiant (SamAccountName), son état pour savoir s'il est activé ou non (Enabled) et sa date de création (WhenCreated)
  • S'il s'agit d'un groupe de sécurité, on récupère la liste des membres de ce groupe, et pour chaque utilisateur on récupère les mêmes propriétés (identifiant, état, date de création)

Ce qui donne le bout de code suivant :

$LocalAdmins = Invoke-Command -ComputerName PC-01 -ScriptBlock { Get-LocalGroupMember -Group Administrateurs | Where-Object { $_.PrincipalSource -eq "ActiveDirectory" } }

Foreach ($LocalAdmin in $LocalAdmins)
{
    If($LocalAdmin.objectclass –eq "Utilisateur"){
        Get-ADUser $LocalAdmin.SID -Properties whenCreated | Select-Object SamAccountName,enabled,whenCreated
    }
    If($LocalAdmin.objectclass –eq "Groupe"){
        Get-ADGroupMember $LocalAdmin.SID | ForEach-Object { Get-ADUser $_ -Properties whenCreated  | Select-Object SamAccountName,enabled,whenCreated } 
    }
}

Ainsi, le résultat suivant est retourné :

Ceci me donne des précisions sur les membres du groupe "IT-CONNECT\GDL-Admins-PC" de l'Active Directory ! Si un administrateur local ne nous plaît pas, il suffirait de le retirer du groupe. S'il s'agit d'un objet local, il est toujours possible de le faire à distance via la commande "Remove-LocalGroupMember".

IV. Récupérer la liste des administrateurs locaux pour tous les ordinateurs

Pour finir et aller plus loin, nous allons voir comment récupérer la liste des administrateurs locaux pour tous les ordinateurs (ou une sélection d'ordinateurs) intégrés à l'Active Directory.

Tout d'abord, nous devons récupérer une liste de machines : à vous de définir vos critères en adaptant la syntaxe de la commande Get-ADComputer. Cette liste de machines sera stockée dans la variable $Targets.

Par exemple, voici comment récupérer une liste d'ordinateurs à partir d'une OU spécifique (et toutes les sous-OUs) :

$Targets = (Get-ADComputer -Filter * -SearchBase "OU=PC,DC=it-connect,DC=local").Name

Nous pouvons aussi utiliser d'autres critères, comme le système d'exploitation. Si l'on recherche uniquement les serveurs sous Windows Server, cela donne :

$Targets = (Get-ADComputer -Filter 'operatingsystem -Like "Windows Server*"').Name

Dans la commande Invoke-Command, nous allons simplement remplacer le nom de la machine à cibler par notre liste représentée par $Targets. Ainsi, nous allons récupérer la liste de tous les ordinateurs correspondants à notre sélection.

$LocalAdmins=Invoke-Command -ComputerName $Targets -ScriptBlock { Get-LocalGroupMember -Group Administrateurs | Where-Object { $_.PrincipalSource -eq "ActiveDirectory" } }

Désormais, nous allons aller plus loin puisque l'on va dresser la liste des administrateurs locaux correspondants à des comptes Active Directory, pour chaque machine. Lorsqu'il s'agit d'un groupe de sécurité, tel que "IT-CONNECT\GDL-Admins-PC", nous allons récupérer la liste des membres pour avoir directement les noms des utilisateurs dans la sortie de la commande.

$LocalAdmins=Invoke-Command -ComputerName $Targets -ScriptBlock { Get-LocalGroupMember -Group Administrateurs | Where-Object { $_.PrincipalSource -eq "ActiveDirectory" } }

$Report = Foreach ($LocalAdmin in $LocalAdmins)
{
    If($LocalAdmin.objectclass –eq "Utilisateur"){
        Get-ADUser $LocalAdmin.SID -Properties whenCreated | Select-Object @{Name = 'ComputerName'; Expression = {$LocalAdmin.PSComputerName}},SamAccountName,enabled,whenCreated, @{Name = 'Type'; Expression = {"Utilisateur"}}
    }
    If($LocalAdmin.objectclass –eq "Groupe"){
        Get-ADGroupMember $LocalAdmin.SID | ForEach-Object { Get-ADUser $_ -Properties whenCreated  | Select-Object @{Name = 'ComputerName'; Expression = {$LocalAdmin.PSComputerName}},SamAccountName,enabled,whenCreated,@{Name = 'Type'; Expression = {"Groupe"}}} 
    }
}

$Report | Format-Table

Le bout de code ci-dessous contient deux propriétés calculées :

  • ComputerName pour spécifier le nom de l'ordinateur (sinon il sera difficile de s'y retrouver).
  • Type pour indiquer la valeurr "Utilisateur" s'il s'agit d'un utilisateur directement membre du groupe "Administrateurs" de la machine ou la valeur "Groupe" s'il s'agit d'un utilisateur membre d'un groupe de sécurité AD étant lui-même membre du groupe "Administrateurs". De ce fait, un même utilisateur peut ressortir deux fois dans les résultats pour une même machine.

Voici un exemple de résultat :

Plutôt sympa, non ? 🙂

Vous pouvez aussi exporter cette liste dans un fichier CSV (qui contient la date du jour dans le nom) :

$Report | Export-CSV "C:\Scripting\CSVLocalAdmins.csv" -NoTypeInformation

Ce qui donne :

V. Conclusion

Libre à vous d'utiliser et d'adapter ces commandes et bouts de code PowerShell afin de vous les approprier : c'est du scripting donc nous pouvons faire du sur-mesure assez facilement. Que ce soit pour un audit, de la surveillance, etc... Il peut s'avérer très utile de récupérer la liste des comptes utilisateurs ayant les privilèges "Administrateurs" sur chaque machine de votre infrastructure ou parc informatique !

Partagez cet article Partager sur Twitter Partager sur Facebook Partager sur Linkedin Partager sur Google+ Envoyer par mail

Florian BURNEL

Ingénieur système et réseau, cofondateur d'IT-Connect et Microsoft MVP "Cloud and Datacenter Management". Je souhaite partager mon expérience et mes découvertes au travers de mes articles. Généraliste avec une attirance particulière pour les solutions Microsoft et le scripting. Bonne lecture.

Nombre de posts de cet auteur : 5580.Voir tous les posts

2 thoughts on “Active Directory : comment obtenir la liste des administrateurs locaux de tous les ordinateurs ?

  • Bien joué !
    Cependant il faut que les ordinateurs soient joignables au moment de l’exécution du script. Ce qui n’est pas toujours le cas.
    L’autre méthode, que j’utilise, c’est de jouer un script au démarrage des machines via gpo. C’est p’us simple de toucher l’ensemble des machines.

    Répondre
  • Plus compliqué mais marche sur toutes les versions d’OS 😉

    function Get-LocalAdministratorGroupMember
    {
    [CmdletBinding()]
    param (
    [Parameter()]
    [System.String]$ComputerName = $env:ComputerName,
    [Parameter()]
    [System.Management.Automation.PSCredential]$Credential

    )

    begin
    {
    $result = @()
    $members = $null

    }

    process
    {
    try
    {
    if ($ComputerName -eq $env:ComputerName)
    {
    # Determine the local Administrators group name based on the locale
    if (((Get-UICulture).Name -eq « fr-FR »))
    {
    $administratorsGroupName = « Administrateurs »
    }
    else
    {
    $administratorsGroupName = « Administrators »
    }
    $members = (net localgroup $administratorsGroupName) -replace ‘The command completed successfully.|\-+’ | Select-Object -Skip 4
    }
    else
    {
    $members = Invoke-Command -ScriptBlock {
    if (((Get-UICulture).Name -eq « fr-FR »))
    {
    $administratorsGroupName = « Administrateurs »
    }
    else
    {
    $administratorsGroupName = « Administrators »
    }
    ((net localgroup $administratorsGroupName) -replace ‘The command completed successfully.|\-+’ | Select-Object -Skip 6) } -Authentication Kerberos -ComputerName $ComputerName
    }
    }
    catch
    {
    Write-Error -Message « An error occurred. Unable to retrieve the list of local administrators of the machine $($ComputerName) »
    }
    }

    end
    {
    $members = $members | Where-Object { $_ -ne «  » }
    foreach ($Member in $members)
    {
    $MyObject = [PSCustomObject]@{
    « Computer » = $ComputerName
    « Members of Local Administrators Group » = $Member
    }
    $result += $MyObject
    }
    $result
    }
    }

    Répondre

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.