Question [Astuce]Analyse des paramètres d'un script/fnction
- Laurent Dardenne
- Auteur du sujet
- Hors Ligne
- Modérateur
-
Réduire
Plus d'informations
- Messages : 6311
- Remerciements reçus 68
il y a 17 ans 3 mois #3464
par Laurent Dardenne
Tutoriels PowerShell
Réponse de Laurent Dardenne sur le sujet Re:[Astuce]Analyse des paramètres d'un script/fnction
Une correction de la version spécifique à PowerShell v1.
L'opérateur cast à un comportement différent des langages de POO tels que Delphi,C#,java,etc.
Si l'opération de cast échoue elle ne renvoi pas $null mais convertie l'objet en une string via un appel à la méthode ToSring().
[code:1]
function ValidateParameter([string]$Name,$Parameter,[Type] $Type, [Switch] $Strict)
{ # Renvoi $False si le contenu est à $Null.
# Si la validation demandée est stricte et que le type du paramètre est du type attendu , on renvoie $True
# Si la validation demandée est stricte et que le type du paramètre n'est pas du type attendu -> Exception
# Si la validation demandée n'est pas stricte, que le type du paramètre est du type attendu et
# que le cast réussi, on renvoi $True
# Si la validation demandée n'est pas stricte, que le type du paramètre n'est pas du type attendu et
# que le cast échoue -> Exception (note : avec le type [string] dans ce cas le cast réussi toujours)
#
#
# Exception : ArgumentTransformationMetadataException
Write-Debug \"ValidateParameter\"
Write-debug \"$Name\"
if ($Parameter -ne $null)
{Write-debug \"$($Parameter.GetType())\"}
else
{
Write-debug \"`Le paramètre $Name est à `$null.\"
return $False
}
Write-debug \"$Parameter\"
Write-debug \"$Type\"
#$host.EnterNestedPrompt()
#Le paramètre reçu est-il du type attendu ?
$isSameType=$Parameter -is $Type
#Peut-on caster la valeur reçue dans le type attendu ?
#En cas de cast impossible, l'opérateur -as appel la méthode ToString()
#Ce qui reste cohérent avec le parsing de PowerShell.
#Si le paramétre attendu est de type [string], dans ce cas une date sera transformée en string.
#Le cast du paramètre en un type [string] réussira toujours !
$isCastFail=($Parameter -as $Type) -eq $null
Write-debug \"$isNotSameType : $isNotSameType\"
Write-debug \"isCastFail : $isCastFail\"
#Si le cast demandé est strict, le type du paramètre doit être celui du type attendu
#ou
#si le cast demandé n'est pas strict que le type du paramètre n'est pas celui du type attendu et que le cast échoue.
if ( ($Strict.IsPresent -and !$isSameType) -or (!$Strict.IsPresent -and !$isSameType -and $isCastFail) )
{ #récupére le contexte d'appel de l'appelant
$Invocation = (Get-Variable MyInvocation -Scope 1).Value
throw (new-object System.Management.Automation.ArgumentTransformationMetadataException \"$($Invocation.MyCommand).$($MyInvocation.MyCommand) : Impossible de convertir la valeur du paramètre $name « $($Parameter.GetType()) » en type « $($Type.ToString()) ».\"«»)
}
return $True
} #ValidateParameter
[/code:1]
test :
[code:1]
Function SendMail( $attach)
{
if (ValidateParameter \"attach\" $attach String)
{
if ( $Attach -eq [string]::Empty) {Throw \"Le contenu du paramètre Attach n'est pas renseigné.\"}
if (! (Test-path $Attach)) {Throw \"Le fichier n'existe pas : $Attach\"}
$Attach
\"Send mail\"
}
else {Throw \"La valeur du paramètre Attach est`$null ou n'est pas du type String.\"}
}
Sendmail
Sendmail \"\"
Sendmail \"C:\notExist.txt\"
# PS cast une date en une string
Sendmail get-date
Sendmail (get-date)
Sendmail 1..5
# PS cast un tableau en une string
Sendmail @(1..5)
Sendmail (Dir c:\)
[/code:1]
L'usage du switche Strict force la validation sur le type attendu et seulement celui-ci
[code:1]
if (ValidateParameter \"attach\" $attach String -Strict)
[/code:1]
Dans ce cas, à la différence de l'appel précédent, celui-ci échouera :
[code:1]
# Pas de PS cast,
#on attend un objet de type string et pas autre chose
Sendmail (get-date)[/code:1]
Tout compte fait je sens que j'ai un faible pour la version 2 de PowerShell
<br><br>Message édité par: Laurent Dardenne, à: 17/12/08 15:16
L'opérateur cast à un comportement différent des langages de POO tels que Delphi,C#,java,etc.
Si l'opération de cast échoue elle ne renvoi pas $null mais convertie l'objet en une string via un appel à la méthode ToSring().
[code:1]
function ValidateParameter([string]$Name,$Parameter,[Type] $Type, [Switch] $Strict)
{ # Renvoi $False si le contenu est à $Null.
# Si la validation demandée est stricte et que le type du paramètre est du type attendu , on renvoie $True
# Si la validation demandée est stricte et que le type du paramètre n'est pas du type attendu -> Exception
# Si la validation demandée n'est pas stricte, que le type du paramètre est du type attendu et
# que le cast réussi, on renvoi $True
# Si la validation demandée n'est pas stricte, que le type du paramètre n'est pas du type attendu et
# que le cast échoue -> Exception (note : avec le type [string] dans ce cas le cast réussi toujours)
#
#
# Exception : ArgumentTransformationMetadataException
Write-Debug \"ValidateParameter\"
Write-debug \"$Name\"
if ($Parameter -ne $null)
{Write-debug \"$($Parameter.GetType())\"}
else
{
Write-debug \"`Le paramètre $Name est à `$null.\"
return $False
}
Write-debug \"$Parameter\"
Write-debug \"$Type\"
#$host.EnterNestedPrompt()
#Le paramètre reçu est-il du type attendu ?
$isSameType=$Parameter -is $Type
#Peut-on caster la valeur reçue dans le type attendu ?
#En cas de cast impossible, l'opérateur -as appel la méthode ToString()
#Ce qui reste cohérent avec le parsing de PowerShell.
#Si le paramétre attendu est de type [string], dans ce cas une date sera transformée en string.
#Le cast du paramètre en un type [string] réussira toujours !
$isCastFail=($Parameter -as $Type) -eq $null
Write-debug \"$isNotSameType : $isNotSameType\"
Write-debug \"isCastFail : $isCastFail\"
#Si le cast demandé est strict, le type du paramètre doit être celui du type attendu
#ou
#si le cast demandé n'est pas strict que le type du paramètre n'est pas celui du type attendu et que le cast échoue.
if ( ($Strict.IsPresent -and !$isSameType) -or (!$Strict.IsPresent -and !$isSameType -and $isCastFail) )
{ #récupére le contexte d'appel de l'appelant
$Invocation = (Get-Variable MyInvocation -Scope 1).Value
throw (new-object System.Management.Automation.ArgumentTransformationMetadataException \"$($Invocation.MyCommand).$($MyInvocation.MyCommand) : Impossible de convertir la valeur du paramètre $name « $($Parameter.GetType()) » en type « $($Type.ToString()) ».\"«»)
}
return $True
} #ValidateParameter
[/code:1]
test :
[code:1]
Function SendMail( $attach)
{
if (ValidateParameter \"attach\" $attach String)
{
if ( $Attach -eq [string]::Empty) {Throw \"Le contenu du paramètre Attach n'est pas renseigné.\"}
if (! (Test-path $Attach)) {Throw \"Le fichier n'existe pas : $Attach\"}
$Attach
\"Send mail\"
}
else {Throw \"La valeur du paramètre Attach est`$null ou n'est pas du type String.\"}
}
Sendmail
Sendmail \"\"
Sendmail \"C:\notExist.txt\"
# PS cast une date en une string
Sendmail get-date
Sendmail (get-date)
Sendmail 1..5
# PS cast un tableau en une string
Sendmail @(1..5)
Sendmail (Dir c:\)
[/code:1]
L'usage du switche Strict force la validation sur le type attendu et seulement celui-ci
[code:1]
if (ValidateParameter \"attach\" $attach String -Strict)
[/code:1]
Dans ce cas, à la différence de l'appel précédent, celui-ci échouera :
[code:1]
# Pas de PS cast,
#on attend un objet de type string et pas autre chose
Sendmail (get-date)[/code:1]
Tout compte fait je sens que j'ai un faible pour la version 2 de PowerShell
Tutoriels PowerShell
Connexion ou Créer un compte pour participer à la conversation.
- Laurent Dardenne
- Auteur du sujet
- Hors Ligne
- Modérateur
-
Réduire
Plus d'informations
- Messages : 6311
- Remerciements reçus 68
il y a 17 ans 1 mois #3873
par Laurent Dardenne
Tutoriels PowerShell
Réponse de Laurent Dardenne sur le sujet Re:[Astuce]Analyse des paramètres d'un script/fnction
Une version modifiée :
[code:1]
function Test-Variable([System.Management.Automation.PSVariable] $Variable=$(Throw \"Test-Variable : le paramètre Variable, de type PSVariable, doit être renseigné.\"«»),
[Type] $Type=$(Throw \"Test-Variable : le paramètre Type doit être renseigné.\"«»),
[Switch] $Strict,
[Switch] $TestEmptyString)
{ # Léve une exception si le contenu de $Variable est à $Null ou ne répond pas aux critéres suivants :
# Si la validation demandée est stricte et que le type du paramètre est du type attendu -> FIN
# Si la validation demandée est stricte et que le type du paramètre n'est pas du type attendu -> Exception
# Si la validation demandée n'est pas stricte, que le type du paramètre est du type attendu et
# que le cast réussi -> FIN
# Si la validation demandée n'est pas stricte, que le type du paramètre n'est pas du type attendu et
# que le cast échoue -> Exception
# note : avec le type [string] dans ce cas le cast réussi toujours. Avec un number vers une Date aussi, etc.
#
# Si $TestEmptyString est indiqué et que $Type est égal à [String] on valide le contenu du paramètre de type chaîne
# S'il est vide -> Exception
# sinon ->Suite
#
# Exception : ArgumentTransformationMetadataException
#
# Test-Variable (gv NomDeVariable) String -strict -TestEmptyString
# Test-Variable (gv NomDeVariable) DateTime -TestEmptyString
Write-Debug (\"Call : {0}\" -F $MyInvocation.InvocationName)
#récupère le contexte d'appel de l'appelant
$ParentInvocation = (Get-Variable MyInvocation -Scope 1).Value
$CS=\"{0}.{1}\" -F $ParentInvocation.MyCommand,$MyInvocation.MyCommand
if ($Variable -eq $null) {Throw \"$CS : le paramètre Variable est à null.\"}
if ($Type -eq $null) {Throw \"$CS : le paramètre Type est à null.\"}
Write-debug $Variable.Name
if ($Variable.Value -ne $null)
{Write-debug \"$($Variable.Value.GetType())\"}
else
{
Write-debug \"`Le paramètre $($Variable.Name) est à `$null.\"
Throw \"$CS : La valeur du paramètre $($Variable.Name) est `$null.\"
}
Write-debug \"$Variable.Value\"
Write-debug \"$Type\"
if ($TestEmptyString -and ($Type -eq [String]) )
{if ($Variable.Value -eq [string]::Empty)
{Throw \"$CS : Le contenu du paramètre $($Variable.Name) n'est pas renseigné.\"}
}
#$host.EnterNestedPrompt()
#Le paramètre reçu est-il du type attendu ?
$isSameType=$Variable.Value -is $Type
#Peut-on caster la valeur reçue dans le type attendu ?
#En cas de cast impossible, l'opérateur -as appel la méthode ToString()
#Ce qui reste cohérent avec le parsing de PowerShell.
#Si le paramètre attendu est de type [string], dans ce cas une date sera transformée en string.
#Le cast du paramètre en un type [string] réussira toujours !
$isCastFail=($Variable.Value -as $Type) -eq $null
Write-debug \"$isNotSameType : $isNotSameType\"
Write-debug \"isCastFail : $isCastFail\"
#Si le cast demandé est strict, le type du paramètre doit être celui du type attendu
#ou
#si le cast demandé n'est pas strict que le type du paramètre n'est pas celui du type attendu et que le cast échoue.
if ( ($Strict.IsPresent -and !$isSameType) -or (!$Strict.IsPresent -and !$isSameType -and $isCastFail) )
{
$StrFrm=\"$CS : Impossible de convertir la valeur du paramètre {0} « {1} » en type « {2} ».\"
$Ex= new-object System.Management.Automation.ArgumentTransformationMetadataException (
$StrFrm -F $Variable.Name,$Variable.Value.GetType(),$Type.ToString() )
throw $Ex
}
} #Test-Variable
[/code:1]
Le code d'appel est simplifié, mais on doit utiliser Get-Variable. Ce cmdlet renvoi une instance du type PSVariable, contenant le nom et le contenu de la variable indiquée.
[code:1]
Function SendMail( $attach)
{
Test-Variable (gv attach) String -TestEmptyString
if (! (Test-path $Attach)) {Throw \"Le fichier n'existe pas : $Attach\"}
$Attach
\"Send mail\"
}[/code:1]<br><br>Message édité par: Laurent Dardenne, à: 1/02/09 21:27
[code:1]
function Test-Variable([System.Management.Automation.PSVariable] $Variable=$(Throw \"Test-Variable : le paramètre Variable, de type PSVariable, doit être renseigné.\"«»),
[Type] $Type=$(Throw \"Test-Variable : le paramètre Type doit être renseigné.\"«»),
[Switch] $Strict,
[Switch] $TestEmptyString)
{ # Léve une exception si le contenu de $Variable est à $Null ou ne répond pas aux critéres suivants :
# Si la validation demandée est stricte et que le type du paramètre est du type attendu -> FIN
# Si la validation demandée est stricte et que le type du paramètre n'est pas du type attendu -> Exception
# Si la validation demandée n'est pas stricte, que le type du paramètre est du type attendu et
# que le cast réussi -> FIN
# Si la validation demandée n'est pas stricte, que le type du paramètre n'est pas du type attendu et
# que le cast échoue -> Exception
# note : avec le type [string] dans ce cas le cast réussi toujours. Avec un number vers une Date aussi, etc.
#
# Si $TestEmptyString est indiqué et que $Type est égal à [String] on valide le contenu du paramètre de type chaîne
# S'il est vide -> Exception
# sinon ->Suite
#
# Exception : ArgumentTransformationMetadataException
#
# Test-Variable (gv NomDeVariable) String -strict -TestEmptyString
# Test-Variable (gv NomDeVariable) DateTime -TestEmptyString
Write-Debug (\"Call : {0}\" -F $MyInvocation.InvocationName)
#récupère le contexte d'appel de l'appelant
$ParentInvocation = (Get-Variable MyInvocation -Scope 1).Value
$CS=\"{0}.{1}\" -F $ParentInvocation.MyCommand,$MyInvocation.MyCommand
if ($Variable -eq $null) {Throw \"$CS : le paramètre Variable est à null.\"}
if ($Type -eq $null) {Throw \"$CS : le paramètre Type est à null.\"}
Write-debug $Variable.Name
if ($Variable.Value -ne $null)
{Write-debug \"$($Variable.Value.GetType())\"}
else
{
Write-debug \"`Le paramètre $($Variable.Name) est à `$null.\"
Throw \"$CS : La valeur du paramètre $($Variable.Name) est `$null.\"
}
Write-debug \"$Variable.Value\"
Write-debug \"$Type\"
if ($TestEmptyString -and ($Type -eq [String]) )
{if ($Variable.Value -eq [string]::Empty)
{Throw \"$CS : Le contenu du paramètre $($Variable.Name) n'est pas renseigné.\"}
}
#$host.EnterNestedPrompt()
#Le paramètre reçu est-il du type attendu ?
$isSameType=$Variable.Value -is $Type
#Peut-on caster la valeur reçue dans le type attendu ?
#En cas de cast impossible, l'opérateur -as appel la méthode ToString()
#Ce qui reste cohérent avec le parsing de PowerShell.
#Si le paramètre attendu est de type [string], dans ce cas une date sera transformée en string.
#Le cast du paramètre en un type [string] réussira toujours !
$isCastFail=($Variable.Value -as $Type) -eq $null
Write-debug \"$isNotSameType : $isNotSameType\"
Write-debug \"isCastFail : $isCastFail\"
#Si le cast demandé est strict, le type du paramètre doit être celui du type attendu
#ou
#si le cast demandé n'est pas strict que le type du paramètre n'est pas celui du type attendu et que le cast échoue.
if ( ($Strict.IsPresent -and !$isSameType) -or (!$Strict.IsPresent -and !$isSameType -and $isCastFail) )
{
$StrFrm=\"$CS : Impossible de convertir la valeur du paramètre {0} « {1} » en type « {2} ».\"
$Ex= new-object System.Management.Automation.ArgumentTransformationMetadataException (
$StrFrm -F $Variable.Name,$Variable.Value.GetType(),$Type.ToString() )
throw $Ex
}
} #Test-Variable
[/code:1]
Le code d'appel est simplifié, mais on doit utiliser Get-Variable. Ce cmdlet renvoi une instance du type PSVariable, contenant le nom et le contenu de la variable indiquée.
[code:1]
Function SendMail( $attach)
{
Test-Variable (gv attach) String -TestEmptyString
if (! (Test-path $Attach)) {Throw \"Le fichier n'existe pas : $Attach\"}
$Attach
\"Send mail\"
}[/code:1]<br><br>Message édité par: Laurent Dardenne, à: 1/02/09 21:27
Tutoriels PowerShell
Connexion ou Créer un compte pour participer à la conversation.
- Laurent Dardenne
- Auteur du sujet
- Hors Ligne
- Modérateur
-
Réduire
Plus d'informations
- Messages : 6311
- Remerciements reçus 68
il y a 16 ans 5 mois #5475
par Laurent Dardenne
Tutoriels PowerShell
Réponse de Laurent Dardenne sur le sujet Re:[Astuce]Analyse des paramètres d'un script/fnction
On prend les mêmes et on recommence, cette fois-ci avec la v2 RTM.
Déterminer si un paramètre prend une valeur par défaut :
[code:1]Function Test-UnBoundArguments
{
param([String] $Name,[int]$Nombre=3,[switch] $Stop)
#$localInvocation=$MyInvocation
#$localPSB=$PSBoundparameters
$OutValue = $null
if ($MyInvocation.BoundParameters.TryGetValue('Nombre', [ref]$OutValue))
{
if ($OutValue -eq $null)
{Write-Warning \"Le paramètre Nombre prend la valeur `$null.\"}
else
{Write-Warning \"Le paramètre Nombre est précisé et prend la valeur $OutValue.\"}
}
else
{
Write-Warning \"Le paramètre Nombre n'est pas précisé mais prend la valeur par défaut.\"
}
\"Nombre =$Nombre\"
}
Test-UnBoundArguments
Test-UnBoundArguments -name \"Test\"
Test-UnBoundArguments \"Test\"
Test-UnBoundArguments \"Test\" 5
Test-UnBoundArguments \"Test\" $null
Test-UnBoundArguments \"Test\" -nombre $null
Test-UnBoundArguments \"Test\" -nombre[/code:1]
Déterminer les paramètres inconnus.
[code:1]
Function Test-UnBoundArguments
{
param([String] $Name,[int]$Nombre=3,[switch] $Stop)
#$localInvocation=$MyInvocation
#$localPSB=$PSBoundparameters
Write-host \" ---- BoundParameters\"
$MyInvocation.BoundParameters
#Write-host \" ---- PSBoundParameters\"
# $PSBoundparameters pointe sur $MyInvocation.BoundParameters
# Faire : $MyInvocation.BoundParameters.Clear()...
#$PSBoundparameters
Write-host \" ---- \"
Write-host \" ---- UnboundArguments\"
$MyInvocation.UnboundArguments
# List<Object>
#$MyInvocation.UnboundArguments.Psbase
#$host.EnterNestedPrompt()
#Les éléments de la liste sont accesssibles par $MyInvocation.UnboundArguments.Item($I)
$Count=
if ($MyInvocation.UnBoundArguments.Count -gt 0)
{
Throw \"Le ou les paramètres suivants sont inconnus : $($MyInvocation.UnBoundArguments).\"
}
\"Nombre =$Nombre\"
}
Test-UnBoundArguments -ParamInconnu 10
Test-UnBoundArguments -nime \"Test\"
Test-UnBoundArguments -Stop
Test-UnBoundArguments -SwitchInconnu -hInconnu -ParamInconnu 10
Test-UnBoundArguments -SwitchInconnu -hInconnu Test-UnBoundArguments -ParamInconnu 10
Test-UnBoundArguments -SwitchInconnu
Test-UnBoundArguments -SwitchInconnu:$False
$truc=$true
Test-UnBoundArguments -SwitchInconnu:$truc
$truc=10
Test-UnBoundArguments -SwitchInconnu:$truc[/code:1]
Notez que la variable $PSBoundparameters pointe sur $MyInvocation.BoundParameters. Pour le vérifier faire : [code:1]
$PSBoundparameters
$MyInvocation.BoundParameters.Clear()
$PSBoundparameters
[/code:1]
Déterminer si un paramètre prend une valeur par défaut :
[code:1]Function Test-UnBoundArguments
{
param([String] $Name,[int]$Nombre=3,[switch] $Stop)
#$localInvocation=$MyInvocation
#$localPSB=$PSBoundparameters
$OutValue = $null
if ($MyInvocation.BoundParameters.TryGetValue('Nombre', [ref]$OutValue))
{
if ($OutValue -eq $null)
{Write-Warning \"Le paramètre Nombre prend la valeur `$null.\"}
else
{Write-Warning \"Le paramètre Nombre est précisé et prend la valeur $OutValue.\"}
}
else
{
Write-Warning \"Le paramètre Nombre n'est pas précisé mais prend la valeur par défaut.\"
}
\"Nombre =$Nombre\"
}
Test-UnBoundArguments
Test-UnBoundArguments -name \"Test\"
Test-UnBoundArguments \"Test\"
Test-UnBoundArguments \"Test\" 5
Test-UnBoundArguments \"Test\" $null
Test-UnBoundArguments \"Test\" -nombre $null
Test-UnBoundArguments \"Test\" -nombre[/code:1]
Déterminer les paramètres inconnus.
[code:1]
Function Test-UnBoundArguments
{
param([String] $Name,[int]$Nombre=3,[switch] $Stop)
#$localInvocation=$MyInvocation
#$localPSB=$PSBoundparameters
Write-host \" ---- BoundParameters\"
$MyInvocation.BoundParameters
#Write-host \" ---- PSBoundParameters\"
# $PSBoundparameters pointe sur $MyInvocation.BoundParameters
# Faire : $MyInvocation.BoundParameters.Clear()...
#$PSBoundparameters
Write-host \" ---- \"
Write-host \" ---- UnboundArguments\"
$MyInvocation.UnboundArguments
# List<Object>
#$MyInvocation.UnboundArguments.Psbase
#$host.EnterNestedPrompt()
#Les éléments de la liste sont accesssibles par $MyInvocation.UnboundArguments.Item($I)
$Count=
if ($MyInvocation.UnBoundArguments.Count -gt 0)
{
Throw \"Le ou les paramètres suivants sont inconnus : $($MyInvocation.UnBoundArguments).\"
}
\"Nombre =$Nombre\"
}
Test-UnBoundArguments -ParamInconnu 10
Test-UnBoundArguments -nime \"Test\"
Test-UnBoundArguments -Stop
Test-UnBoundArguments -SwitchInconnu -hInconnu -ParamInconnu 10
Test-UnBoundArguments -SwitchInconnu -hInconnu Test-UnBoundArguments -ParamInconnu 10
Test-UnBoundArguments -SwitchInconnu
Test-UnBoundArguments -SwitchInconnu:$False
$truc=$true
Test-UnBoundArguments -SwitchInconnu:$truc
$truc=10
Test-UnBoundArguments -SwitchInconnu:$truc[/code:1]
Notez que la variable $PSBoundparameters pointe sur $MyInvocation.BoundParameters. Pour le vérifier faire : [code:1]
$PSBoundparameters
$MyInvocation.BoundParameters.Clear()
$PSBoundparameters
[/code:1]
Tutoriels PowerShell
Connexion ou Créer un compte pour participer à la conversation.
Temps de génération de la page : 0.088 secondes
- Vous êtes ici :
-
Accueil
-
forum
-
PowerShell
-
Contributions à la communauté
- [Astuce]Analyse des paramètres d'un script/fnction