Bien que PowerShell soit extrêmement « productif »
par rapport à d’autres langages de script ; je veux dire par là qu’avec
peu de lignes de code on réalise beaucoup d’actions, il existe néanmoins un
domaine dans lequel il est très facile de se faire des nœuds au cerveau et de
perdre énormément de temps. Ce domaine est l’appel d’exécutables externes auxquels
on veut passer des valeurs non fixées en dur dans le code.
Après tout PowerShell comme son nom l’indique est avant tout
un shell, et à ce titre, il est donc tout à fait normal de vouloir combiner du
PowerShell avec des exécutables existants tels que Robocopy.exe, 7Zip ou autres. En
effet, pourquoi vouloir tout reécrire en PowerShell alors que des exécutables que
l’on utilisait avec CMD remplissent parfaitement leur office ?
Certes, lorsque l’on est puriste comme moi, on voudrait
pouvoir faire table rase du passé et tout faire avec un seul script PowerShell mais bon parfois..., comme dirait maître Yoda, raison garder il nous faut !
Bref, imaginons que nous voulions faire appel à l’utilitaire
Robocopy pour mettre en miroir deux répertoires.
Exemple 1:
Appel direct
PS > robocopy
C:\temp\Source\ C:\Temp\Destination\ /MIR /LOG:c:\temp\robocopy.log /TEE
Pas de problème, ici les valeurs sont renseignées en "dur", tout fonctionne.
Exemple 2: Appel direct avec variables
On commence par définir les variables qui référenceront les répertoires source et destination.
PS > $source = 'C:\temp\Source'
PS > $dest = 'C:\Temp\Destination'
PS >
robocopy
$source $dest /MIR /LOG:c:\temp\robocopy.log /TEE
Puis on appelle le script en substituant les valeurs en dur par les noms des variables.
Exemple 3 : Concaténation de la ligne de commande et exécution de cette dernière
Là où les choses se corsent un peu, c'est lorsque nous voulons faire plus "proprement" les choses. C'est à dire qu'il peut être plus professionnel de créer une variable de type chaine qui contiendra l'intégralité de la ligne de commande et ensuite de faire appel à elle pour l'exécution.
PS > $cmdline = "robocopy $source $dest /MIR /LOG:c:\temp\robocopy.log /TEE"
PS > & ([scriptblock]::Create($cmdline))
Pour que cela fonctionne, il faut créer un bloc de script à partir de notre chaine de caractère, puis passer ce dernier à l'opération d'invocation "&".
Exemple 4 : Exécution en arrière-plan
Enfin, une chose qu'il m'arrive de faire de temps à autres afin de paralléliser des actions longues durées, c'est d'utiliser les jobs. Ainsi si nous voulions faire exécuter notre commande en arrière plan, nous pourrions le faire ainsi :
PS > Start-Job
-ScriptBlock ([scriptblock]::Create($cmdline)) -Name Robocopy
PS > Receive-Job
–Name Robocopy
|