none
Modifier valeurs dans un fichier csv pendant l'éxécution d'un script Powershell RRS feed

  • Question

  • Bonjour,

    Je suis entrain de rédiger un script Powershell afin de créer et générer des OU / Utilisateurs pour un ADDS.

    Je rencontre un problème, les données se modifie bien dans le .csv via 

    Set-Content ...

    , mais après le script a finit de s'éxécuter ...
    J'aimerai remédier à ce problème "bloquant" pour pouvoir continuer mon dev.

    Je vous remercie par avance de votre aide qui me sera précieuse je pense.

    j'ai commenté le code, la ou je rencontre un pb.

    ######################################################
    #        CREATE AND POPULATE YOUR ADDS               #
    #          **A script by brlndtech **                #
    #      github : https://github.com/brlndtech         #
    #            Please RTFM README.md                   #
    ######################################################
    
    
    Import-Module ActiveDirectory
    Import-Module 'Microsoft.PowerShell.Security'
    
    $users = Import-Csv -Delimiter ";" -Path "users-random.csv"
    
    
    $netbios=Read-Host "Entrez le NetBIOS de votre domaine (ex : entreprise) "
    $domain=Read-Host "Entrez votre .tld (ex : .com) "
    $site1=Read-Host "Entrez le nom de votre premier site "
    $site2=Read-Host "Entrez le nom de votre deuxième site "
    $site3=Read-Host "Entrez le nom de votre troisième site "
    
    # c'est ici que je rencontre un problème, les données se modifie bien, mais après le script a finit de # s'éxécuter ... 
    
    $content = Get-Content ".\users-random.csv" | foreach { $_ -replace "Paris","ville1" } 
    Set-Content -Path ".\users-random.csv" -Value $content
    
    $content = Get-Content ".\users-random.csv" | foreach { $_ -replace "Lyon","ville2" } 
    Set-Content -Path ".\users-random.csv" -Value $content
    
    $content = Get-Content ".\users-random.csv" | foreach { $_ -replace "Marseille","ville3" } 
    Set-Content -Path ".\users-random.csv" -Value $content
    
    # c'est ici que je rencontre un problème, les données se modifie bien, mais après le script a finit de # s'éxécuter ... 
    
    
        New-ADOrganizationalUnit -Name "Sites" -Path "dc=$netbios,dc=$domain"
    
        New-ADOrganizationalUnit -Name "$site1" -Path "ou=Sites,dc=$netbios,dc=$domain"
        New-ADOrganizationalUnit -Name "Services" -Path "ou=$site1,ou=Sites,dc=$netbios,dc=$domain"
        New-ADOrganizationalUnit -Name "Info" -Path "ou=Services,ou=$site1,ou=Sites,dc=$netbios,dc=$domain"
        New-ADOrganizationalUnit -Name "Compta" -Path "ou=Services,ou=$site1,ou=Sites,dc=$netbios,dc=$domain"
    
        New-ADOrganizationalUnit -Name "$site2" -Path "ou=Sites,dc=$netbios,dc=$domain"
        New-ADOrganizationalUnit -Name "Services" -Path "ou=$site2,ou=Sites,dc=$netbios,dc=$domain"
        New-ADOrganizationalUnit -Name "Info" -Path "ou=Services,ou=$site2,ou=Sites,dc=$netbios,dc=$domain"
        New-ADOrganizationalUnit -Name "Compta" -Path "ou=Services,ou=$site2,ou=Sites,dc=$netbios,dc=$domain"
    
        New-ADOrganizationalUnit -Name "$site3" -Path "ou=Sites,dc=$netbios,dc=$domain"
        New-ADOrganizationalUnit -Name "Services" -Path "ou=$site3,ou=Sites,dc=$netbios,dc=$domain"
        New-ADOrganizationalUnit -Name "Info" -Path "ou=Services,ou=$site3,ou=Sites,dc=$netbios,dc=$domain"
        New-ADOrganizationalUnit -Name "Compta" -Path "ou=Services,ou=$site3,ou=Sites,dc=$netbios,dc=$domain"
    
    
    #*******Ajout de chaque utilisateur dans son OU spécifique*******
    
    foreach ($user in $users) {
        
        $name = $user.firstName + " " + $user.lastName
        $fname = $user.firstName
        $lname = $user.lastName
        $login = $user.firstName + "." + $user.lastName
        $Uoffice = $user.office
        $Upassword = $user.password
        $dept = $user.department
      
        If ($user.office -eq "$site1") {
            switch($user.department)
            {
                "Info" {$office = "OU=Info,OU=Services,OU=$site1,OU=Sites,DC=$netbios,DC=$domain"} # à modifier, pour adpater à sa sauce 
                "Compta" {$office = "OU=Compta,OU=Services,OU=$site1,OU=Sites,DC=$netbios,DC=$domain"} # à modifier, pour adpater à sa sauce 
    
            }
        }
        ElseIf ($user.office -eq "$site2") {
            switch($user.department)
            {
                "Info" {$office = "OU=Info,OU=Services,OU=$site2,OU=Sites,DC=$netbios,DC=$domain"} # à modifier, pour adpater à sa sauce
                "Compta" {$office = "OU=Compta,OU=Services,OU=$site2,OU=Sites,DC=$netbios,DC=$domain"} # à modifier, pour adpater à sa sauce 
    
            }
        }
        ElseIf ($user.office -eq "$site3") {
            switch($user.department)
            {
                "Info" {$office = "OU=Info,OU=Services,OU=$site3,OU=Sites,DC=$netbios,DC=$domain"} # à modifier, pour adpater à sa sauce
                "Compta" {$office = "OU=Compta,OU=Services,OU=$site3,OU=Sites,DC=$netbios,DC=$domain"} # à modifier, pour adpater à sa sauce 
    
            }
        }
        
         try {
                New-ADUser -Name $name -SamAccountName $login -UserPrincipalName $login -DisplayName $name -GivenName $fname -Surname $lname -AccountPassword (ConvertTo-SecureString $Upassword -AsPlainText -Force) -City $Uoffice -Path $office -Department $dept -Enabled $true
                echo "Utilisateur ajouté : $name"
              
               
            } catch{
                echo "-Utilisateur non ajouté : $name"
           }   
    
    }
    #*********************Groupes Root************************
    New-ADGroup -Name G_Info_InterSite -GroupScope Global -GroupCategory Security -Path "ou=Sites,dc=coud,dc=local"
    New-ADGroup -Name G_Compta_InterSite -GroupScope Global -GroupCategory Security -Path "ou=Sites,dc=coud,dc=local"
    
    #*********************Groupes sous $site2************************
    New-ADGroup -Name G_Info_$site2 -GroupScope Global -GroupCategory Security -Path "ou=Info,ou=Services,ou=$site2,ou=Sites,dc=coud,dc=local"
    New-ADGroup -Name G_Compta_$site2 -GroupScope Global -GroupCategory Security -Path "ou=Compta,ou=Services,ou=$site2,ou=Sites,dc=coud,dc=local"
    
    #*********************Groupes sous $site1************************
    New-ADGroup -Name G_Info_$site1 -GroupScope Global -GroupCategory Security -Path "ou=Info,ou=Services,ou=$site1,ou=Sites,dc=coud,dc=local"
    New-ADGroup -Name G_Compta_$site1 -GroupScope Global -GroupCategory Security -Path "ou=Compta,ou=Services,ou=$site1,ou=Sites,dc=coud,dc=local"
    
    #*********************Groupes sous $site3************************
    New-ADGroup -Name G_Info_$site3 -GroupScope Global -GroupCategory Security -Path "ou=Info,ou=Services,ou=$site3,ou=Sites,dc=coud,dc=local"
    New-ADGroup -Name G_Compta_$site3 -GroupScope Global -GroupCategory Security -Path "ou=Compta,ou=Services,ou=$site3,ou=Sites,dc=coud,dc=local"
    
    foreach ($user in $users){
    
        $name = $user.firstName + " " + $user.lastName
        $fname = $user.firstName
        $lname = $user.lastName
        $login = $user.firstName + "." + $user.lastName
        $Uoffice = $user.office
        $Upassword = $user.password
        $dept = $user.department 
    
    
    #********Ajout des utilisateurs de $site2 dans leurs groupes********************
    
        if ($Uoffice -eq "$site2" -and $dept -eq "Info"){
    
            Add-ADGroupMember -Identity "G_Info_$site2" -Members $login
            echo "$name a été ajouté au groupe G_Info_$site2"
    
        }
        elseif ($Uoffice -eq "$site2" -and $dept -eq "Compta"){
    
            Add-ADGroupMember -Identity "G_Compta_$site2" -Members $login
            echo "$name a été ajouté au groupe G_Compta_$site2"
    
        }
    
    
        #********Ajout des users de $site3 dans leurs groupes********************
    
    
        if ($Uoffice -eq "$site3" -and $dept -eq "Info"){
    
            Add-ADGroupMember -Identity "G_Info_$site3" -Members $login
            echo "$name a été ajouté au groupe G_Info_$site3"
    
        }
        elseif ($Uoffice -eq "$site3" -and $dept -eq "Compta"){
    
            Add-ADGroupMember -Identity "G_Compta_$site3" -Members $login
            echo "$name a été ajouté au groupe G_Compta_$site3"
    
        }
    
    
    #********Ajout des users de $site1 dans leurs groupes********************
    
    
        if ($Uoffice -eq "$site1" -and $dept -eq "Info"){
    
            Add-ADGroupMember -Identity "G_Info_$site1" -Members $login
            echo "$name a été ajouté au groupe G_Info_$site1"
    
        }
        elseif ($Uoffice -eq "$site1" -and $dept -eq "Compta"){
    
            Add-ADGroupMember -Identity "G_Compta_$site1" -Members $login
            echo "$name a été ajouté au groupe G_Compta_$site1"
    
        }
    
    } #Accolade fermante de notre boucle – Fin de la boucle
    
    Add-ADGroupMember -Identity 'G_Info_InterSite' -Members G_Info_$site1,G_Info_$site2,G_Info_$site3
    Add-ADGroupMember -Identity 'G_Compta_InterSite' -Members G_Compta_$site1,G_Compta_$site2,G_Compta_$site3



    mardi 3 mars 2020 06:25

Toutes les réponses

  • Bonsoir,

    pouvez-vous indiqué l'erreur exacte et bloquante ?

    Pour le moment, le seul problème éventuel à partir de la ligne

    New-ADOrganizationalUnit -Name "Sites" -Path "dc=$netbios,dc=$domain""

    Peut correspondre au fait que l'OU existe déjà et que le script s'arrête (Erreur rouge).

    A tout hasard, vérifier que le script est bien exécuté dans un Powershell en mode "administrateur".

    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

    mardi 3 mars 2020 22:15
  • bonjour technherb

    en complément de ce qu'a écrit Thierry (pas de test existence OU avant création), ajoute juste en début de ta boucle foreach un Write-Output "traitement de $'$user.lastname)" comme ça tu verra si tu rentre ou pas dans ta boucle. ensuite je vois,

    • ta variable $user tu l'importe bien en ligne 12, tu mets à jour ton fichier en ligne 24 et 27, mais ta variable, elle n'est pas réactualisée. Import-csv dans $user pour voir ta variable réactualisée.en ligne 31 par ex.
    • dans la 1ère boucle foreach (ligne55) tu fais 2 plusieurs choses : custo attribut department, et création user, je ne vois pas de pb particulier à ce niveau
    • ensuite tu crées des groupes (100 à 114) : pas de vérification existence de groupes
    • tu reparts dans une même boucle foreach ou l'à tu ajoutes tes users dans les groupes.
    • et enfin après le foreach tu ajoutes les groupes dans d'autres groupes.

    ==> Je te propse de le jouer différemment:Création des groupes (avec vérf existence avant créatiion), ajout des groupes dans les groupes, puis boucle foreach user ou tu fais tout ce que tu a mise dans tes 2 boucles (création comptes si pas existant et ajout dans groupes). 

    Evite l'utilisation de Echo, c'est un Alias. Autant tu peux utiliser des alias quand tu passes des lignes directement dans les scripts, autant c'est déconseillé dans des scripts. Met Write-Output. Pour le respect des bonnes pratiques, Invoke-ScriptAnalyzer (module PSScriptsAnalyzer)  aide bien (en standard avec DS Code, à ajouter avec ISE ou PS)

    Pour le débug, tu es derrière la console, n"hésites pas à ajouter des Write-Output  ou des Write-Host (avec -ForegroundColor c'est plus joli) pour voir ce qui passe et ce qui ne passe pas.

    en ligne 65, tu écris $user.office .... , alors que tu viens de définir $uoffice en ligne 61. puis dans ton switch, si $Office = Info alors change la valeur par un nom F.Q.D.N.  EN fait en lisant plus loin, $Office est le path ou doit être créé le compte. Change le nom de ta variable($uPath par exmple) , ça facilite la comprehension et évitera des boulettes. idem pour $uoffice ($user.office) qui correspond à l'attribut City des comptes.

    dans tes catchs ajoute un Write-Output $Error.Exception.Message, comme ça tu sauras pourquoi ton compte n'a pas été ajouté.

    Une fois ton script exécuté tu ne sais pas ce qui a été crée et pas créé. un fichier de log pour tout ça, bien pratique. Commence par un Start-Transcript (mode easy way mais loggin sale), et si tu veux faire quelques choses de bien utilise le module EZLog (prononcer EasyLog), probablement le meilleur module de log exisitant. Une seule cmdlet à connaitre Write-Ezlog , il remplacera facilement à la fois les write-Outptut et le logging en console (regarde l'exemple 3) donné en exemple sur le github, ca facile énormément l'utilisation (pas la peine de préciser à chaque utilisation le path pour le log, le delimiter custom éventuel, si tu veux un affichage en console ...

    d'ailleurs, dans le esprit (utilisation de $PSDefaultParameterValues)  ajoute Import-Csv avec le delimiter que tu veeux, ainsi quand tu feras appel à cette cmdlet plus loin dans ton script, inutile de lui préciser le délimiter à chaque fois. il le prendra par défaut. Ok, dans ton script, tu ne l'utilise qu'une seule fois mais comme écrit avant je pense que tu devrais l'utiliser 2 fois.

    point supplémentaire, ton script est destiné à n'être exécuté qu'en mode interactif (Read-hHost). Par la sute, tu t'apercevras que cela n'est peut-être pas la meilleures façon de partiquer et tu voudras peut être l'exécuter en mode "silencieux" (tâche planifiée par ex). tu as quasiment tout pour faire (ligne 15 à 19). Il te suffit d'ajouter en début de script une section Param (comme dans une advanced function) et de lui passer des valeurs par défaut utilisant des variables automatiques ou pas. ex. avec 1 seule variable

    Param    (       

    # Netbios (valeur par défaut le domain courant)

            [Parameter(Mandatory=$true,

            ValueFromPipeline=$true,

            ValueFromPipelineByPropertyName=$true)]

    $Netbios = $env:USERDOMAIN

    )

    ainsi tu pourras exécuter ton script avec les valeurs par défaut ou en lui passant en paramètre les valeurs des variables.

    Je termine par un dernier truc. OK, ton script marche,il fait ce qu'il doit faire, ça serait peut être utile de "prouver" que tu as fait ce que demandé (export dans un .csv des comptes créés et des comptes non créés, des membres des groupes, .... Je dis .csv par facilité, mais tu peux directement exporter dans un fichier excel joli tout plein avec le module ImportExcel et la cmdlet Export-Excel. Ca sera joli tout plein

    cordialement

    Olivier 

    P.S. : promis un jour j'apprendrais ce que veut dire le mot "conscision". :-)


    mercredi 4 mars 2020 07:12