Question aide pour corriger script AD

Plus d'informations
il y a 3 ans 2 mois #30428 par garrigues
Réponse de garrigues sur le sujet aide pour corriger script AD
Bonsoir, merci pour tes réponses, je vais du coup expliquer un peu le contexte car je pense que ma création d'utilisateurs via script dans mon AD ne se fait mais peut être pas aussi bien que sa.

J'ai un fichier CSV avec des utilisateurs contenant : CN, distiguishedname, enable, prénom, mail, name: (prénom+nom), samaccountname, nom, userprincipalname, groupe:(groupe principal),  groups(groupe secondaire pour ceux qui en ont un), path (ou secondaire,ou principale,dc,dc).

Le but du script était d'automatiser le + possible la création des OU, groupes, utilisateurs et pour finir mettre les utilisateurs dans leur/s groupe/s suivant s'ils en avient 1 ou 2.

Derrière sa je devais importer dans GLPI mes utilisateurs créés précédement avec mon script, sauf que lorsque j'essaye de les iomporter GLPI ne les trouvent pas.

J'avais fait cet exercice sous virtual box (je m'étais fait une doc avec les réglages etc) mais sans utiliser de script qui avait fonctionné.

Etant passé sur VMware je voulais donc refaire le même exercice sur la base GLPI (mais avec d'autres choses différentes pour la suite ).

J'ai donc tenté de me faire un script (celui que j'ai poster) qui fait tout ce que je voulais mais sûrement pas comme il faut puisque la suite qui avait fonctionner quand tout avait été créé à la main (sur VB) ne fonctionne pas après avoir créé mes utilisateurs via mon script sur VMware.

Pour répondre du coup à la question pour le $name et $nom c'est comme je l'ai expliquer au-dessus que l'un met prenom+nom quand l'utilisateur est créé dans son OU et l'autre uniquement le nom qui a fait qu'un utilisateur n'avait pas été créé puisqu'il y en avait déjà un avec le même nom (mais pas le même prénom et sa le script n'en a pas tenu compte).

>> Pour être assuré que cela fonctionne, que cela réponde à ton besoin, tu peux créer des tests unitaires avec Pester, mais c'est une autre étape.
Euh j'ai tenter de lire un peu à quoi correspondait les test  PESTER et mon cerveau a fumé et m'a dit qu'il avait pas compris la question .
Je vais quand même regarder un peu plus de choses sur PESTER, voir des tutos s'il y en a, car sa a l'air très intéressant mais aussi trés compliqué...

Pour le "try" "catch" , je n'ai vu des exemples que pour des créations réussies, ne connaissant pas le fonctionnement de cette combinaison, je l'ai utilisé pour les création qui devaient réussir .

Enfin pour ce qui concerne le "Hashtable" je ne savais pas que sa existait (je n'ai que 30h de powershell en expérience dont 25h minimum d'erreurs ) , mais c'est très pratique car sa évite une ligne de commande à rallonge et du coup limite le risque d'erreurs .

Je vais donc commencer par mettre tout en anglais (pour unifier la langue), puis inverser mes "try" "catch" sur les tests qui sont censés échouer pour voir le comportement , tester le "Hashtable" et pour finir essayer de comprendre pourquoi mes utilisateurs créés avec mon script ne s'importent pas dans mon GLPI.

Je reviendrais donner des nouvelles sur l'évolution du script et sur l'avancement de mon infrastructure virtuelle .
Merci encore pour les conseils 

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 3 ans 2 mois - il y a 3 ans 2 mois #30429 par Laurent Dardenne
>>Pour répondre du coup à la question pour le $name et $nom
Justement, une simple lecture d'un code ne devrait pas nécessiter 3 lignes d'explication pour le comprendre, en tout cas ici.

>>J'ai un fichier CSV avec des utilisateurs contenant : CN, distiguishedname, enable, prénom, mail, name: (prénom+nom), samaccountname, nom, userprincipalname, groupe: (groupe principal), groups (groupe secondaire pour ceux qui en ont un), path (ou secondaire,ou principale,dc,dc).
Pour
name = (prénom+nom)
groupe=(groupe principal) et
groups=(groupe secondaire pour ceux qui en ont un)

Je te propose de renommer ces champs ainsi :
FullName
GroupePrincipal
GroupeSecondaire

Ainsi tu n'as plus besoin de préciser ce que c'est, c'est comme le 'Port Salut' ...

>>car ça a l'air très intéressant mais aussi trés compliqué...
C'est comme tout le reste lorsqu'on ne connait pas. La dernière version se comporte différement avec la notion de portée sous Powershell, c'est qui le rend désormais, à mon avis, moins accessible pour un débutant.
C'est juste du code qui teste du code en utilisant les possibilités de Powershell.
La question ici est de prouver, tant que faire se peut, que cela fonctionne. C'est en quelque sorte de la 'maintenance préventive'.

>>ne connaissant pas le fonctionnement de cette combinaison
Il est tout de même préférable, pour gagner du temps, d'accepter d'en perdre à comprendre comment cela fonctionne.
Dans ma signature il y a un un lien vers des tutoriaux, dont un sur la gestion des erreurs.

>>mais c'est très pratique car sa évite une ligne de commande à rallonge
Exact.

>>et du coup limite le risque d'erreurs
Pas sûr :-)

Tutoriels PowerShell
Dernière édition: il y a 3 ans 2 mois par Laurent Dardenne. Raison: formatage

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 3 ans 2 mois - il y a 3 ans 2 mois #30430 par garrigues
Réponse de garrigues sur le sujet aide pour corriger script AD
Bonjour Laurent, merci pour tes conseils et tes réponses. mon script continu d'évoluer tout comme les idées que j'ai pour l'amelliorer encore plus (je suis pénible avec moi même car même si sa marche je veux que sa soit mieux ).

Actuellement mon script fait donc:
la création des OU, il m'affiche un message de 2 couleurs différentes pour dire si une OU a été créée ou si elle exitait déjà.
Même chose pour les groupes .
Il me créé les utilisateurs et la aussi 2 couleurs et messages pour me dire si l'utilisateur existait ou s'il a été créé.


Là ou je bloque par contre c'est pour l'intégration dans les groupes, le script le fait mais je n'arrive pas à trouver comment y intégrer des tests, j'aurais aimé que le script teste :
- dans le fichier csv si l'utilisateur a bien un groupe  et m'affiche un 1er message
- si l'utilisateur est déjà dans ce groupe et qu'il m'affiche un second message,
- enfin si l'utilisateur a bien un groupe noté dans le csv mais qu'il ne s'y trouve pas, alors le script l'intègre au groupe et afiche la aussi un message précisant l'ajout de l'utilisateur à son groupe( c'est la partie fonctionnant mais pas comme il faut car il me met toujours le message d'intégration même si l'utilisateur été déjà intégré...).

Je pensais faire les test à partir de mon csv dans une boucle "foreach" pour les 3 tests mais actuellement sa ne marche pas du tout .
Pour le second j'ai recherché sur le net mais pour le moment mes tentatives et tests de certaines solutions trouvées sont veines .
Du coup je me demande s'il ne faudrait pas plutôt que je fasse un "foreach" pour chaque tests et actions à réaliser.

J'aurais aimé faire sa pour le groupe principal et le groupe secondaire.

Pour finir j'aimerais qu'a la fin du script un fichier soit généré récapitulant toutes les actions qui ont été faites (ou du moins qu'il mintègre les réponses qui sont afichées à l'écran disant si telle ou telle chose existait ou a été créée).

Si tu as un début de piste je serais preuneur car là je sèche complètement, j'ai bien tenté des "try catch" mais pas sûr que sa soit adapté à la situation (je n'ai pas encore bien intégré a quel moment on doit utiliser les 2)

Merci d'avance pour ton aide et tes indications qui m'ont déja été utiles

 
Dernière édition: il y a 3 ans 2 mois par garrigues.

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 3 ans 2 mois - il y a 3 ans 2 mois #30431 par Laurent Dardenne
Salut,

tu fais il me semble, l'erreur de base avec Powershell, tu couples les traitements, ici leur résultat, avec l'affichage.
Il faut 'découper' ton script en + parties à l'aide de fonction.

>>Du coup je me demande s'il ne faudrait pas plutôt que je fasse un "foreach" pour chaque tests et actions à réaliser.
Il faut un traitement de validation des données, un résultat, un ou + traitements sur le résultat de cette validation.
Si toutes les données sont fausses les traitements suivants le seront aussi.

Il faut un traitement (une action), un résultat (une action sur un user), un ou + traitements sur le résultat.

Ensuite sans le code, difficile de le lire et encore plus de t'aider.Enfin je n'ai pas de jeux de test ni d'AD sous la main...

>>Pour finir j'aimerais qu'a la fin du script un fichier soit généré récapitulant toutes les actions qui ont été faites
>> (ou du moins qu'il m'intègre les réponses qui sont affichées à l'écran disant si telle ou telle chose existait ou a été créée).

Si tu as une structure de données qui mémorise ce déroulement tu pourras faire ce que tu veux, ou presque.
1 intègrer les réponses (action)
2 affichées (rendu)
3 si telle ou telle chose existait ou a été créée ( détails/résultat)

>>Si tu as un début de piste je serais preneur car là je sèche complètement
Je fais ça souvent(contrôle,action, rapport), mais ici je dois extraire ce type de traitement, l'adapter et le documenter. Ce qui prend du temps...
Communique le script (code existant) et son déroulement (pseudo code)

Tutoriels PowerShell
Dernière édition: il y a 3 ans 2 mois par Laurent Dardenne.

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 3 ans 2 mois - il y a 3 ans 2 mois #30432 par garrigues
Réponse de garrigues sur le sujet aide pour corriger script AD
Re-bonjour, je te remercie encore une fois pour les réponses et aides que tu me donne.

Etant novice en powershell même si maintenant je commence à comprendre certaines choses un peu mieux, je pense que je n'ai depuis le début pas la bonne approche qu'aurait quelqu'un de + expérimenté que moi.

A commencer par les fonctionss et le déroulement d'un script, j'improvise un peu en fonction des idées qui me viennent sur le moment alors qu'un vrai et bon scripteur lui réfléchira en amont à tout ce que dois faire le script et ensuite passera à sa création.

Je pense par exemple aux test d'intégration des utilisateurs dans les groupes principaux (en particulier le test vérifiant que l'utilisateur ai bien un groupe principal indiqué dans le csv).
Je me suis demandé si au final ce test avait un interêt et quel serait l'utilité.

Après y avoir réfléchi, la réponse est "oui" ce test a un interêt si par exemple si la personne ayant fait le csv a oublié de noter le groupe principal de l'utilisateur on peut le voir grâce à ce test et donc par exemple le corriger manuellement à l'aide d'un choix pour indique le nom d'un groupe manuellement et que le script intègre ensuite l'utilisateur dans son groupe.

Ce même test pour les groupes secondaires par contre n'est pas forcément intéressant vu que tout les utilisateurs n'ont pas forcément plusieurs groupes secondaires.

J'ai donc un peu avancé sur la partie des test d'intégration dans les groupes, j'ai commencé par vérifier que chaque utilisateurs ai bien un groupe principal dans le csv.

La chronologie du script est la suivante: création OU racine, création Ou enfant, création des groupes dans l'OU qui les héberge tous, création des utilisateurs, intégration de tout les utilisateurs dans leur groupes.

Voici donc la partie fonctionnelle du script:

Cette partie correspond à tout ce qui touche aux OU ( l'OU racine + les OU enfants)

#Chargement des modules active directory
Import-Module ActiveDirectory

$MyForegroundColor=@("Green")
$MyForegroundColor1=@("Yellow")
$MyForegroundColor2=@("red")


#création de l'UO racine

$Domain = read-Host "non de votre domaine ex: DC=myDomain,DC=com"
$Root_OU = Read-Host "nom de votre OU racine"

    if ((Get-ADOrganizationalUnit -filter "name -like'*$($Root_OU)'")){
       write-host -ForegroundColor $MyForegroundColor1 "l'organisation $Root_OU est deja presente dans l'AD"
    }

    else {
       New-ADOrganizationalUnit -Name $Root_OU -Path $Domain -ProtectedFromAccidentalDeletion $false
       write-host -ForegroundColor $MyForegroundColor "la creation de l'organisation $Root_OU a fonctionne correctement"
    }



#Creation des UO
$OUs=import-csv -path "C:\OU-AP.csv" -delimiter ";"
 
foreach($ou in $OUs)
{
$parametersOU=@{
Name=$ou.name
Path=$ou.path
ProtectedFromAccidentalDeletion= $false
}
$oun= $ou.name

    if ((Get-ADOrganizationalUnit -filter "name -like'*$($ou.name)'"))
    {
            write-host -ForegroundColor $MyForegroundColor1 "l'organisation $oun est deja presente dans l'AD"
    }

    else
    {
            New-ADOrganizationalUnit @parametersOU

            write-host -ForegroundColor $MyForegroundColor "la creation de l'organisation $oun a fonctionne correctement"
    }
}


La partie suivante concerne uniquement la création des groupes dans l'OU qui les contient

#Creation des groupes
$Groups=import-csv -path "C:\groupes.csv" -delimiter ";"

foreach($Group in $Groups)
{
$group= $Group.name

    if ((Get-ADGroup -filter "name -like'*$($group)'"))
    {
            write-host -ForegroundColor $MyForegroundColor1 "le groupe $group est deja present dans l'AD"
    }

    else
    {
            New-ADGroup  -GroupScope: "Global" -GroupCategory: "Security" -Name $group.name -Path $Group.path
            
            write-host -ForegroundColor $MyForegroundColor "la creation du groupe $goup a fonctionne correctement"      
    }  
}


Cette partie concerne la création des utilisateurs

#création des utilisateurs

# Importation des utilisateurs depuis le fichier CSV spécifié
$Users=import-csv -path "C:\users-domjacom.csv" -delimiter ";"

# Demande du mot de passe par défaut
$password=Read-Host -AsSecureString "Taper le mot de passe par défaut des utilisateurs" -PassThrue -PasswordNeverExpire $true

# Création de l'utilisateur
foreach($user in $Users)
{
#hashtable
$parametersusers=@{
Name= $user.UserName
GivenName= $user.GivenName
Path= $user.path
SamAccountName= $user.SamAccountName
UserPrincipalName= $user.UserPrincipalName
EmailAddress= $user.EmailAddress
SurName= $user.SurName
Enabled= $true
DisplayName= $user.MailNickname
#Splatting ( clé de hastable= nom d'un paramètre ; valeur de la clé = valeur du paramètre)
}
$name= $user.UserName
    if ((Get-ADUser -filter "name -like'*$($name)'"))
    {

            write-host -ForegroundColor $MyForegroundColor1 "l'utilisateur $name est deja present dans l'AD"
    }

    else
    {
        $new= New-ADUser @parametersusers -AccountPassword $password

        write-host -ForegroundColor $MyForegroundColor "l'utilisateur $name a bien ete cree dans l'AD"    
    }
}


Ces 3 premieres parties fonctionnent et répondent aux attentes que je souhaitais.

Il reste la denière partie avec les intégrations des utilisateurs dans leurs groupes

voici la dernière partie que je suis entrain de travailler

#Ajout des utilisateurs dans les groupes primaires et secondaires

#Ajout des utilisateurs aux groupes primaires

$UGs=import-csv -path "C:\users-domjacom.csv" -delimiter ";"

foreach($UG in $UGs)
{
$name=$UG.UserName

#test si le csv contient un groupe principal pour l'utilisateur
if  ($UG.group -eq $null)
    {
        write-host -ForegroundColor $MyForegroundColor2 "l'utilisateur $name n'a pas de groupe principal"
        write-host "voulez vous indiquer un groupe pour l'uitilsateur $name ?"
        switch (choix)
        {
        '1'
        {
        $choix1="yes"
        $ng= read-Host "ajouter $name a un groupe: ex gg-* "
        Add-ADGroupMember -Members $UG.SamAccountName  -Identity $ng
        }
        '2'
        {
        $choix2="no"
        }
        }

foreach($UG in $UGs)
{
$sam=$UG.SamAccountName
$name=$UG.UserName
if  (!($UG.group -eq $null))
    {
        write-host -ForegroundColor $MyForegroundColor1 "l'utilisateur $name a un groupe principal"
    }
    }

else
    {
  Add-ADGroupMember -Members $UG.SamAccountName  -Identity $UG.group

  write-host -ForegroundColor $MyForegroundColor "l'utilisateur $name a bien ete integre dans son groupe principal"
    }
    }


La partie en rouge n'est pas finie, je travaille dessus actuellement pour savoir comment dire a mon script de continuer si l'utilisateur du script répond '"non" (a moins de partir du principe qu'il est obligatoire que chaque utilisateurs ai un groupe principal auquel cas mon choix ne sert a rien )

Il me restera enfin le dernier test qui consiste a savoir si chaque utilisateur qui a son groupe principal est bien effectivement dedant (la je ne vois pas comment faire pour le moment...)
Pour finir il faudra du coup que je fasse une fonction comme tu me l'indique pour chaques partie du script afin de pouvoir récupérer les résultats dans un fichier de contrôle (là aussi je risque d'avoir besoin de piste pour l'extraction des résultats et pas du coup de l'affichage qui devront être envoyés dans le fichier de contrôle.

Je travaille aussi avec des linux et ce qu'on nous as appris c'est que chaque action que l'on fait il vaut mieux la vérifier et surtout vérifier le résultat, sa évite de mauvaises surprise par la suite, c'est pour sa que j'essaye de tester et vérifier un maximum d'informations.
Dernière édition: il y a 3 ans 2 mois par garrigues.

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 3 ans 2 mois #30433 par Laurent Dardenne
Je te répond juste sur un point.

Un jeu de test :
Function New-UserInfos{
#New-PSCustomObjectFunction -Noun UserInfos -Parameters Name,GivenName,Path,SamAccountName,UserPrincipalName,EmailAddress,SurName,DisplayName -File
 param(
        [Parameter(Mandatory=$True,position=0)]
    $Name,
        [Parameter(Mandatory=$True,position=1)]
    $GivenName,
        [Parameter(Mandatory=$True,position=2)]
    $Path,
        [Parameter(Mandatory=$True,position=3)]
    $SamAccountName,
        [Parameter(Mandatory=$True,position=4)]
    $UserPrincipalName,
        [Parameter(Mandatory=$True,position=5)]
    $EmailAddress,
        [Parameter(Mandatory=$True,position=6)]
    $SurName,
        [Parameter(Mandatory=$True,position=7)]
    $DisplayName
 )

  [pscustomobject]@{
    PSTypeName='UserInfos'; #Permet de typer un objet personnalisé
    Name=$Name;
    GivenName=$GivenName;
    Path=$Path;
    SamAccountName=$SamAccountName;
    UserPrincipalName=$UserPrincipalName;
    EmailAddress=$EmailAddress;
    SurName=$SurName;
    DisplayName=$DisplayName;
  }
}

$users=@(
    New-UserInfos -Name 'user1' -GivenName 'user1Full' -Path 'path' -SamAccountName 'SamAccountName1' -UserPrincipalName 'User1PrincipalName' `
                  -EmailAddress 'user1@Mail.com' -SurName  'User1SurName' -DisplayName 'user1MailNickname'
    New-UserInfos -Name 'user2' -GivenName 'user2Full' -Path 'path' -SamAccountName 'SamAccountName2' -UserPrincipalName 'User2PrincipalName' `
    -EmailAddress 'user2@Mail.com' -SurName  'User2SurName' -DisplayName 'user2MailNickname'

    New-UserInfos -Name 'user3' -GivenName 'user3Full' -Path 'path' -SamAccountName 'SamAccountName3' -UserPrincipalName 'User3PrincipalName' `
    -EmailAddress 'user3@Mail.com' -SurName  'User3SurName' -DisplayName 'user3MailNickname'
)

foreach ($user in $users) 
{
  #Ajoute des membres permettant de mémoriser le résultat d'une action
  #isExist : par défaut à false, on suppose que le compte n'existe pas.
  #isCreated : par défaut à false, on suppose, si le compte n'existe pas, que sa création à échouer.
  #On ne peut avoir isExist=$True et isCreated= $true.
  #Si en fin de traitement on a isExist=$False et isCreated= $false, la création a échouée.
  #etc
    $user|
     Add-member -MemberType NoteProperty -Name isExist -Value $false -PassThru|
     Add-member -MemberType NoteProperty -Name isCreated -Value $false
}
On réutilise la structure de donnée $User que l'on a enrichi :
foreach($user in $Users)
{
    $name= $user.UserName
    $parametersusers=@{
        Name= $Name
        ...
    }
   
    if ((Get-ADUser -filter "name -like'*$($name)'"))
    {  
       $user.IsExist=$True
       write-host -ForegroundColor $MyForegroundColor1 "L'utilisateur '$name' est déjà présent dans l'AD."
    }
    else
    {
        $new= New-ADUser @parametersusers -AccountPassword $password
        $user.isCreated=$True
        write-host -ForegroundColor $MyForegroundColor "Utilisateur '$name' crée."    
    }
}
$Users
Ainsi en fin de traitement tu mémorises le résultat des actions (ici une seule, mais 2 infos à mémoriser).
Ce qui permet de filtrer la collection d'utilisateurs et/ou de les grouper par état.
Et à partir de là créer un rapport si besoin ( en texte, en pdf, en Html,...)

En passant :
Dans les chaînes d'affichage/log insère le nom des variables entre simple quote : "L'utilisateur '$name' crée."
En cas d'erreur on le remarque plus rapidement.

Et pour
"if ($UG.group -eq $null)"
Un membre d'objet issu du cmdlet Import-csv ne sera jamais null mais vide ([String]::Empty), car on manipule du texte.
Et en Powershell une chaine de caractères ne contient jamais $null.

Ici :
New-ADGroup -GroupScope: "Global" -GroupCategory: "Security"
simplfie en :
New-ADGroup -GroupScope 'Global' -GroupCategory 'Secu

Tutoriels PowerShell

Connexion ou Créer un compte pour participer à la conversation.

Temps de génération de la page : 0.105 secondes
Propulsé par Kunena