PARTIE 1 | PARTIE 2 | PARTIE 3 | PARTIE 4 | ||
---|---|---|---|---|---|
Sommaire général | Exécuter Powershell | Les cmdlets | Instructions dans des scripts | Aide, gestion d’erreurs et manipulation de fichiers | Références |
Cet article liste quelques fonctionnalités un peu plus avancées de Powershell pour traiter quelques cas d’implémentation courants.
Gestion des erreurs
break
continue
Spécialiser l’erreur attrapée par “trap”
Manipulation de fichiers
Lister des fichiers dans un répertoire
Manipulations basiques sur des fichiers
Générer un fichier
Exporter dans un fichier CSV
Fichier XML
Messages d’aide
Pour obtenir de l’aide sur une fonction, on peut utiliser l’instruction:
Get-Help <nom de la fonction>
Pour créer des messages d’aide lorsqu’on définit une fonction, on peut utiliser des commentaires déclarés avec une syntaxe particulière. Ces commentaires seront affichés suivant les paramètres utilisés à l’exécution de la fonction Get-Help
.
Par exemple:
On peut indiquer dans le corps de la fonction les commentaires:
# .SYNOPSIS
pour indiquer un texte décrivant brièvement la fonction# .DESCRIPTION
permet de décrire la fonction# .PARAMETER
donnera des indications sur les paramètres de la fonction# .EXAMPLE
indiquera un exemple
Il est possible d’indiquer d’autres informations:
# .INPUTS
# .OUTPUTS
# .NOTES
# .LINK
Dans le corps de la fonction, ces commentaires doivent être indiqués de cette façon:
function NomFonction($arg1, $arg2)
{
<#
.SYNOPSIS
Texte correspondant au synopsis
.DESCRIPTION
Texte correspondant à la description
.PARAMETER arg1
Aide concernant l'argument 1
.PARAMETER arg2
Aide concernant l'argument 1
.EXAMPLE
Texte correspondant à l'exemple
.NOTES
Notes diverses
.LINK
Liens éventuels
.INPUTS
Indication pour les données en entrée
.OUTPUTS
Indication pour les données en sortie
#>
Write-Host Argument 1: $arg1
Write-Host Argument 2: $arg2
}
Pour obtenir la documentation complète d’une fonction, il faut utiliser l’option -full
:
Get-Help <nom de la fonction> -full
Dans le cas de l’exemple, pour afficher une documentation partielle, on peut exécuter:
PS C:\> Get-Help NomFonction
NAME
NomFonction
SYNOPSIS
Texte correspondant au synopsis
SYNTAX
NomFonction [[-arg1] <Object>] [[-arg2] <Object>] [<CommonParameters>]
DESCRIPTION
Texte correspondant à la description
RELATED LINKS
Liens éventuels
REMARKS
To see the examples, type: "get-help NomFonction -examples".
For more information, type: "get-help NomFonction -detailed".
For technical information, type: "get-help NomFonction -full".
For online help, type: "get-help NomFonction -online"
Dans le cas de la documentation complète, le résultat est:
PS C:\> Get-Help NomFonction -full
NAME
NomFonction
SYNOPSIS
Texte correspondant au synopsis
SYNTAX
NomFonction [[-arg1] <Object>] [[-arg2] <Object>] [<CommonParameters>]
DESCRIPTION
Texte correspondant à la description
PARAMETERS
-arg1 <Object>
Aide concernant l'argument 1
Required? false
Position? 1
Default value
Accept pipeline input? false
Accept wildcard characters? false
-arg2 <Object>
Aide concernant l'argument 1
Required? false
Position? 2
Default value
Accept pipeline input? false
Accept wildcard characters? false
<CommonParameters>
This cmdlet supports the common parameters: Verbose, Debug,
ErrorAction, ErrorVariable, WarningAction, WarningVariable,
OutBuffer, PipelineVariable, and OutVariable. For more information, see
about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216).
INPUTS
Indication pour les données en entrée
OUTPUTS
Indication pour les données en sortie
NOTES
Notes diverses
-------------------------- EXAMPLE 1 --------------------------
PS C:\>Texte correspondant à l'exemple
RELATED LINKS
Liens éventuels
Gestion des erreurs
Pour gérer n’importe quel type d’erreurs qui pourrait intervenir dans la fonction, il faut utiliser le mot clé trap
. Par exemple:
function NomFonction()
{
Write-Host Exécuté avant "trap"
trap
{
Write-Host Une erreur est survenue
}
Write-Host Exécuté après "trap"
}
Dans ce cas, il n’y a pas d’erreurs donc le contenu de la partie trap
ne sera pas exécutée:
PS C:\> NomFonction
Exécuté avant trap
Exécuté après trap
Dans le cas d’une erreur, le contenu de la partie trap
est exécutée:
function NomFonction()
{
Write-Host Exécuté avant "trap"
trap
{
Write-Host Une erreur est survenue
}
# ATTENTION: l'exécution continue après le "trap"
# L'erreur est une division par zéro
$arg= 3/0
Write-Host Exécuté après "trap"
}
Le résultat de l’exécution est:
PS C:\> NomFonction
Exécuté avant trap
Une erreur est survenue
Tentative de division par zéro.
At line:12 char:4
+ $arg= 3/0
+ ~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
Exécuté après trap
break
Comme indiqué en commentaire de l’exemple précédent, l’exécution se poursuit après l’erreur. Pour stopper l’exécution à la ligne où l’erreur se produit, il faut ajouter break
dans le bloc trap
:
function NomFonction()
{
Write-Host Exécuté avant "trap"
trap
{
Write-Host Une erreur est survenue
break
}
# ATTENTION: l'exécution continue après le "trap"
$arg= 3/0
Write-Host Exécuté après "trap"
}
En exécutant, on obtient:
PS C:\> NomFonction
Exécuté avant trap
Une erreur est survenue
Tentative de division par zéro.
At line:12 char:4
+ $arg= 3/0
+ ~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : RuntimeException
continue
A l’opposé de l’exemple précédent, si on veut que l’exécution se poursuive après la ligne où l’erreur s’est produite, il faut utiliser le mot clé continue
. Avec continue
, il n’y aura pas de message d’erreurs:
function NomFonction()
{
Write-Host Exécuté avant "trap"
trap
{
Write-Host Une erreur est survenue
continue
}
# ATTENTION: l'exécution continue après le "trap"
$arg= 3/0
Write-Host Exécuté après "trap"
}
En exécutant la fonction, on obtient:
PS C:\> NomFonction
Exécuté avant trap
Une erreur est survenue
Exécuté après trap
Pour afficher l’erreur avec un texte choisi, on peut utiliser $_
:
function NomFonction()
{
Write-Host Exécuté avant "trap"
trap
{
Write-Host L`'erreur survenue est:
Write-Host $_
continue
}
# ATTENTION: l'exécution continue après le "trap"
$arg= 3/0
Write-Host Exécuté après "trap"
}
Le résultat de l’exécution dans ce cas est:
PS C:\> NomFonction
Exécuté avant trap
L'erreur survenue est:
Tentative de division par zéro.
Exécuté après trap
Spécialiser l’erreur attrapée par “trap”
Pour spécialiser l’erreur attrapée par un bloc trap
, il faut préciser le type d’exception comme le bloc try...catch
en C#:
function NomFonction()
{
Write-Host Exécuté avant "trap"
trap [System.DivideByZeroException]
{
Write-Host L`'erreur est:
Write-Host $_
continue
}
$arg= 3/0
Write-Host Exécuté après "trap"
}
Le résultat de l’exécution est similaire aux exemples précédents:
PS C:\> NomFonction
Exécuté avant trap
L'erreur est:
Tentative de division par zéro.
Exécuté après trap
En faisant cohabiter avec une autre bloc trap
plus général:
function NomFonction()
{
Write-Host Exécuté avant "trap"
trap [System.DivideByZeroException]
{
Write-Host L`'erreur est:
Write-Host $_
continue
}
trap
{
Write-Host Autre erreur est:
Write-Host $_
continue
}
$unknownParameter = "chaine"
$unknownParameter = 4 + $unknownParameter
Write-Host Exécuté après "trap"
}
Pour la fonction précédente, l’erreur n’est pas une division par zéro donc c’est le 2e bloc trap
qui sera exécuté:
PS C:\> NomFonction
Exécuté avant trap
Autre erreur est:
Cannot convert value "chaine" to type "System.Int32". Error: "Le format de la chaîne d'entrée est incorrect."
Exécuté après trap
Manipulation de fichiers
Pour lire le contenu d’un fichier:
Get-Content "<chemin du fichier>"
Assigner le contenu d’un fichier à une variable:
$val=Get-Content "<chemin du fichier>"
Dans le cas d’un fichier qui contient les lignes suivantes:
First line
Second line
Third line
Si on écrit la ligne suivante, le résultat est:
PS C:\> Write-Host $val
First line Second line Third line
Le résultat est un tableau contenant toutes les lignes. Chaque ligne est accessible en écrivant:
$val[0]
Dans le cas de l’exemple précédent:
Write-Host $val[0]
First line
Pour combiner les éléments du tableau dans une chaîne de caractères unique:
$separateur = [System.Environment]::NewLine
$result = [String]::Join($separateur, $val)
$result
est donc une chaîne de caractères contenant tous les éléments du tableau.
Si on affiche son contenu, on obtient:
Write-Host $result
First line
Second line
Third line
Lister des fichiers dans un répertoire
Pour afficher des informations sur liste de fichiers dans un répertoire, on utilise Get-ChildItem
. Dans le cas d’un seul fichier, on utilise Get-Item
. On peut sélectionner les informations à afficher avec les paramètres suivants:
-Name
: pour afficher le nom du fichier-Recurse
: pour parcourir un répertoire récursivement-Path
: pour afficher le chemin du fichier.
Par exemple pour afficher le chemin des fichiers se trouvant dans le répertoire courant (Get-Location
renvoie le chemin du répertoire courant):
Get-ChildItem -Path (Get-Location).Path
Manipulations basiques sur des fichiers
Quelques cmdlets permettent d’effectuer des opérations basiques sur les fichiers:
Remove-Item
: pour supprimer un fichier ou un répertoireRename-Item
: pour renommer un fichier ou un répertoireMove-Item
: pour déplacer un fichier ou un répertoire
Pour créer un répertoire on peut écrire la commande suivante:
New-Item -Path "<chemin du répertoire>" -ItemType Directory
Générer un fichier
Pour écrire un fichier, on peut écrire:
Set-Content -Value <variable avec le contenu à écrire> -Path "<chemin du fichier à écrire>"
Si le fichier existe déjà, Set-Content
écrase son contenu, il ne rajoute d’élément à un contenu déjà existant.
Pour ajouter un contenu quand le fichier existe déjà, il faut utiliser Add-Content
.
Par exemple:
Add-Content -Value <nom d'une variable avec le contenu à écrire> -Path "<chemin du fichier>"
Si le fichier n’existe pas, il sera créé.
On peut aussi utiliser la commande Out-File
.
Par exemple pour générer un fichier temporaire:
$tempFilePath = [System.IO.Path]::GetTempFileName()
$fileContent = "Content to write to the temp file"
$fileContent | Out-File $tempFilePath
Exporter dans un fichier CSV
On peut exporter un fichier CSV avec des instructions particulières, par exemple:
Get-Process | Export-Csv "<nom du fichier>"
Ajouter un header au fichier CSV au moment d’importer le fichier:
$header = "col1", "col2", "col3"
$process = Import-Csv "<nom du fichier à importer>" -Header $header
Fichier XML
De même pour créer un fichier XML, on peut écrire:
$courseTemplate = @"
<employees>
<employee id="1">
<name>Person 1</name>
<age>23</age>
</employee>
<employee id="2">
<name>Person 2</name>
<age>56</age>
</employee>
<employee id="3">
<name>Person 3</name>
<age>21</age>
</employee>
</employees>
"@
$courseTemplate | Out-File "<chemin du fichier>"
Si on affiche le contenu de la variable, on s’aperçoit qu’il s’agit d’un type plus complexe qu’une chaîne de caractères:
Par exemple:
PS C:\> Write-Host $xmlVar
#document
En omettant Write-Host
, on peut afficher davantage d’éléments:
Par exemple:
PS C:\> $xmlVar
employees
---------
employees
et
PS C:\> $xmlVar.employees
employee
--------
{Person 1, Person 2, Person 3}
Pour charger un fichier XML
On peut écrire le code suivant:
$xmlVar = New-Object xml
$xmlVar.Load("<chemin du fichier à lire>")
Travailler sur un nœud XML
On peut atteindre un nœud particulier d’un fichier XML facilement de la façon suivante:
$nodeVal = (@($xmlVar.employees.employee)[0]).Clone()
employees.employee
correspond à un élément du fichier; (@($xmlVar.employees.employee)
contiendra un tableau avec toutes les occurences de l’élément.
Ainsi, pour afficher le contenu de $nodeVal
:
Par exemple:
PS C:\> $nodeVal
id name age
-- ---- ---
1 Person 1 23
Pour ajouter des éléments XML
A partir de la variable définit précédemment, on peut éditer des valeurs et ajouter un nouveau nœud en écrivant:
$newVal = $nodeVal.Clone()
$newVal.name = "Person 4"
$newVal.age = "3"
$xmlVar.employees.AppendChild($newVal) > $null
Si on ne rajoute pas > $null
dans la ligne .AppendChild($newVal)
, l’ajout sera redirigé vers l’écran.
Si on affiche de nouveau, le contenu de $xmlVar.employees
, on s’aperçoit qu’un nœud a été rajouté:
Par exemple:
PS C:\> $xmlVar.employees
employee
--------
{Person 1, Person 2, Person 3, Person 4}
Pour supprimer le template du fichier ou supprimer un nœud du fichier:
$xmlVar.courses.course |
Where-Object {$_.Name -eq "Person 1"} |
ForEach-Object {[void]$_
$xmlVar.courses.RemoveChild($_)
}
Pour sauver le fichier XML
$xmlVar.Save("<chemin du fichier>")
Pour charger directement un fichier XML
On peut utiliser le mot clé [xml]
, par exemple:
[xml]$xmlVar = Get-Content "<chemin du fichier>"
Partie 3: instructions dans des scripts Powershell
Partie 4: aide, gestion d’erreurs et manipulation de fichiers
bonjour,
merci pour ton site qui est très complet, j’ai appris de nombreuses astuces !!
je cherche un livre ou bien un site qui puisse m’expliqué comment utilisé une DLL managé en C#
au travers de powershell. j’utilise une DLL du constructeur ftdichip.com lequel fournit les sources et la DLL
associé. J’arrive facilement à utiliser les méthodes, mais la DLL contient aussi des types personnalisés
et je n’arrive pas à les exploiter lorsque ceux ci sont utilisé en paramètre d’une méthode
exemple:
$FtdiDllPath = $PSScriptRoot + “\FTD2XX_NET_v1.1.0\FTD2XX_NET.dll”
$objectFTDI = [Reflection.Assembly]::LoadFile($FtdiDllPath)
$objectFTDI = New-Object FTD2XX_NET.FTDI
$objectFTDI.GetDeviceList(parameter = $objectFTDI.FT_DEVICE_INFO_NODE)
bonne journée
Bonjour,
Je pense que tu devrais utiliser une méthode avec Add-Type pour exécuter du code C# qui appellerait directement les fonctions dans les DLL FTDI.
Cette méthode est explicitée sur ces sites:
https://blog.stefan-gossner.com/2010/05/07/using-csharp-c-code-in-powershell-scripts/
https://gist.github.com/Sh1n0g1/8e98dcaf8df5f2951f1e52607a127191
https://blog.adamfurmanek.pl/2016/03/19/executing-c-code-using-powershell-script/
http://executeautomation.com/blog/calling-c-code-in-powershell-and-vice-versa/
Il faut faire attention aux dépendances des DLL. A l’exécution, il faut vérifier s’il n’y a pas des erreurs liées à des dépendances manquantes pour les rajouter le cas échéant avec l’argument ReferencedAssemblies.