• Foreach sous Powershell

    Powershell, comme nous l'avons déjà entr'aperçu, est un shell très orienté développeurs. On y retrouve en effet un nombre de paradigmes de la programmation "objets". Parmis ceux-ci, la notion d'itération (c'est à dire la possibilité d'executer un traitement plusieurs fois) est representée par 3 commandes : forwhile et foreach. C'est sur cette derniere - qui est la plus intéressante - que nous allons un peu nous attarder.

    Commençons par un petit exemple très simple : imaginons que vous souhaitiez obtenir la liste des fichiers de sauvegarde SQL dans un dossier. La commande suivante devrait parfaitement vous satisfaire :

    gci *.bak

    Nous allons donc un peu complexifier cet exemple et imaginer que nous allons restaurer (dans un environnement de developpement, de pré-prod ou tout ce que vous voudrez) tous ces fichiers sur l'instance locale de SqlServer (nous utiliserons pour cela la fonction restore-database que vous trouverez ici - Attention, cette fonction est juste un exemple de ce que l'on peut faire pour restaurer une base de données SQL, elle n'est pas destinée à être utilisée en production).Pour ne pas trop chercher à rendre incompréhensible le script , les fichiers de sauvegardes seront supposés être nommés nom_de_la_base-date_de_la_sauvegarde.

    gci *.bak | foreach 
    {
    restore-database ...
    $_.Name.SubString($_.Name.IndexOf("-")) ...
    $_.Name }

    Expliquons un peu cette ligne de commande : l'instruction foreach va executer le block entre accolades pour chacun des objets qu'elle obtiendra de la pipeline. Pour savoir l'objet courant de l'itération (sur quel objet on se trouve actuellement...), nous avons à disposition la variable reservée $_. $_.Name va donc énumérer successivement tous les noms de fichiers récupérés par le gci.

    Ce qui est interessant de savoir, c'est que le contenu d'un foreach n'a pas besoin de se limiter à une seule instruction. Le script suivant est parfaitement valable :

    gci *.bak | foreach 
    {
    restore-database ...
    $_.Name.SubString($_.Name.IndexOf("-")) ...
    $_.Name move $_ ..\done }

    Pour savoir si vous avez bien compris, je vous invite a essayer d'ecrire :

    • un script qui modifie les dates de dernieres modifications de tous les fichiers bak pour simuler la commande touch.
    • un script qui vous donne l'état des services MSSQLSERVER et IISADMIN ainsi que leurs "enfants" (l'agent Sql, les services http, https, etc.). Pour cela, je vous donne une petite aide : pour obtenir les 2 services "racines", vous pouvez faire
    "mssqlserver","isadmin" | get-service
    • un script qui retire tous les fichiers de sauvegarde de toutes les bases sauf le plus récent (et pas question de tricher avec une comparaison par rapport à la date du jour : vous pourriez avoir plusieurs sauvegardes le même jour)