Getty Images
Administration Windows : bannissez les erreurs des scripts PowerShell
L’utilisation d’expressions régulières pour valider les informations saisies et générer un message d’erreur personnalisé sur un nouveau script utilisateur peut éviter des tickets d’assistance inutiles.
Il est utile de savoir détecter les problèmes et d’envoyer un message d’erreur approprié lorsque vous écrivez des scripts en PowerShell. Il se peut que des personnes non techniques utilisent vos scripts et aient besoin de savoir ce qu’elles ont fait de mal si leurs données produisent une erreur.
L’un des moyens de tester une fonction consiste à valider les données saisies par l’utilisateur. L’attribut PowerShell ValidatePattern génère un message d’erreur si la saisie de l’utilisateur ne correspond pas à votre expression régulière. Cette méthode de validation des entrées permet de gagner du temps et de réduire les problèmes, mais elle nécessite un codage supplémentaire pour produire un message d’erreur compréhensible pour l’utilisateur final.
Qu’est-ce que ValidatePattern ?
Les fonctions avancées de PowerShell vous permettent de spécifier plusieurs types de validations de paramètres.
Le premier est le type de paramètre lui-même. Par exemple, si nous voulons une chaîne de caractères pour un paramètre spécifique, nous utilisons le type [string] et la fonction n’autorisera que les chaînes de caractères pour ce paramètre.
La deuxième forme de validation des paramètres s’effectue par le biais de différents attributs de validation qui confirment plusieurs aspects de la valeur transmise. L’un des attributs de validation est appelé ValidatePattern.
ValidatePattern compare le paramètre transmis à une expression régulière et rejette la valeur si elle ne correspond pas. ValidatePattern fonctionne sur d’autres types de paramètres que les chaînes de caractères. Pour ce faire, il convertit d’abord la valeur en chaîne de caractères, puis effectue la comparaison avec l’expression régulière. Il se peut que vous obteniez des résultats inattendus avec des paramètres autres que des chaînes de caractères ; veillez donc à effectuer des tests approfondis avant d’utiliser quoi que ce soit en production.
Comment utiliser ValidatePattern ?
Comme ValidatePattern vérifie les paramètres des fonctions, il est placé dans un bloc param, précédant le paramètre que vous souhaitez valider par un motif.
Par exemple, si nous devions utiliser un exemple d’expression régulière de numéro de téléphone (ici au format américain), nous pourrions avoir un paramètre comme le suivant :
param (
[ValidatePattern('\(?(?<areaCode>\d{3})\)?(-| )?(?<first>\d{3})(-| )?(?<second>\d{4})')]
[string]$PhoneNumber
)
La fonction suivante convertit tout numéro de téléphone transmis au format correct :
Function Format-PhoneNumber {
[OutputType([string])]
param (
[ValidatePattern('\(?(?<areaCode>\d{3})\)?(-| )?(?<first>\d{3})(-| )?(?<second>\d{4})')]
[string]$PhoneNumber
)
$regex = '\(?(?<areaCode>\d{3})\)?(-| )?(?<first>\d{3})(-| )?(?<second>\d{4})'
$phoneNumber -match $regex | Out-Null
Write-Output "($($Matches.areaCode))-$($Matches.first)-$($Matches.second)"
}
Vous pouvez tester la fonction en essayant de transmettre un numéro de téléphone non valide :
Format-PhoneNumber -PhoneNumber 123
Le message d’erreur n’est utile que si vous savez lire les expressions régulières, ce qui peut poser un problème en fonction de la personne qui reçoit le message. Veillez à rédiger un message d’aide clair à l’aide de l’attribut HelpMessage :
param (
[Parameter(
HelpMessage = 'A phone number with 10 digits is expected.'
)]
[ValidatePattern('\(?(?<areaCode>\d{3})\)?(-| )?(?<first>\d{3})(-| )?(?<second>\d{4})')]
[string]$PhoneNumber
)
L’utilisateur peut maintenant essayer la commande Get-Help pour obtenir de l’aide :
Get-Help Format-PhoneNumber -Parameter PhoneNumber
Si nous transmettons la bonne valeur, la fonction formatera le numéro de téléphone :
Format-PhoneNumber -PhoneNumber 1234567890
Comment vérifier la saisie d’une adresse électronique ?
Dans un autre scénario de codage, imaginez que vous ayez écrit une fonction sophistiquée qui exécute plusieurs tâches dans votre infrastructure, mais qu’elle échoue à la fin parce que vous avez saisi une adresse électronique non valide pour le message de notification.
Les adresses électroniques peuvent être difficiles à valider, selon le degré de précision souhaité. Le site emailregex.com utilise le format suivant pour vérifier les adresses électroniques :
Function Validate-EmailAddress {
[cmdletbinding()]
param (
[ValidatePattern(@'
^(?(")(".+?(?<!\\)"@)|(([0-9a-z]((\.(?!\.))|[-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)(?<=[0-9a-z])@))(?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|(([0-9a-z][-\w]*[0-9a-z]*\.)+[a-z0-9][\-a-z0-9]{0,22}[a-z0-9]))$
'@
)]
[string]$EmailAddress
)
}
Bien qu’elle fonctionne, cette expression régulière est difficile à comprendre. Vous pourriez vouloir une expression régulière plus simple qui inclurait le nom de dozmaine de votre entreprise. Vous pouvez utiliser la classe System.Net.Mail.MailAddress à la place :
Function Validate-EmailAddress {
[cmdletbinding()]
param (
[System.Net.Mail.MailAddress]$EmailAddress
)
}
Dans cet exemple, c’est .NET qui se charge de la validation. C’est un exemple d’utilisation d’autres outils pour faire le travail plutôt que d’écrire une expression régulière compliquée que vous ne comprendrez pas lorsque vous la réviserez à l’avenir.
Comment valider l’entrée d’un fichier ou d’un dossier ?
Il se peut que vous utilisiez déjà un paramètre commun pour accepter les chemins d’accès aux fichiers ou aux dossiers. L’examen du chemin d’accès à un fichier ou à un dossier est une bonne occasion d’utiliser une expression régulière. Cependant, il est préférable d’utiliser les types .NET pour ces deux éléments.
Pour les fichiers, utilisez System.IO.FileInfo et pour les répertoires, System.IO.DirectoryInfo :
Function Validate-Path {
[cmdletbinding()]
param (
[System.IO.FileInfo]$File,
[System.IO.DirectoryInfo]$Folder
)
}
Si vous devez accepter un fichier avec une extension spécifique, c’est là que les expressions régulières facilitent le processus de validation. Dans l’exemple suivant, le script ingère un fichier CSV et l’un des paramètres est le chemin d’accès au fichier CSV :
Function Ingest-CSV {
[cmdletbinding()]
param (
[System.IO.FileInfo]$CsvPath
)
}
Nous savons que le paramètre $CsvPath doit se terminer par .csv. Vous pouvez donc utiliser l’ancre $ dans une expression régulière, c’est-à-dire à la fin d’une chaîne de caractères :
'\.csv$'
Dans ce cas, le point dans « \. » est un caractère d’échappement dans l’expression régulière.
Lorsque le type d’objet System.IO.FileInfo est converti en chaîne de caractères, nous obtenons le chemin d’accès au fichier avec la commande :
([System.IO.FileInfo]'C:\blah.txt').ToString()
Dans cette optique, nous pouvons utiliser la même fonction Ingest-CSV, mais en ajoutant simplement la fonction ValidatePattern :
Function Ingest-CSV {
[cmdletbinding()]
param (
[ValidatePattern('\.csv$')]
[System.IO.FileInfo]$CsvPath
)
$CsvPath
}
Si nous transmettons un chemin non-CSV, PowerShell génère un message d’erreur.
Dans un autre exemple, vous pouvez vérifier qu’un utilisateur spécifie un fichier dans un partage de fichiers. Commencez par l’ancre « ^ » qui indique le début de la correspondance, et poursuivez avec le chemin d’accès au partage, échappé de manière appropriée. Par exemple, si le partage est \dc1\it-share\folder, votre fonction pourrait ressembler à ce qui suit :
Function Validate-SharePath {
[cmdletbinding()]
param (
[ValidatePattern('^\\\\dc1\\it-share\\folder')]
[System.IO.FileInfo]$SharePath
)
$SharePath
}
Nous pouvons le tester en passant un chemin d’accès valide :
Validate-SharePath -SharePath \\dc1\it-share\folder\blah.txt
Comment tirer parti de ValidatePattern ?
L’attribut ValidatePattern de PowerShell libère un grand potentiel avec les expressions régulières, en particulier lorsque vous écrivez des fonctions dans des scripts qui seront utilisés par d’autres personnes. Vos scripts peuvent réduire le nombre d’entrées inattendues et diminuer le travail de réécriture du code pour tenir compte de tous les scénarios d’entrée possibles.
La validation des paramètres ajoute une autre couche de protection pour qu’une fonction s’exécute comme prévu, mais n’allez pas trop loin avec des expressions régulières trop complexes. Vous pouvez couvrir la validation des paramètres avec le bon type d’objet.
Vous pouvez utiliser ValidatePattern avec d’autres types que les chaînes de caractères, comme le montrent les exemples du type de fichier et du partage de fichiers, alors n’hésitez pas à faire preuve de créativité.