Active Directory – PowerShell : récupérer la liste des utilisateurs de plusieurs OU
I. Présentation
La flexibilité de PowerShell s'avère très pratique lorsqu'il s'agit d'interroger un annuaire Active Directory. Notamment si l'on souhaite récupérer la liste des utilisateurs (ou d'un autre type d'objets) au sein de plusieurs OU, sans prendre tout l'annuaire.
Grâce à un script PowerShell simple, nous allons pouvoir générer facilement cette liste d'utilisateurs sans passer par des exports multiples dans la console Active Directory, qu'il faudra ensuite fusionner... Bref, pas pratique.
II. Le script
La première étape consiste à définir un tableau qui va servir à lister les OU pour lesquelles nous souhaitons récupérer les utilisateurs. Dans la variable $OUList sera stocké le tableau. Par exemple, pour 4 OU différentes, cela donne :
$OUList = @("OU=Comptabilite,DC=it-connect,DC=local", "OU=Secretariat,DC=it-connect,DC=local", "OU=Direction,DC=it-connect,DC=local", "OU=Commercial,DC=it-connect,DC=local")
La suite est simple : pour chaque OU du tableau, nous allons récupérer la liste des utilisateurs grâce à Get-ADUser qui sera utilisé avec le paramètre SearchBase qui aura notre OU comme valeur. Ainsi, on récupère que les utilisateurs de l'OU, et cela pour nos 4 OU. Dans cet exemple, je sélectionne uniquement le SamAccountName mais vous pouvez ajouter d'autres propriétés.
Ce qui donne le script complet suivant :
$OUList = @("OU=Comptabilite,DC=it-connect,DC=local", "OU=Secretariat,DC=it-connect,DC=local", "OU=Direction,DC=it-connect,DC=local", "OU=Commercial,DC=it-connect,DC=local") $Users = Foreach($OU in $OUList){ Get-ADUser -Filter * -SearchBase $OU | Select-Object SamAccountName } $Users | Export-CSV -Path "C:\Users.csv" -NoTypeInformation
La variable $Users contient tous les utilisateurs, nous pouvons facilement l'exporter vers un fichier CSV grâce au cmdlet Export-CSV comme vous pouvez le voir sur la dernière ligne du script ci-dessus.
Voilà, simple mais efficace, non ? 👀
Bonjour,
merci pour le tuto, par contre si je veux récupérer le nom du compte ainsi que l’utilisateur à coté quel commande je dois rajouter ? J’ai essayé de rajouter la ligne :
Get-ADUser -Filter * -SearchBase $OU | Select-Object distinguishedName
en dessous de :
Get-ADUser -Filter * -SearchBase $OU | Select-Object SamAccountName
mais ça ne fonctionne pas.
Merci de m’aider 🙂
Bonjour Guillaume,
Il vaut mieux utiliser directement cette syntaxe :
Get-ADUser -Filter * -SearchBase $OU | Select-Object SamAccountName, distinguishedName
Fait un essai et redis-moi 🙂
Florian
Bonjour Florian,
Comme Guillaume, je cherche à avoir un peu plus d’informations sur l’utilisateur, comme son nom, son mail, et sa date de dernière connexion.
Sais tu ou je peux trouver le nom des champs que je dois ajouter derrière le Select-Object.
Merci pour ton aide,
Bon, ben je viens de trouver la solution à mon problème.
Voici les champs accessibles :
AccountExpirationDate :
accountExpires :
AccountLockoutTime :
AccountNotDelegated :
AllowReversiblePasswordEncryption :
AuthenticationPolicy : {}
AuthenticationPolicySilo : {}
BadLogonCount : 0
badPwdCount : 0
CannotChangePassword :
CanonicalName :
Certificates : {}
City :
CN :
co :
codePage :
Company :
CompoundIdentitySupported : {}
Country :
countryCode :
Created :
createTimeStamp :
Deleted :
Department :
Description :
DisplayName :
DistinguishedName :
Division :
DoesNotRequirePreAuth :
dSCorePropagationData : {}
EmailAddress :
EmployeeID :
EmployeeNumber :
Enabled :
extensionAttribute10 :
extensionAttribute12 :
extensionAttribute13 :
extensionAttribute14 :
extensionAttribute15 :
Fax :
GivenName :
HomeDirectory :
HomedirRequired :
HomeDrive :
HomePage :
HomePhone :
Initials :
instanceType :
isDeleted :
KerberosEncryptionType : {}
l :
LastBadPasswordAttempt :
LastKnownParent :
LastLogonDate :
lastLogonTimestamp :
LockedOut :
lockoutTime :
LogonWorkstations :
mail :
mailNickname :
Manager :
MemberOf : {}
MNSLogonAccount :
MobilePhone :
Modified :
modifyTimeStamp :
mS-DS-ConsistencyGuid :
msDS-User-Account-Control-Computed :
Name :
nTSecurityDescriptor :
ObjectCategory :
ObjectClass :
ObjectGUID :
objectSid :
Office :
OfficePhone :
Organization :
OtherName :
PasswordExpired :
PasswordLastSet :
PasswordNeverExpires :
PasswordNotRequired :
personalTitle :
physicalDeliveryOfficeName :
POBox :
PostalCode :
PrimaryGroup :
primaryGroupID :
PrincipalsAllowedToDelegateToAccount : {}
ProfilePath :
ProtectedFromAccidentalDeletion :
proxyAddresses : {}
pwdLastSet :
SamAccountName :
sAMAccountType :
ScriptPath :
sDRightsEffective :
ServicePrincipalNames : {}
SID :
SIDHistory :
SmartcardLogonRequired :
sn :
State :
StreetAddress :
Surname :
targetAddress :
Title :
TrustedForDelegation :
TrustedToAuthForDelegation :
UseDESKeyOnly :
userAccountControl :
userCertificate :
UserPrincipalName :
uSNChanged :
uSNCreated :
whenChanged :
whenCreated :
Si cela peut servir à quelqu’un …
Bonjour William,
Oui effectivement il s’agit de la liste des attributs. Pour les utiliser dans le script, il faut ajouter l’option « -Properties » et indiquer derrière les noms des attributs à « charger » car par défaut il y en a seulement quelques-uns d’affiché.
Bonne journée
Florian
Bonjour,
Est-il possible de lister directement les users de l’OU et de ses sous-OU ?
Merci 🙂
Bonjour Nico,
La commande actuelle prend directement en compte les sous-OU pour chaque OU définie dans la liste 😉
Redis moi si tu as un problème.
Cordialement,
Florian
J’ai dans chaque OU d’autres OU qui contiennent elles-mêmes d’autres OU, etc.
Ce que je souhaiterais c’est exporter tous les utilisateurs de OU et de ses sous OU sans avoir à les spécifier dans le script sinon je vais mettre des plombes a faire le script ^^
Si tu as une OU de haut niveau qui contient toutes les sous OU que tu veux cibler, tu n’as qu’à l’indiquer et ce sera récursif pour récupérer les utilisateurs dans les sous-OU (à partir de cette racine).
Ok je vais tester ça. Merci beaucoup !
Bonjour Florian,
Merci pour tout et bonne et heureuse annee.
Et t’il possible de faire la recherche directement a partir d’un domaine card dans mon cas j’ai plusieur domaines
Ce qui donnerait quelque chose comme ca:
$DList = @(« DC=we,DC=local,DC=net »,
« DC=ee,DC=local »,DC=net »,
« DC=na,DC=local »,DC=net »,
« DC=la,DC=local »,DC=net »)
Ensuite je voudrais avoir comme resultat tous les users qui ont des compte sur plusieur domaine.
Je pourrai faire une boucle qui prendari chaque user et verifirai si le user existe sure un autre domaine mais je ne trouve pas ca tres « propre » car si un user a pluseur compte le script va faire le meme traivaille plusieur fois.
Et je ne vois pas comment faire autrement 🙁
Merci pour ton aide.
Bonjour Eric,
J’y regarde dès que possible 😉
Florian
Bonjour Eric,
Merci, bonne année également 🙂
Si les domaines sont membres de la même forêt, ce qui semble être le cas d’après l’exemple, cela me semble possible.
Tu peux stocker la liste de l’ensemble des utilisateurs dans la variable $Users et ensuite créer une variable qui va contenir tous les comptes une seule fois (à toi de définir l’attribut sur lequel se baser). Il restera à comparer la variable $Users avec la variable qui contient qu’une fois chaque utilisateur ($UsersUnique) pour faire ressortir ceux qui sont présents deux fois. Trois lignes utiles pour éclaircir mes propos :
$Users += (Get-ADUser -Filter * -SearchBase "" | Select-Object SamAccountName).SamAccountName
$UsersUnique = $Users | Select-Object -Unique
Compare-object -ReferenceObject $UsersUnique -DifferenceObject $Users
Si ce n’est pas clair, dis moi 🙂
Cordialement,
Florian
Bonjour Florian,
Merci de ton aide.
J’ai essaye ton code en rajoutant un pipe cvs
Compare-object -ReferenceObject $UsersUnique -DifferenceObject $Users | Export -cvs – path $path -NoTypeInformation -Encoding UTF8
Mais je me retrouve avec la liste complete des utilisateurs et pas simplement les duplicates
J’ai essaye le meme en changeant la derniere ligne
$users | Group-Object -Property userprincipalname | where-object -property count -gt 2 | Export-Csv -Path $path -Encoding UTF8 -Delimiter « ; » -NoTypeInformation
Le resultat dans le fichier est le suivant
Values count Group name
System.collections.arrayList 55 **
**System.Collections.ObjectModel.Collection’1[System.Management.Automation.PSObject]
Je ne comprends pas pourquoi je n’est pas la liste des UPNs dans le fichier 🙁
Bonjour Florian,
Je vais essaye d’etre plus clair
Voici mon code
#Je recupere mes differnts domaines we,ee,it,la…
$Alldomains = (Get-ADForest).domains
#Affecte une valeur a ma variable path
$path = « c:\users.csv »
#J’initialise mon tableau users
[email protected]()
# je fais une boucle qui va me recuperer dans ma variable users tous les UPN des tous mes usrs sous tous mes domaines
foreach ($domain in $Alldomains)
{
$users+=get-aduser -Filter * -Server $domain | select UserPrincipalName
}
#la je pense que ca va pas **
$users | Group-Object UserPrincipalName | select name,count | Export-Csv -Path $path -Encoding UTF8 -Delimiter « ; » -NoTypeInformation
** Le Group-Object UserPrincipalName ne fait « rien » en tout cas je ne voit pas trop ce qu’il fais pour la raison suivante
chaque users de mon tableau a un unique UPN
[email protected]
[email protected]
J’ai donc en sorti la liste de tous les users commen par example [email protected] ; 1
meme chose avec
$users | Group-Object -Property userprincipalname | where-object -property count -gt 2 | Export-Csv -Path $path -Encoding UTF8 -Delimiter « ; » -NoTypeInformation
Il faudrait que je fasse un trie en fonction du prenom et du nom et ensuite en sorti L’UPN complet pour voir sous quel domain le user a un compte.
Bonjour Eric,
Pour être sûr de bien comprendre, pourrais-tu me dire sur quel attribut tu veux te baser pour détecter les doublons ? Ensuite je vois pour faire quelques tests.
Cordialement,
Florian