Auteur de questions
Mette à jour en masse les informations des profiles utilisateurs de multiple OU et sous OU avec Powershell

Question
-
Bonjour,
Je suis en stage pour valider mon diplôme.
On m'a demandé de mettre à jour les informations dans les différents onglet sur les profiles utilisateurs qui sont :
Onglet Général :
- Description
-Numéros de téléphone
-Adresse de messagerie
Onglet Organisation :
- Fonction
- Service
- Société
Onglet Adresse :
- Adresse
Ville
Code postale.
J'ai trouvé différent script ici et sur le net, mais le problème c'est que les utilisateur sont répartie dans des OU et sous OU dans l'annuaire.
Auriez vous un script pouvant réaliser cela ?
Rechercher l'utilisateur et modifier les informations avec ceux fournis dans le CSV ?
- Modifié Sylvain77 lundi 7 décembre 2020 13:36
Toutes les réponses
-
Bonjour,
la position dans une quelconque "OU" ne pose pas de problème.
L'important est de rechercher l'utilisateur sur un critère qui soit/devrait être unique; le Samaccountname, l'adresse de messagerie, le UserPrincipalName, s'il le faut à partir de la racine de l'annuaire.
=> Ce critère doit être fourni dans l'une des colonnes du fichier CSV.
Quand l'utilisateur est trouvé, utiliser le "DistinguishedName" pour charger/Mettre à jour l'utilisateur trouvé.
S'il n'est pas trouvé, ou s'il y a des doublons (ce qui est techniquement possible pour l'adresse de messagerie), indiquer l'erreur et ne pas mettre à jour.
Mettre le tout dans une boucle traitant chaque ligne du fichier CSV.
A bientôt,
Thierry DEMAN-BARCELO. Office Apps&Services MVP. MCSE:Enterprise admin, Messaging, Server Infrastructure 2016(89 MCPs). MCSA Office 365,Microsoft 365 Certified: Messaging Administrator Associate,Modern Desktop Administrator Associate, Security Admin https://base.faqexchange.info
-
Bonjour Thierry, et merci pour votre retour,
Ok donc je peut utiliser comme référence de recherche Userprincipalname.
ici même j'avais trouvé un script et fichier template "AD User Attribute Update from Excel" mais je trouve cela très complexe
Avez vous un script sous la main ?
-
PS 1 : que pensez vous de ce script ?
https://social.technet.microsoft.com/Forums/fr-FR/f9af0dda-b0e5-4d21-b9bb-76a090d3f7c5/resolu-modification-multiple-attributs-ad-via-importcsv?forum=1300
Puis-je simplement l'adapter ?
- Modifié Sylvain77 lundi 7 décembre 2020 14:28
-
Avant que le scriptcenter bascule dans docs microsoft, tu trouveras plein d'exemples de scripts Powershell de gestion des utilisateurs d'un active directory :
-
ha merci pour le conseil :)
Mais le soucis c'est que mon stage fini dans 2 semaines et cette mission me prend du temps sur un autre projet en cour d'étude (procdure technique migration serveur AD 2008 R vers 2012 R2) elle presque fini et en parallèle de tous ça je dois faire mon rapport de stage qui se retrouve bloqué :(
J'ai essayé d'adapter un script :
$users = Import-Csv -Path C:\test_script\Update_AD.csv -delimiter ";" foreach ($user in $users) { Get-ADUser -Filter "sAMAccountName -eq '$($user.login)'"` -Properties * -SearchBase 'OU=nom,DC=domain,DC=local' | Set-ADUser -surname $($user.nom) ` -GivenName $($user.prenom) ` -DisplayName $($user.nomcomplet) ` -description $($user.Description) ` -telephoneNumber $(if ($user.telephone -eq "") {$null} Else {$user.telephone}) ` -mail $($user.adressmail) ` -streetAddress $($user.Adresse)` -l $($user.ville) ` -postOfficeBox $($user.BoitePostale) ` -postalCode $($user.CodePostal)` -title $(if ($user.Title -eq "") {$null} Else {$user.Title}) ` -Department $($user.Department) ` -Company $($user.Company) }
j'ai réussi à passer certain message d'erreur
mais il me dit ça :PS C:\test_script> C:\test_script\Update_AD.ps1
-DisplayName : Le terme «-DisplayName» n'est pas reconnu comme nom d'applet de commande, fonction, fichier de script ou programme exécutable. Vérifiez l'orthographe du
nom, ou si un chemin d'accès existe, vérifiez que le chemin d'accès est correct et réessayez.
Au caractère C:\test_script\Update_AD.ps1:8 : 3
+ -DisplayName $($user.nomcomplet) `
+ ~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (-DisplayName:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
-DisplayName : Le terme «-DisplayName» n'est pas reconnu comme nom d'applet de commande, fonction, fichier de script ou programme exécutable. Vérifiez l'orthographe du
nom, ou si un chemin d'accès existe, vérifiez que le chemin d'accès est correct et réessayez.
Au caractère C:\test_script\Update_AD.ps1:8 : 3
+ -DisplayName $($user.nomcomplet) `
+ ~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (-DisplayName:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundExceptionpour tenter de passer j'ai mis cette ligne en commentaire mais pareil quand il passe à description.
Vous avez une idée ?
Par avance merci sincèrement votre aide
Edit : La version du serveur est un 2012 R2 et le domain et la forêt 2012 R2
- Modifié Sylvain77 lundi 7 décembre 2020 20:10
-
Bonjour Sylvain
C'est ce qui arrive quand on veut utiliser du code (qui date en plus) sans le comprendre. Le message d'erreur est pourtant clair : pb sur la ligne qui précède DisplayName. Un backtick qui est suivi d'un espace
2 points :
- Les backticks sont à éviter dans les scripts. PS sait très bien quand une cmdllet se termine et quand une autre commence
https://get-powershellblog.blogspot.com/2017/07/bye-bye-backtick-natural-line.html
https://github.com/PowerShell/PSScriptAnalyzer/issues/218
- Quand on a une cmdlet dans laquelle on veut passer 13 paramètres comme tu l'a fait, il est bien plus human-readable d'utiliser un splat
https://thinkpowershell.com/powershell-splatting-what-is-it-why-use-it/
users = Import-Csv -Path C:\test_script\Update_AD.csv -delimiter ";" foreach ($user in $users) { $ADUserParams = @{ surname = $($user.nom) GivenName = $($user.prenom) DisplayName = $($user.nomcomplet) Description = $($user.Description) TelephoneNumber = $(if ($user.telephone -eq "") {$null} Else {$user.telephone}) Mail = $($user.adressmail) StreetAddress = $($user.Adresse) l = $($user.ville) PostOfficeBox = $($user.BoitePostale) PostalCode = $($user.CodePostal) Title = $(if ($user.Title -eq "") {$null} Else {$user.Title}) Department = $($user.Department) Company = $($user.Company) } Get-ADUser -Filter "sAMAccountName -eq '$($user.login)'" -Properties * -SearchBase 'OU=nom,DC=domain,DC=local' | Set-ADUser @ADUserParams }
Tu as fait exactement le type d'erreur que l'on peut obtenir quand on utilise des backticks.
Cordialement
Olivier
Edit : et j'oubliais un autre point important, le fameux "Filter left, format right".
Tu as un Get-ADUser et tu filtres bien à gauche (comprendre avant le pipeline).Bien !
Cependant la sortie par défaut de Get-ADUser ne contient pas ce que tu veux. Donc tu ajoutes un -Properties pour ajouter à la sortie par défaut de la cmdlet les propriétés qui manquent. Rien de plus normal. Mais pourquoi passer toutes les propriétés d'un compte alors que seuls 14 t'intéressent ? Tu passes un objet maouse costaud au pipeline. Certes cela ne touche qu'un seul utilisateur à chaque requête - et je conçois que cela soit plus rapide que se taper les fameuses properties qui manquent - mais ce n'est pas une bonne pratique : consommation CPU, temps, ... C'est quelque chose qu'il faut éviter au maximum.
- Modifié Oliv - TheFrog lundi 7 décembre 2020 21:14
-
Bonjour et Merci Oliv pour ton retour détaillé et très formateur,
comme l'évoque Aaron dans sont article sur le Splatting, j'ai réussi à passer ma commande sans les backtick
Du coup effectivement tout fini à l'horizontal et ce n'est pas pratique du tout, mais en tous cas l'ensemble de la commande passe maintenant, j'ai pu identifier et corriger certaines erreur lier au nommage des applets pour les attribut à modifier.
Je vais tester ton script incluant le Splatting :)
Je reviens vers vous dès que tous est validé ;)
-
alors ça passer sauf que j'ai dû comme dans mon 1er script validé modifier les nom des attributs
$ADUserParams = @{
surname = $($user.nom)
GivenName = $($user.prenom)
DisplayName = $($user.nomcomplet)
Description = $($user.Description)
Officephone = $(if ($user.telephone -eq "") {$null} Else {$user.telephone})
EmailAddress = $($user.adressmail)
StreetAddress = $($user.Adresse)
l = $($user.ville)
POBox = $($user.BoitePostale)
PostalCode = $($user.CodePostal)
title = $(if ($user.Title -eq "") {$null} Else {$user.Title})
Department = $($user.Department)
Company = $($user.Company)
}Dernière question vous savez comment évité que les cas avec accent "é ou è" finissent avec un symbole type losange noir avec un "?" dedans" ?
- Modifié Sylvain77 mardi 8 décembre 2020 07:51
-
Bonjour Sylvain77
Pb courant pour nous autres français mais que l'on peut régler facilement.
Quand on fait un Import-Csv depuis un fichier .csv généré avec un MS Office en langue française, ou un quelquonque éditeur de texte sur un OS en langue FR.
- ne jamais oublier d'ajouter le paramètre -Encoding et préciser la valeur UTF8 : fini les pbs avec les accents.
- de même, on n'oubliera pas d'ajouter le paramètre -Delimiter avec comme valeur ";" (et ou, en langue française, le délimiter par défaut d'un "Comma Separate Value file" est un ;).
et tant qu'on y est, ne pas oublier de passer ces mêmes paramètres lors d'un Export-Csv
- Ca facilite l'importation dans Excel : c'est bien une valeur par cellule comme attendu sans avoir à faire un "convertir"
- Et puis, c'est également très pratique quand on a dans l'export des paths LDAP (type DistinguishedName) qui présentent des valeurs séparées par des ","
Dernier truc pour la route : Je suis sur un OS en FR et dans l'AD (Utilisateurs et Ordinateurs Active Directory) les infos se présentent en FR, mais ce ne sont pas les "vrais" noms des propriétés dans l'AD (qui sont toujours en US). La question est : Comment déterminer le "vrai" nom desdites propriétés ?
- AD Users&Computers, Dans les menus choisir "afficher les fonctionnalités avancées" (ou qq chose comme cela), ensuite prendre un compte quelquonque (Utilisateur ou Ordinateur) et on a alors un nouvel on onglet nommé "Attrbuts" où toutes les propriétés de l'objet concerné sont visibles.
- Get-ADUser (ou computer) -Name <Compte> -Property * : Là on récupère toutes les propriétés dudit objet et surtout ce qu'on cherche, leur "vrai" nom. Naturellement, on fait cela sur un seul objet, pas sur tout l'AD :-). Totalement transposable à tout autre objet de l'AD : Groupe, OU, ...
Cordialement
Olivier
-
-
Le test est concluant un grand merci à tous :)
On me demande maintenant au moment de finir si on peux changer le nom d'affichage dans l'AD celui qui s'affiche quand on fait une recherche dans les UO. j'ai l'impression que c'est le nom de l'objet
J'ai essayé CN, Name mais rien n'y fait je ne trouve pas l'attribut
- Modifié Sylvain77 jeudi 10 décembre 2020 08:07
-
-
Voici une commande que tu peux utiliser pour renommer le nom d'affichage d'un objet:
Get-ADUser "nom de l'objet" | Rename-ADObject -NewName "Nouveau nom de l'objet"
-
Salut Olivier :)
Oui c'est ce que je faisais jusqu’à maintenant, mais depuis ton conseil j'ai fait ça :
j'ai repris mon fichier test CVS, copier/collé des valeurs sur un nouveau tableur
Enregistrer sous CSV encoding UTF8 (séparateur virgule)
Et quand je l'ai ouvert avec notpad++ il y avais les délimiteur ";"
Le test d'import fonctionne à 100% sans soucis maintenant :)
-
Bonjour JM :)
hummm mais comment l'intégrer dans mon script ?
Est ce que cela pourrais être bon à votre avis ?
$users = Import-Csv -Path C:\script\Update_AD.csv -delimiter ";"
foreach ($user in $users) {
$ADUserParams = @{
surname = $(if ($user.nom -eq "") {$null} Else {$user.nom})
GivenName = $($user.prenom)
DisplayName = $($user.nomcomplet)
Description = $(if ($user.Description -eq "") {$null} Else {$user.Description})
Officephone = $(if ($user.telephone -eq "") {$null} Else {$user.telephone})
EmailAddress = $($user.adressmail)
StreetAddress = $($user.Adresse)
l = $($user.ville)
POBox = $($user.BoitePostale)
PostalCode = $($user.CodePostal)
title = $(if ($user.Title -eq "") {$null} Else {$user.Title})
Department = $(if ($user.Department -eq "") {$null} Else {$user.Department})
Company = $($user.Company)
}
$ADObjetParams = @{
NewName = $(user.nomcomplet)
}
Get-ADUser -Filter "sAMAccountName -eq '$($user.login)'" -Properties * -SearchBase 'DC=XXXX,DC=local' |
Set-ADUser @ADUserParams
Get-ADUser -Filter "sAMAccountName -eq '$($user.login)'" -Properties * -SearchBase 'DC=XXXX,DC=local' |
Rename-ADObject @ADObjetParams
}- Modifié Sylvain77 jeudi 10 décembre 2020 08:15
-
bonjour Sylvain77
Ca me semble bien à première vue.
Un conseil (pour valider tout ça) : rejoute un -Whatif derrière tes Set-AdUser et Rename-ADObject ça te permettra de tester et valider si tout est OK sans foutre en l'air ton environnement.
Après, il peut être nécessaire de mettre en place une gestion des erreurs. En effet, que se passe-t-il si on query un user (provenant du .csv) qui n'existe pas ? Ca va claquer une erreur. Et on fait quoi dans ce cas, on poursuit en loguant le compte concerné pour un traitement séparé, on arrête tout ?
C'est indispensable si ton fichier .csv a été alimenté manuellement (un doigt crochu, ça arrive). Cela peut ne pas l'être si ton .csv a été alimenté par une query AD précédente.
Cordialement
Olivier
-
Bonjour Olivier,
Le script ne fonctionne pas avec la modif des abjet user.
Pour le moment j'ai stoppé à la première version sans la modification des objets users.
Je sais que le script n'est pas parfait et comme tu l'indique ne traite pas les erreurs.
Pour la création du CSV j'ai réaliser un nouvel export de l'ADuser et construit avec une rechercheV autour des login utilisateurs présent en date du 8/12 sur l'AD, et non reposant sur le premier export qui à été effectué il y a un mois pour l'étude du projet et les échanges avec les services RH.
Cela m'a permis d'identifier 4 comptes inconnu sur l'annuaire entre ces deux exports, j'ai donc fait un retrait des 4 comptes sur mon CSV.
Mais je vais faire script test et ajouter -Whatif dessus merci pour l'info ;)
- Modifié Sylvain77 vendredi 11 décembre 2020 08:29