Question ValidateSet, ValidateScript et constante

Plus d'informations
il y a 10 ans 8 mois #20537 par Cédric MORIN
Bonjour !

Je suis face a un petit souci, pour le moment insoluble avec mes compétences.

J'ai écrit un script qui me permet de créer des machines dans notre AD, la place dans la bonne OU et lui affecte les groupes qui vont bien.

Pour la partie création de la machine et affectation des groupes, tout va bien. En revanche ce qui me pose souci c'est pour l'OU de destination.

Pour le moment j'ai un paramètre du script avec une longue liste dans le ValidateSet, voyez plutôt :
[code:1]
[Parameter(Mandatory = $True,
Position = 1,
HelpMessage = \"Département d'affectation de l'ordinateur (puis le service pour l'administration)\"
)]
[ValidateSet(\"ADM\",\"ADM45\",\"AIIT\",\"APS\",\"BIB\",\"CSN\",\"CSH\",\"DGP\",\"DRI\",\"GBA\",\"GCU\",\"GEI\",\"GME\",\"GMM\",\"GPE\",\"MED\",\"MSIAI\",\"PAO\",\"PRET-CRI\",\"STPI\"«»)]
[String]
$Dept,
[/code:1]
Ici, ce ne sont que les abréviations que l'on donne a nos OU, j'ai donc un Swith qui suit et qui fait le lien entre l'abréviation et le vrai nom :
[code:1]
Switch ($Dept){
\"ADM\" { Write-Host -Object \"\"
Write-Host -Object \"Choix de l'Ou pour l'administration\"
Write-Host -Object \"1 - Service Logistique Immobilière\"
Write-Host -Object \"2 - Service Vie de l'INSA\"
Write-Host -Object \"3 - Service Hygiène et Sécurité\"
Write-Host -Object \"4 - Service Formation Continue\"
Write-Host -Object \"5 - Service Financier - Agence Comptable\"
Write-Host -Object \"6 - Service Enseignement\"
Write-Host -Object \"7 - Service du Personnel\"
Write-Host -Object \"8 - Service Communication\"
Write-Host -Object \"9 - Secrétariat Général\"
Write-Host -Object \"10 - SAIC\"
Write-Host -Object \"11 - Direction de la Stratégie\"
Write-Host -Object \"12 - Direction et Secrétariat de Direction\"
Write-Host -Object \"13 - Direction de la Recherche\"
$Choix = Read-Host -Prompt \"Choix\"
Switch ($Choix){
1 {$OU=\"Service_Logistique_Immobiliere\"}
2 {$OU=\"Service_Vie_de_l_INSA\"}
3 {$OU=\"Service_Hygiene_et_Securite\"}
4 {$OU=\"Service_Formation_Continue\"}
5 {$OU=\"Service_Financier_Agence_Comptable\"}
6 {$OU=\"Service_Enseignement\"}
7 {$OU=\"Service_du_Personnel\"}
8 {$OU=\"Service_Communication\"}
9 {$OU=\"Secretariat_General\"}
10 {$OU=\"SAIC\"}
11 {$OU=\"Direction_de_la_Strategie\"}
12 {$OU=\"Direction_et_Secretariat_de_Direction\"}
13 {$OU=\"Direction_de_la_Recherche\"}
}
Write-host -Object \"$Choix : $OU\"
}
\"ADM45\" {$OU=\"Administration_des_annees_4-5\"}
\"AIIT\" {$OU=\"Association_des_ingenieurs_de_l_INSA_Toulouse\"}
\"APS\" {$OU=\"Centre_d_Activités_Physiques_et_Sportives\"}
\"BIB\" {$OU=\"Service_Commun_de_la_Documentation\"}
\"CSN\" {$OU=\"Centre_de_Ressources_Informatiques\"}
#\"CRITT\" {$OU=\"CRITT_Bio_industries\"}
\"CSH\" {$OU=\"Centre_des_Sciences_Humaines\"}
\"DGP\" {$OU=\"Departement_de_Genie_Physique\"}
\"DRI\" {$OU=\"Direction_des_Relations_Internationales\"}
\"GBA\" {$OU=\"Departement_de_Genie_Biochimique_et_Alimentaire\"}
\"GCU\" {$OU=\"Departement_de_Genie_Civil_et_Urbanisme\"}
\"GEI\" {$OU=\"Departement_de_Genie_Electrique_et_Informatique\"}
\"GME\" {$OU=\"Departement_de_Genie_Mecanique\"}
\"GMM\" {$OU=\"Departement_de_Genie_Mathematique\"}
\"GPE\" {$OU=\"Departement_de_Genie_des_Procedes_Industriels\"}
\"MED\" {$OU=\"Service_Medico_Social\"}
\"MSIAI\" {$OU=\"Master_Specialise_Ingenieur_d_affaires_industrielles\"}
\"PAO\" {$OU=\"Atelier_PAO_DAO\"}
\"PRET-CRI\" {$OU=\"Portables_de_pret\"}
#\"RESTAU\" {$OU=\"Service_Restaurant\"}
\"STPI\" {$OU=\"Departement_des_Sciences_et_Technologies_Pour_l_Ingenieur\"}
Default {Write-Host -foregroundcolor Red -Object \"Erreur de département\"
Return
}
}
[/code:1]

Bon, ça fonctionne, ce qui est bien, mais pas top...
Donc l'idée est de récupéré la liste des OU grace a ceci :
[code:1]$ListeOU = Get-ADOrganizationalUnit -Filter 'Name -like\"*\"' -SearchBase \"OU=Personnel,OU=Ordinateurs,DC=company,DC=mycompany,DC=fr\" -SearchScope OneLevel | Select-Object -Property Name[/code:1]

et de l'injecté dans le ValidateSet. Bon, ben forcement comme ça, ça veut pas. Evidement. Donc le met cela dans une constante, puis que la console me dit :
[code:1]
+ [ValidateSet($ListeOU)]
+ ~~~~~~~~
Les attributs de paramètre doivent être une constante ou un bloc de script.
+ CategoryInfo : ParserError: (:«») [], ParseException
+ FullyQualifiedErrorId : ParameterAttributeArgumentNeedsToBeConstantOrScriptBlock
[/code:1]

Mais non, même avec
[code:1]
Set-Variable ListeOU -Option Constant -Value (Get-ADOrganizationalUnit -Filter 'Name -like\"*\"' -SearchBase \"OU=Personnel,OU=Ordinateurs,DC=company,DC=mycompany,DC=fr\" -SearchScope OneLevel | Select-Object -Property Name) -Scope Global
[/code:1]

ça veut pas...

Du coup, avec ValidateScript, je me suis dit que je pourrais valider la variable $Dept, mais je perd l'autocompletion, et ça c'est pas possible, j'en ai besoin (c'est quand plus rapide que de taper \"Master_Specialise_Ingenieur_d_affaires_industrielles\", en plus c'est source d'erreurs.

Voila, comment je peut m'en sortir ? Je sèche complètement ...

Merci d'avance.

PS: j relis, et j’espère avoir fourni assez de détails et je me dit que c'est peut etre pas tout a fait du niveau débutant, ça non ? :-)

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

Plus d'informations
il y a 10 ans 8 mois #20539 par Laurent Dardenne
Salut,
Cédric MORIN écrit:

Bon, ça fonctionne, ce qui est bien, mais pas top...

Le mieux est l'ennemi du bien.
C'est verbeux certes, mais lisible. Tu peux essayer de condenser autour d'une hashtable : Key=\"ADM\",Value= { code}...
Cédric MORIN écrit:

et de l'injecter dans le ValidateSet.

Je ne sais pas si c'est possible, enfin moi, comme toi, je n'ai pas trouvé de solution dynamique autour de cet attribut.
Pour la liste des noms d'OU je ferais plutôt ceci :
[code:1]
[string[]] $ListeOU = @(Get-ADOrganizationalUnit -Filter 'Name -like\"*\"' -SearchBase \"OU=Personnel,OU=Ordinateurs,DC=company,DC=mycompany,DC=fr\" -SearchScope OneLevel |
Select-Object -ExpandProperty Name)
[/code:1]
Comme tu le dis l'attribut ValidateScript est possible :
[code:1]
[string[]]$Depts=@(\"ADM\",\"ADM45\",\"AIIT\"«»)

$SB={ Param([ValidateScript({$_ -in $Depts})]$Dept) Write-host \"Dept =$Dept\"}
&$SB -dept 'ADM'
#ok

&$SB -dept 'APS'
#erreur

#modifie la liste
[string[]]$Depts=@(\"ADM\",\"ADM45\",\"AIIT\",\"APS\"«»)
&$SB -dept 'APS'
#ok

rv Depts
&$SB -dept 'APS'
#erreur
'APS' -in $null
#False
[/code:1]
Autre approche : typer ton paramètre $Dept en une énumération créée dynamiquement à partir de tes noms d'OU.
Une limite : la session ne peut redéfinir la classe Enum, à moins d'exécuter cette partie dans un job, ainsi la classe n'est pas créée dans la session courante :
[code:1]
$Enums=@{}
$Enums.Dept=@(\"ADM\",\"ADM45\",\"AIIT\"«»)
# ou $Enums.Dept=$ListeOU
New-Enum $Enums
[Dept]$Dept='ADM'
[Dept]$Dept='APS'
#erreur
#close PS session

#new PS Session
#New OU 'APS'
$Enums=@{}
$Enums.Dept=@(\"ADM\",\"ADM45\",\"AIIT\",\"APS\"«»)
# ou $Enums.Dept=$ListeOU
New-Enum $Enums
[Dept]$Dept='APS'
[/code:1]
Il reste peut être une autre limite concernant les caractères des noms d'OU, par exemple la présence d'espaces.<br><br>Message édité par: Laurent Dardenne, à: 23/07/15 16:23

Tutoriels PowerShell

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

Plus d'informations
il y a 10 ans 8 mois #20540 par Cédric MORIN
OK, c'est bien ce qu'il me semblait, je cherche un mouton a 5 pattes... tant pis je vais essayer avec l'autre approche donc.

Laurent Dardenne écrit:

Autre approche : typer ton paramètre $Dept en une énumération créée dynamiquement à partir de tes noms d'OU.
Une limite : la session ne peut redéfinir la classe Enum, à moins d'exécuter cette partie dans un job, ainsi la classe n'est pas créée dans la session courante :


Euh...alors, la premiere phrase me plait, c'est, il me semble, ce que je voudrais obtenir. Il faut cependant que je garde l'autocompletion.
Par contre le reste....ben j'ai pas tout bien saisi ! Classe, job, je ne voit pas bien ce dont il s'agit :unsure:

Laurent Dardenne écrit:

Il reste peut être une autre limite concernant les caractères des noms d'OU, par exemple la présence d'espaces.&lt;br&gt;&lt;br&gt;Message édité par: Laurent Dardenne, à: 23/07/15 16:23

Pour ça, pas de danger, j'ai déjà éliminer, espace accent et autre caractère non supporte par nos amis anglo-saxons ^^

Merci de la réponse, je vais essayer avec une énumeration (enfin si je comprend ce que je fait...)

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

Plus d'informations
il y a 10 ans 8 mois #20542 par Laurent Dardenne
Cédric MORIN écrit:

OK, c'est bien ce qu'il me semblait, je cherche un mouton a 5 pattes.

Pas vraiment, tu peux tout à fait écrire un attribut spécifique afin d'implémenter ce besoin.
Bien que PS soit dynamique, parfois on aimerait qu'il le soit plus ;)
Cédric MORIN écrit:

Euh...alors, la premiere phrase me plait, c'est, il me semble, ce que je voudrais obtenir. Il faut cependant que je garde l'autocompletion.

L'auto complétion fonctionne avec une énumération.
Cédric MORIN écrit:

Par contre le reste....ben j'ai pas tout bien saisi ! Classe, job, je ne voit pas bien ce dont il s'agit :unsure:

Oubli, si tu rencontres le pb tu reviendras nous voir :)
Cédric MORIN écrit:

je vais essayer avec une énumération (enfin si je comprend ce que je fait...)

Soit tu analyses le code de New-Enum, soit tu l'utilises directement sans te poser de questions, sache que c'est du code validé en prod.

Le principe de cette fonction est de déclarer en Powershell les valeurs d'une énumération dans une hashtable, ensuite à partir de celle-ci la fonction crée le code d'une énumération en C#, code qui est compilé à la volée.

Comme c'est une classe C# tu ne peux pas la rédéclarer comme une variable Powershell, et tu dois la créer avant de la référencer.

Tutoriels PowerShell

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

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