Question [Astuce] Implémenter -Path et -LiteralPath
- Laurent Dardenne
- Auteur du sujet
- Hors Ligne
- Modérateur
-
Réduire
Plus d'informations
- Messages : 6298
- Remerciements reçus 68
il y a 9 ans 9 mois #17108
par Laurent Dardenne
Tutoriels PowerShell
[Astuce] Implémenter -Path et -LiteralPath a été créé par Laurent Dardenne
Voici une approche pour implémenter la gestion des paramètres Path et LiteralPath sur une fonction avancée :
[code:1]
Function Test {
[CmdletBinding(DefaultParameterSetName=\"Path\"«»)]
param(
[parameter(Mandatory=$True,ValueFromPipeline=$True, ParameterSetName=\"Path\"«»)]
[string]$Path,
[parameter(Mandatory=$True,ValueFromPipeline=$True, ParameterSetName=\"LiteralPath\"«»)]
[string]$LiteralPath,
$ParamNull='Valeur par défaut'
)
begin { Write-Warning \"Begin ParamNull=$ParamNull\"}
process {
$isLiteral = $PsCmdlet.ParameterSetName -eq 'LiteralPath'
Write-Warning \"Literal Path ? $isLiteral\"
if ($isLiteral)
{ $ExecutionContext.InvokeProvider.Item.Exists(([Management.Automation.WildcardPattern]::Escape($LiteralPath)),$false,$false) }
else
{ $ExecutionContext.InvokeProvider.Item.Exists($Path,$false,$false) }
Write-Warning \"`tProcess ParamNull=$ParamNull\"
}
}
new-item -ItemType directory -Path 'C:\Temp\Test[' -ea SilentlyContinue
[/code:1]
L'implémentation de LiteralPath permet à la fonction d'utiliser des noms de fichiers contenant des caractères génériques utilisés par PowerShell.
Un exemple du problème potentiel:
[code:1]
Test-path -LiteralPath 'C:\Temp\Test['
#True
Test-path 'C:\Temp\Test['
#Test-path : Impossible de récupérer les paramètres dynamiques pour l'applet de commande.
#Les caractères génériques spécifiés ne sont pas valides : Test[
[/code:1]
Le code en lui même est compréhensible et son usage aisé :
[code:1]
$ParamNull=\"Scope de l'appelant\"
#---Liaison par la ligne de commande
Test -LiteralPath 'C:\Temp\Test['
#Begin ParamNull=Valeur par défaut
Test -Path C:\Temp
#Begin ParamNull=Valeur par défaut
[/code:1]
Le seul problème, mais pas des moindres, et que ce type de construction sous Powershell V2 est buguée :
[code:1]
#---Liaison par le pipeline
'C:\Temp\Test['|Test -LiteralPath {$_}
#Begin ParamNull=Valeur par défaut
'C:\Temp'|Test
#Begin ParamNull=Scope de l'appelant
[/code:1]
L'usage du pipeline met en évidence ce bug .
Pour le contourner on doit redéclarer la gestion de la valeur par défaut dans le bloc begin :
[code:1]
begin {
if (-not $PSBoundParameters.ContainsKey('ParamNull'))
{ $ParamNull='Valeur par défaut'} #bug v2 : parameters-initialization
Write-Warning \"Begin ParamNull=$ParamNull\"
}
[/code:1]
Ce bug est corrigé sous PS v3, mais pour ne faire de jaloux, celle-ci propose des régressions
<br><br>Message édité par: Laurent Dardenne, à: 4/03/14 14:59
[code:1]
Function Test {
[CmdletBinding(DefaultParameterSetName=\"Path\"«»)]
param(
[parameter(Mandatory=$True,ValueFromPipeline=$True, ParameterSetName=\"Path\"«»)]
[string]$Path,
[parameter(Mandatory=$True,ValueFromPipeline=$True, ParameterSetName=\"LiteralPath\"«»)]
[string]$LiteralPath,
$ParamNull='Valeur par défaut'
)
begin { Write-Warning \"Begin ParamNull=$ParamNull\"}
process {
$isLiteral = $PsCmdlet.ParameterSetName -eq 'LiteralPath'
Write-Warning \"Literal Path ? $isLiteral\"
if ($isLiteral)
{ $ExecutionContext.InvokeProvider.Item.Exists(([Management.Automation.WildcardPattern]::Escape($LiteralPath)),$false,$false) }
else
{ $ExecutionContext.InvokeProvider.Item.Exists($Path,$false,$false) }
Write-Warning \"`tProcess ParamNull=$ParamNull\"
}
}
new-item -ItemType directory -Path 'C:\Temp\Test[' -ea SilentlyContinue
[/code:1]
L'implémentation de LiteralPath permet à la fonction d'utiliser des noms de fichiers contenant des caractères génériques utilisés par PowerShell.
Un exemple du problème potentiel:
[code:1]
Test-path -LiteralPath 'C:\Temp\Test['
#True
Test-path 'C:\Temp\Test['
#Test-path : Impossible de récupérer les paramètres dynamiques pour l'applet de commande.
#Les caractères génériques spécifiés ne sont pas valides : Test[
[/code:1]
Le code en lui même est compréhensible et son usage aisé :
[code:1]
$ParamNull=\"Scope de l'appelant\"
#---Liaison par la ligne de commande
Test -LiteralPath 'C:\Temp\Test['
#Begin ParamNull=Valeur par défaut
Test -Path C:\Temp
#Begin ParamNull=Valeur par défaut
[/code:1]
Le seul problème, mais pas des moindres, et que ce type de construction sous Powershell V2 est buguée :
[code:1]
#---Liaison par le pipeline
'C:\Temp\Test['|Test -LiteralPath {$_}
#Begin ParamNull=Valeur par défaut
'C:\Temp'|Test
#Begin ParamNull=Scope de l'appelant
[/code:1]
L'usage du pipeline met en évidence ce bug .
Pour le contourner on doit redéclarer la gestion de la valeur par défaut dans le bloc begin :
[code:1]
begin {
if (-not $PSBoundParameters.ContainsKey('ParamNull'))
{ $ParamNull='Valeur par défaut'} #bug v2 : parameters-initialization
Write-Warning \"Begin ParamNull=$ParamNull\"
}
[/code:1]
Ce bug est corrigé sous PS v3, mais pour ne faire de jaloux, celle-ci propose des régressions

Tutoriels PowerShell
Connexion ou Créer un compte pour participer à la conversation.
Temps de génération de la page : 0.066 secondes
- Vous êtes ici :
-
Accueil
-
forum
-
PowerShell
-
Contributions à la communauté
- [Astuce] Implémenter -Path et -LiteralPath