none
Mette à jour en masse les informations des profiles utilisateurs de multiple OU et sous OU avec Powershell RRS feed

  • 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
    lundi 7 décembre 2020 09:14

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

    lundi 7 décembre 2020 13:20
  • 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 ?

    lundi 7 décembre 2020 14:02
  • 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
    lundi 7 décembre 2020 14:18
  • Avant que le scriptcenter bascule dans docs microsoft, tu trouveras plein d'exemples de scripts Powershell de gestion des utilisateurs d'un active directory :

    Powershell, VB Script, SQL et JavaScript - Scripteurs et professionnels de l'informatique TechNet (microsoft.com)

    lundi 7 décembre 2020 15:24
  • 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 : CommandNotFoundException

    pour 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
    lundi 7 décembre 2020 18:44
  • 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.

    lundi 7 décembre 2020 20:53
  • 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é ;)

    mardi 8 décembre 2020 07:34
  • 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
    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

    mardi 8 décembre 2020 10:30
  • Bonjour Olivier,

    Sur Excel il n'y as pas de possibilité de choisir un enregistrement CSV -Encoding UTF8 avec séparateur point virgule.

    Seul le séparateur virgule le fait.

    je vais faire un test en modifiant dans le script le -Delimiter
    mercredi 9 décembre 2020 06:53
  • 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
    mercredi 9 décembre 2020 11:03
  • si regardes,

    mercredi 9 décembre 2020 11:40
  • 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"


    • Proposé comme réponse JMVianney mercredi 9 décembre 2020 14:13
    • Modifié JMVianney mercredi 9 décembre 2020 14:27
    mercredi 9 décembre 2020 14:13
  • 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 :)

    mercredi 9 décembre 2020 17:47
  • 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
    mercredi 9 décembre 2020 18:06
  • 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

    vendredi 11 décembre 2020 06:09
  • 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
    vendredi 11 décembre 2020 08:29