Introduction
Lorsque l'on développe des scripts Powershell, il y a un certain nombres de commandes génériques que l'on réutilise très souvent. Nous verrons aussi quelques astuces qui peuvent être utiles dans de nombreux scripts.
Astuces
Retrouver le dossier d'exécution du script :
Souvent, il arrive que l'on crée une bibliothèque de scripts. Un script peut en appeler un autre parce qu'il contient des fonctions. On peut aussi vouloir faire appel à un fichier de configuration. Beaucoup de scripts contiennent alors le chemin d'exécution via une variable qu'il convient de changer manuellement dès que le répertoire est modifié. Cela n'est cependant pas très portatif. Il est nettement plus intéressant de retrouver ce chemin dynamiquement.
La commande ci-dessous permet de retourner le dossier où se situe le script qui est en train de s'exécuter.
001 002
| $RootFolder = Split-Path -Path $MyInvocation.MyCommand.Path
|
On peut ensuite retrouver nos fichiers additionnels via des chemins relatifs calculés depuis celui que l'on vient de récupérer.
"$MyInvocation.MyCommand.Path" retourne le chemin du fichier.
A partir de ce dernier la commande "Split-Path" nous retourne uniquement le dossier dans lequel est contenu le script.
Connaître le contexte d'exécution (32 ou 64 bits) :
Il peut arriver que l'on souhaite lancer un exécutable spécifiquement depuis une instance Powershell x86 ou x64 car celui-ci n'existe pas dans un autre contexte.
Pour cela, il existe une astuce permettant de savoir quelle édition de Powershell (x86 ou x64) est lancée :
001 002
| [System.IntPtr]::Size
|
Cette commande nous donne la taille d'un pointeur sous la forme d'un entier. Lorsque l'invite de commande Powershell est en x64, cette valeur vaut 8. Dans le cas contraire il s'agit de 4. On peut facilement imaginer une structure conditionnel permettant de relancer un script automatiquement en Powershell x86 qui intègre un exécutable ne tournant que sur cette version.
001 002 003 004 005 006
| if( [System.IntPtr]::Size -ne 4) { #Chemin du script $Path = $myInvocation.InvocationName #Invocation de Powershell x86 avec le même script à exécuter comme paramètre $Return = &"$env:windir\syswow64\windowspowershell\v1.0\powershell.exe" $Path } |
Le script est-il exécuté en mode administrateur :
Dans le même esprit, il est possible de savoir si un script a été lancé en mode administrateur. En effet, certaines opérations peuvent exiger ce mode de fonctionnement :
001 002
| ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator") |
Bien évidemment il n'existe pas de commande pour relancer le script dans ce mode. On peut cependant inviter l'utilisateur à le faire.
Tester son script pour une autre version de Powershell :
Il peut arriver que l'on développe son script Powershell sur son poste client qui est en version 3 alors que le serveur qui le lance est lui en version 2. Afin d'être certain que ce script est compatible, il est possible d'indiquer la version de Powershell à utiliser. En voici un exemple ci-dessous :
En version 3 il n'est plus nécessaire de faire d'Import-Module pour utiliser les cmdlets Active Directory, ce qui n'est pas le cas en Powershell 2. Nous voyons donc clairement la différence entre les 2 exécutions.
Appeler une librairie .NET :
Il existe de nombreuses méthodes pour charger une librairie .NET (sous forme de dll ou directement de code C# par exemple). Ici, nous en verrons une qui utilise la commande Powershell Add-Type :
Pour utiliser les Windows forms pour les interfaces graphiques.
001 002
| Add-Type -AssemblyName "System.Windows.Forms" |
Pour administrer IIS, on charge une dll depuis son emplacement sur le disque
001 002
| Add-Type -Path "c:\windows\system32\inetsrv\microsoft.web.administration.dll" |
Intégrer directement du code C# (il est aussi possible de le faire avec du code VBScript)
001 002 003 004 005 006 007 008 009 010 011 012
| Main; Add-Type -TypeDefinition @" public class Test { public string Name {get;set;} public int Size {get;set;} public Test(string Name, int Size){ this.Name = Name; this.Size = Size; } } "@ |
Toutefois lorsque la commande Add-Type sera exécutée il n'est pas possible de recharger une librairie qui aurait été modifiée (Cela est dû à .NET). En effet une librairie ne peut être déchargée. Il faut alors changer de session Powershell (c'est à dire lancer une nouvelle instance de Powershell).