PI Services

Le blog des collaborateurs de PI Services

Powershell: Gestion des erreurs sur Cmdlet

 

Dans mon précédent blog, je vous est montré comment on pouvait mettre en place la gestion d’erreur sur des commandes sous powershell qui ne sont pas des CMDLET, cette fois-ci nous allons voir comment appliquer la gestion d’erreur sur une CMDLET

PERIMETRE: Dans le cadre de l’amélioration des script powershell concernant la vérification des services après le redémarrage des serveurs en production chez un de nos client, celui-ci à laisser le soin au service architecture de trouver une solution.

 

Mon script d’origine:

######SERVEURS A REDEMARRER################

$Computerstring = "orches1"
$Computerdestination = $Computerstring.Split(",")

######SERVICES A ARRETER ET REDEMARRER################

$Servicesstring = "wudfsvc"
$Servicesname = $Servicesstring.Split(",")

######LOG CREER POUR LA VERIFICATION AVANT L'ARRET DES SERVICES SUR CHAQUES SERVEURS + GESTION ERREUR SUR SYNTAXE Command###
$StatusService = foreach ($vm in $Computerdestination){
         get-Service -ComputerName $vm -name $Servicesname | select status,name,machinename }
       

#GESTION ERREUR DES SERVICES

$ExitCodeService = foreach ($SRVservices in $StatusService) {
if ($($SRVservices.status) -eq "Running"){
"Success : Service(s) Running" + $SRVservices
}else{
"Error : Service(s)" + $SRVservices
}
}

$ErrorStatusSVC = if ($StatusService -eq $null){
"Error : Service(s) "
}else{
"Success : Service(s)"
}  

Voici le résultat pour les sortie erreurs:

$ExitCodeService

image

$ErrorStatusSVC

image

Vous voyez au dessus $ExitCodeService prend en compte que le service wudfsvc étant arrêté comme SUCCESS condition voulu ceci est normal et que $ErrorStatusSVC à été mise en place pour anticipé les erreurs $ExitCodeService si aucune valeur ne ressort ($ExitCodeService = VIDE) cela peut être une erreur de syntaxe, de service ou de serveurs inaccessible ou inexistant

Par contre aucune erreur détailler il faut effectuer une recherche supplémentaire.

 

Mon script amélioré:

######SERVEURS A REDEMARRER################

$Computerstring = "orches1"
$Computerdestination = $Computerstring.Split(",")

######SERVICES A ARRETER ET REDEMARRER################

$Servicesstring = "wudfsvc"
$Servicesname = $Servicesstring.Split(",")

######LOG CREER POUR LA VERIFICATION AVANT L'ARRET DES SERVICES SUR CHAQUES SERVEURS + GESTION ERREUR SUR SYNTAXE Command###

$StatusService =
Try {
foreach ($vm in $Computerdestination){
         get-Service -ComputerName $vm -name $Servicesname -ErrorAction stop | select status,name,machinename
        }
}catch{
   "$vm => " + $Error[0]
   }

#GESTION ERREUR DES SERVICES

$ExitCodeService =                                                                                         foreach ($SRVservices in $StatusService) {
            if ($($SRVservices.status) -eq "stopped"){
                    "Success:" + $SRVservices
            }else{
                   "Error:" + $SRVservices
            } 
    }

Voici le résultat pour la sortie d’erreur:

La correction se base sur la gestion d’erreur avec les commandes Try et Catch

Dans la partie Try  entre crochets, la commande get-service doit obligatoirement avoir l’option qui permet la sortie d’erreur qui se nomme        –ErrorAction stop cela permettra d’avoir dans la partie catch les messages d’erreur le déroulement du processus $Error[0] . 

Message des erreurs qui sont géré dans : $StatusService

image

Erreur sur le compte d’ordinateur inexistant ou inaccessible:

image

Erreur sur le service inexistant ou inaccessible:

image

Erreur sur la syntaxe commande get-service:

image

Les messages de sortie sont aussi retransmis dans la variable  $ExitCodeService à l’aide des conditions if et else

Powershell – Exemple de transfert de données vers un système Unix

 

A la suite de la récupération d’un dataset issu d’une requête a une base sql on veut exporter et transférer les données vers un système Unix.

Comme indiqué dans le code, a la suite de la validation du fait que le résultat de la requête contienne des données (RequestSQL OK),  on converti le dataset en csv vers un fichier local ($FullLocalFile):

($DataSet.Tables[0] | convertto-csv -Delimiter ";" -NoTypeInformation)  | Out-File -FilePath $FullLocalFile

Puis on récupère le contenu du fichier pour ensuite le convertir au format UTF8 (au passage on écrase le fichier d’origine):

$content=get-content $FullLocalFile
Set-Content -value $content -Encoding UTF8 -Path $FullLocalFile –Force

Enfin on envoi en ftp le fichier vers le système Unix (en construisant dynamiquement le fichier de commande):

N.B: Il est possible que le mode de transfert (ascii ou binary) ait une influence sur le résultat du transfert. N’hésitez pas a tester les deux cas.

#construction fichier ftpcommands
New-Item -Path "$LocalDirectory\ftpcommands.txt" -ItemType file -Force -value `
"open monserverunix
user1
password
ascii
cd /monappli/data
lcd $LocalDirectory
mput $FileName
Y
bye"

#Envoi FTP et verification
ftp.exe -s:$LocalDirectory\ftpcommands.txt > "$LocalDirectory\resultatftp.txt"

(...)

#suppression du fichier ftpcommands
Remove-Item -Path "$LocalDirectory\ftpcommands.txt"
Remove-Item -Path "$LocalDirectory\resultatftp.txt"

 

$LocalDirectory="D:\Data" $FileName="data.csv" $FullLocalFile="$LocalDirectory\$FileName" (...) #Si le dataset est vide => Echec de la requête => $RequestSuccess=$false If (($DataSet.Tables[0] | Measure-Object).count -eq "0") { $RequestSuccess=$false write-host -ForegroundColor blue "Dataset vide - FIN DU SCRIPT" Exit } Else { $RequestSuccess=$true write-host -ForegroundColor green "RequestSQL OK" #Export du fichier CSV en local ($DataSet.Tables[0] | convertto-csv -Delimiter ";" -NoTypeInformation) | Out-File -FilePath $FullLocalFile #Recuperation du contenu et conversion en UTF8 pour compatibilité Unix $content=get-content $FullLocalFile Set-Content -value $content -Encoding UTF8 -Path $FullLocalFile -Force } #construction fichier ftpcommands New-Item -Path "$LocalDirectory\ftpcommands.txt" -ItemType file -Force -value ` "open monserverunix user1 password ascii cd /monappli/data lcd $LocalDirectory mput $FileName Y bye" #Envoi FTP et verification ftp.exe -s:$LocalDirectory\ftpcommands.txt > "$LocalDirectory\resultatftp.txt" (...) #suppression du fichier ftpcommands Remove-Item -Path "$LocalDirectory\ftpcommands.txt" Remove-Item -Path "$LocalDirectory\resultatftp.txt"

Powershell – Script – Suppression création de compteur de performance

 

Il peut être nécessaire dans le cas d’un script insérant des données de performance de supprimer/recréer l’objet de performance

L’exemple ci-dessous montre la suppression ré-création d’un objet MyObject et d’un compteur de performance Mycounter1.

On vérifie l’existence de l’objet de performance via wmi et l’objet .net [Diagnostics.PerformanceCounterCategory]

On supprime MyObject

On recrée l’objet et son compteur  via Diagnostics.CounterCreationDataCollection et Diagnostics.CounterCreationData

On soumet la création de l’objet “global” via [Diagnostics.PerformanceCounterCategory]

Le compteur peut a partir de là être alimenté et interrogé.

 

if((Get-WmiObject -Query "Select * from Win32_perfformatteddata_MyObject_MyObject").MyCounter1 -eq 0 ` -OR (Get-WmiObject -Query "Select * from Win32_perfformatteddata_MyObject_MyObject").MyCounter1 -eq $null ` -AND [Diagnostics.PerformanceCounterCategory]::Exists(“MyObject”)) { write-host "Suppression et re-creation de l'objet de performance MyObject" #Suppression [Diagnostics.PerformanceCounterCategory]::Delete(“MyObject”); #Creation de l'objet de perf $script:cntrColl = New-Object Diagnostics.CounterCreationDataCollection; Write-Host "Add counter 1"; $counter = New-Object Diagnostics.CounterCreationData; $counter.CounterName = "Mycounter1"; $counter.CounterHelp = "Help for Counter_1"; $counter.CounterType = [Diagnostics.PerformanceCounterType]::NumberOfItems64; $script:cntrColl.Add($counter); #Ajout du compteur Write-Host "Ajout du compteur a PerfMon"; [Diagnostics.PerformanceCounterCategory]::Create(“MyObject”, “My counter”, $script:cntrColl); }

SCOM – Mise a jour de MP Author en SP3

 

L’outil gratuit de création de management pack de Silect Software a été mis  a jour en SP3

http://www.silect.com/mp-author 

Au menu:

- Amélioration de la visualisation et de l'édition des KB

- Amélioration de l’edition du XML

- Détection des oublis de champs DisplayName

- Possibilité d’utiliser les “Bases classes” a la place de LocalApplication en tant que cible d’une nouvelle classe.

- Affichage d’objets supplémentaires issus des MP

-  Ajout d’une liste dynamique de variable pour la customisation des messages d’alertes.

- Amélioration de la gestion de la mémoire utilisée.

Powershell: Gestion d’erreur sur une commande NON CMDLETS

 

PERIMETRE: Tâches planifiés qui permette la réplication de fichier d’un serveur vers un autre chez un de nos client.

FONCTIONNEMENT: Les tâches planifiées lancent des scripts PowerShell, la commande utilisé est la commande ROBOCOPY

Dans le cadre de la gestion des erreurs des commandes dites NON CMDLETS qui sont propre à powershell, la gestion des erreurs est différente.

 

SCRIPT D’ORIGNE:

#Listes des serveurs destinations +chemin
$Srvdestination = "\\orches1\tachep"
$srvdest1 = $Srvdestination.split("\")  
$srvdest = $srvdest1[2]

#Fichier Log avec nom du serveur.log
$Filelog = "$srvdest.log"

#repertoire de LOGS pour la derniere ligne du script powershell
$Folderlogs = "\\orches2\TACHEcollection2"

# Rapport Log Robocopy
$LOGS1 = "$Folderlogs"+"\"+"$Filelog"

#Option logs + chemin du rapport log
$LOGS = "/log:"+"$LOGS1"


#Liste de(s) fichier(s) à copier
$File = "*.*"

#Listes du dossier sources Réplication
$SourceFolder = "\\orches2\tachep2"

#Options de la commande robocopy
$optionstrings = "/XX,/E,/Z,/R:1,/W:2,/MT:64,/TEE"
$options = $optionstrings.split(",")

 

#Copie du fichier source vidéo vers le serveur de destination
$Robocopy = Robocopy $sourcefolder $srvdestination $file $options $logs

$LASTEXITCODE

Il faut savoir que dans la variable $Robocopy vous avez l’affichage du Log robocopy + la création du log $logs  grâce à l’option /TEE qui permet 2 sorties

Nous avons le log Robocopy sous cette forme :

-----------------------------------------------------------------------------
   ROBOCOPY     ::     Robust File Copy for Windows                             
-------------------------------------------------------------------------------

  Started : dimanche 8 mars 2015 16:40:16
   Source : \\orches2\tachep2\
   Dest : \\orches1\tachep\

    Files : *.*       


  Options : *.* /TEE /S /E /DCOPY:DA /COPY:DAT /Z /XX /MT:64 /R:1 /W:2

------------------------------------------------------------------------------

        New File          246.3 m    \\orches2\tachep2\tache.zip
  ------------------------------------------------------------------------------

               Total    Copied   Skipped  Mismatch    FAILED    Extras
    Dirs :         1                0         0         0         0
   Files :         1         1         0         0         0         0
   Bytes :  246.36 m  246.36 m         0         0         0         0
   Times :   0:00:59   0:00:14                       0:00:00   0:00:14
   Ended : dimanche 8 mars 2015 16:40:45

Nous voyons clairement que le log robocopy affiche le résultat de la copie Ok, mais lorsque la copie est un fichier ou répertoire identique  ou qu’il y’a des options au niveau du robocopy à ajouter ou modifier cela devient compliquer à gérer, de plus si nous voulons afficher une sortie simplifié du style Error ou Success en plus du log robocopy, il faudrait connaitre tout les retours sur ce qui est considérer comme Error ou Success , Sans oublier l’erreur de syntaxe de la commande robocopy qui n'apparait pas.

solution se baser sur  $LASTEXITCODE par contre le code de sortie de 0 à 16 cela ne nous dis pas si c’est une Erreur ou un Succès du déroulement de la copie

Voici le 2ème Script avec la gestion des erreurs qui inclura aussi l’erreur de syntaxe de la commande avec l’utilisation de TRY et CATCH. et le SWITCH pour les sorties $LASTEXITCODE.

2EME SCRIPT (le début et identique):

Pour info: Robocopy $LASTEXITCODE. :

- De 0 à 7 : Succès

- De 8 à 16 : Erreur

#Copie du fichier source vidéo vers le serveur de destination
$RoboSyntaxe = try {

      Robocopy $sourcefolder $srvdestination $file $options $logs | Out-Null

          Switch ($LASTEXITCODE
{   
"16" {$RobocopyJob = "Error Robocopy : Serious error. Robocopy did not copy any files. $srvdestination" }
"15" {$RobocopyJob = "Error Robocopy :OKCOPY + FAIL + MISMATCHES + XTRA. $srvdestination" }
"14" {$RobocopyJob = "Error Robocopy : FAIL + MISMATCHES + XTRA . $srvdestination" }
"13" {$RobocopyJob = "Error Robocopy :OKCOPY + FAIL + MISMATCHES. $srvdestination" }
"12" {$RobocopyJob = "Error Robocopy : FAIL + MISMATCHES. $srvdestination" }
"11" {$RobocopyJob = "Error Robocopy : OKCOPY + FAIL + XTRA. $srvdestination" }
"10" {$RobocopyJob = "Error Robocopy : FAIL + XTRA . $srvdestination" }
"9" {$RobocopyJob = "Error Robocopy : OKCOPY + FAIL. $srvdestination" }
"8" {$RobocopyJob = "Error Robocopy: Some files or directories could not be copied $srvdestination" }
"7" {$RobocopyJob = "Success Robocopy : Files were copied, a file mismatch was present, and additional files were present $srvdestination"}
"6" {$RobocopyJob = "Success Robocopy : Additional files and mismatched files exist, No files were copied $srvdestination" }
"5" {$RobocopyJob = "Success Robocopy : Some files were copied. Some files were mismatched $srvdestination"}
"4" {$RobocopyJob = "Success Robocopy : Some Mismatched files or directories were detected $srvdestination" }
"3" {$RobocopyJob = "Success Robocopy : Some files were copied. Additional files were present $srvdestination" }
"2" {$RobocopyJob = "Success Robocopy : Some Extra files or directories were detected $srvdestination "}
"1" {$RobocopyJob = "Success Robocopy : One or more files were copied successfully $srvdestination"}
"0" {$RobocopyJob = "Success Robocopy : No Change files successfully $srvdestination"}     
}
                           
    }catch{
          "Error : syntaxe command robocopy"
          } 
 

Dans ce script nous avons 2 types de sortie d’erreur :

- La 1ère s’effectue à l’aide du Try et catch, si on enleve le Y de ROBOCOPY on obtient :

image

image

- La 2ème s’effectue à l’aide du switch sur la variable $LASTEXITCODE mais commenter avec le chemin de destination et la variable qui permet d’afficher le résultat est $RobocopyJob :

image

image

Nous pouvons envoyer ses informations dans les journaux d’évènement dans un journal personnaliser APPLIMETIER par exemple plutôt que le log robocopy qui peut être trop long et pas pris en compte.

 

 

 

Powershell 5.0 : Les classes

Introduction

Powershell 5.0 a bénéficié de plusieurs releases lors de l'année 2014, chacune d'entre elles apportant son lot de nouveautés/correctifs. Ce dernier est toujours en développement (la version finale n'arrivant qu'avec Windows 10) mais nous allons tout de même nous attarder dans cet article sur une nouvelle notion : la création de classes. Celle-ci n'était pas disponible nativement jusqu'en Powershell 5.0, ce qui pouvait paraître étrange pour un langage de scripting orienté objet. Je ferai un bref rappel sur les options disponibles avant cette version.

Dorénavant, nous pourrons créer nos propres objets personnalisés. Souvent, dans les scripts Powershell, on remarque l'utilisation de tableau ou de dictionnaire imbriqués et qu'il faut ensuite analyser pour récupérer la bonne valeur. Ces scripts obligent à avoir des algorithmes assez long et le script devient difficilement lisible en dehors du fait de ne pas être rigoureux. De plus, ils nécessitent souvent l'imbrication de multiples boucles de traitement influençant les performances générales du script.

Dans cet article, nous aborderons la création de classes d'objets en Powershell, l'ajout de propriétés et de méthodes ainsi que la façon d'instancier ("créer") nos objets. Pour certaines notions, une définition sera donnée (Cela permettra aux personnes non familières avec certaines notions de programmation objet de mieux appréhender le sujet).

Dans la suite de cet article, nous prendrons l'exemple d'une classe d'objet HRUser définissant un utilisateur dans le système RH pour illustrer la nouvelle syntaxe. Imaginons que cet exemple soit utilisé dans le cadre d'une interaction avec une base de données. L'objet utilisateur possédera les attributs suivant (nous ajouterons d'autres propriétés et des méthodes/fonctions ultérieurement) :

  • firstname
  • lastname
  • isCollaborator (un booléan permettant de savoir si l'utilisateur est un collaborateur)
  • salary (un nombre entier)

NB : Contrairement à la première beta, Powershell 5.0 est dorénavant disponible pour Windows 2012 et supérieur (qui n’était compatible qu’avec Windows 2012 R2 et supérieur). Le lien suivant vous mènera à la dernière beta sortie (Novembre 2014) :

http://www.microsoft.com/en-us/download/details.aspx?id=44987

Avant Powershell 5.0

Jusqu'à Powershell 4.0, il existait plusieurs méthodes pour créer des objets personnalisés en Powershell.

New-Object et NoteProperty :

La première méthode consiste à créer un objet de type PSCustomObject auquel on ajoute des propriétés de type NoteProperty.

Cependant, cette méthode ne permet pas d'ajouter des fonctions et le typage de nos attributs est dynamique. De plus, tout les objets personnalisés posséderont la même classe : PSCustomObject.

C# et Add-Type :

La seconde méthode était l'utilisation de code C#. Powershell pouvant interprété ce langage,  il est tout à fait possible d'écrire entièrement une classe en C# puis de l'ajouter dans une session Powershell via la commande Add-Type.

On peut ensuite créer l'objet grâce à la commande New-Object. Ce dernier possédera son propre type (HRUser) qui sera différent pour toutes les classes que vous créerez.

 

Il est aussi possible d'ajouter des fonctions statiques ou non à notre classe (nous reviendrons sur cette notion ultérieurement).

Cette méthode est complète mais nécessite de connaître le C#, ce qui complexifie aussi la lecture des scripts. Dans les prochains paragraphes, nous allons voir que Powershell offre dorénavant nativement les mêmes possibilités.

Les classes

Une classe contient la définition de nos objets ainsi que les traitements qui peuvent être effectués sur ceux-ci. Une nouveau mot clé apparaît dans Powershell 5.0 : “class” que l'on retrouve avant un scriptblock. Une classe se déclare de la façon ci-dessous :

Malheureusement, il n'existe pas encore de syntaxe pour gérer l'héritage de classe.

NB : Attention, les classes doivent obligatoirement être déclarées dans des scripts powershell. Une déclaration dans une invite de commande Powershell ne pourra donc pas être fonctionnelle.  De plus, lorsqu'une classe a été chargée, il est nécessaire d'ouvrir une nouvelle version avant d'en exécuter une version différente (elle ne peut pas être mis à jour dans une même session Powershell).

Les propriétés

Les propriétés contiennent tous les attributs de notre classe.

Celles-ci peuvent optionnellement contenir un type (comme dans l'exemple ci-dessus). Cela permet de réaliser de la validation sur les propriétés d'un objet.

Nous pouvons donc créer notre objet de type HRUser via la cmdlet New-Object en indiquant le type d'objet à créer.

 

On peut aussi créer un objet grâce à la méthode new qui existe dans chaque classe.

 

Toutes les propriétés sont initialisées avec une valeur par défaut (une chaîne vide, un booléen faux ou le chiffre 0 dans notre exemple).

On peut ensuite définir les propriétés de notre objet.

 

Attention, dans notre exemple, nos propriétés sont typées. On peut donc rencontrer une erreur si par exemple on définit une chaîne de caractères à la place d'un nombre pour la propriété “salary”.

ERROR PROPERTY TYPE

Les constructeurs

Un constructeur permet de créer un objet en initialisant certaines ou toutes de ces propriétés avec des valeurs fournies en paramètres et éventuellement d'effectuer des traitements lors de la création d'objets. La méthode “new” que nous avons vu précédemment correspond au constructeur par défaut. Mais il est possible d'en ajouter un ou plusieurs autre, c'est ce qu'on appelle la surcharge.

La syntaxe d'un constructeur est la suivante (il faut la placer à l'intérieur de la définition de notre classe) : On peut créer l'objet en lui passant des paramètres pour utiliser notre constructeur :

 

Ou

 

Cependant, on rencontrera une erreur si on ne renseigne pas tous les paramètres :

ERROR CONSTRUCTOR 

Pour palier à ce problème, on peut imaginer un second constructeur sans le salaire :

Les méthodes

Les méthodes sont l'équivalent de fonctions qui permettant d'interagir avec un objet. Nous allons créer une fonction permettant de gérer l'augmentation de salaire d'un employé.

Le type indiqué devant la méthode nous indique ce qui est retourné (“void” correspond à une méthode ne retournant rien).

Exemple d'exécution incluant une augmentation de salaire pour une personne :

EXEMPLE METHOD

Si nous souhaitons récupérer le nouveau salaire, il faut modifier la méthode en utilisant le mot clé “return” et en modifiant le type de retour.

Méthodes et propriétés statiques

Il reste un dernier mot clé à définir : “static”. Il permet de définir des méthodes et des propriétés qui sont accessibles sans avoir à créer un objet. Pour illustrer cette notion, nous allons ajouter une propriété représentant le total des utilisateurs du système. De plus, nous allons modifier les constructeurs pour incrémenter le compteur quand un utilisateur est créé.

On définit la propriété count :

 

On peut y accéder via : [HRUser]::count

Voici le script contenant l'intégralité de la définition de  la classe HRUser :

Exemple d'exécution :

EXEMPLE STATIC

Il aurait pu être intéressant d'intégrer la modification du compteur lors de la suppression de l'utilisateur dans la classe. Cependant, il n'existe pas de destructeur (méthode permettant de détruire un objet) dans la version actuelle de Powershell 5.0.

Conclusion

Nous avons aborder la création de classes d'objets en Powershell qui nécessite d'avoir des connaissances en programmation orientée objet. Initialement, Microsoft a ajouté cette notion pour simplifier la création de ressources pour Desired State Configuration (exemple : https://technet.microsoft.com/en-us/library/dn820211%28v=wps.640%29.aspx). A noter que lorsque vous charger une classe et que vous créer des objets, toutes les propriétés et méthodes associées sont accessible via l'auto complétion. Les classes écrites en Powershell sont une nouveauté et il reste encore des améliorations à réaliser :

  • l'héritage des classes.
  • la portée sur les propriétés : en Powershell, elles sont toutes publiques et donc accessible/modifiable depuis n'importe quel endroit dans un script. Changer la portée permettrait de spécifier des propriétés qui ne seraient accessibles que dans une méthode de la classe.

Powershell 5.0 : découvertes de quelques nouveautés

Introduction

Powershell 5.0 est encore en beta mais de nombreuses nouveautés sont déjà présentes. Nous allons aborder dans cet article quelques unes d'entres elles. Elles peuvent concerner : Powershell, son éditeur (Powershell ISE) ou encore son paramétrage dans Windows. Certaines avaient déjà été évoquées dans l'article suivant lors de la première preview de Powershell 5.0 :
http://blog.piservices.fr/post/Powershell-V5-Preview-est-sorti-!-DSC-Switch-OneGet-et-du-chocolat.aspx

NB : Contrairement à la première beta, Powershell 5.0 est dorénavant disponible pour Windows 2012 et supérieur (qui n’était compatible qu’avec Windows 2012 R2 et supérieur). Le lien suivant vous mènera à la dernière beta sortie (Novembre 2014) :

http://www.microsoft.com/en-us/download/details.aspx?id=44987

Gestion des Archives

Un nouveau module permettant de gérer nativement les archives apparaît dans Powershell 5.0. Cette option n'était auparavant disponible qu'au travers de module réalisé par la communauté. Ce dernier permet de générer des archives (Compress-Archive) ou de les extraire (Expand-Archive). Seul le format Zip est actuellement géré. Un paramètre nommé “update” permet de mettre à jour une archive existante en ajoutant seulement les nouveaux fichiers et les changements sur les fichiers déjà présents dans l'archive. Le paramètre “path” peut définir un ou plusieurs fichiers ainsi qu'un dossier entier en utilisant le caractère “*” (wildcard). Enfin le paramètre “CompressionLevel” permet d'influencer le taux de compression et la taille finale de l'archive.

 

Zip module

Support des raccourcis claviers

La console Powershell supporte désormais certains raccourcis clavier : copier (CTRL+C), coller (CTRL+V), tout sélectionner (CTRL+A).

Gestion des liens symboliques

Il est dorénavant possible de créer/supprimer des raccourcis via Powershell. Cette fonctionnalité est incluse dans la commande New-Item en spécifiant le type “SymbolicLink”.

Création d'un raccourci vers un fichier

 

Création d'un raccourci vers un dossier

 

On peut aussi lister des fichier via la commande Get-ChildItem en passant par un raccourci !

Event Viewer

Un nouveau journal de log est apparu dans l'observateur d'événements. Par défaut, ce dernier enregistre les lancements de console Powershell et les erreurs générales comme un échec de chargement de module. Ce nouveau journal est situé dans Applications and Services Logs\Microsoft\Windows\PowerShell\Operational. Il peut aussi enregistrer les exécutions de code Powershell. Cette fonctionnalité s'active via GPO.

Attention : Activer l'utilisation de ce journal pour les exécutions de code est très verbeux. Néanmoins cela peut être très utile pour obtenir rapidement des traces d'actions effectuées sur des serveurs via Powershell.

Il est possible d'activer cette fonctionnalité via GPO (voir paragraphe ci-dessous).

GPO

Les modèles d'administration possède désormais un ADMX permettant de gérer quelques paramètres Powershell. Ce dernier est situé dans Administrative Templates / Windows Components / Windows PowerShell. Il serait compatible avec les systèmes d'exploitation de la famille Windows 7 / Windows 2008 et supérieur (je ne l'ai personnellement testé que sur Windows 10 Server Technical Preview). Cette nouveauté n'est donc pas totalement liée à Powershell 5.0 puisqu'elle sera fonctionnelle sur les anciennes versions de Powershell.

Administrative Template Powershell

Les paramètres configurables sont les suivants :

  • Activer les traces dans l'observateur d'événements pour tout exécution de script.
  • Activer les traces dans l'observateur d'événements pour les exécutions de module Powershell (il faut préciser les modules concernés).
  • Définir la politique d'exécution des scripts (Set-ExecutionPolicy). Il s'agit d'une très bonne nouvelle car il n'existait pas de solution pour généraliser ce paramètre sur un grand nombre de serveur hormis en passant par une ressource DSC (ce qui représente un déploiement beaucoup plus lourd).
  • Activer automatique du transcript : cela permet de ne pas avoir à lancer la commande “start-transcript”. Il est également possible de définir le chemin où doit être stocké le transcript. Par défaut le nom du fichier est horodaté, contient le nom de l'ordinateur et est stocké dans le répertoire “Mes documents” de l'utilisateur de la session Powershell.
  • Définir la source de l'aide Powershell. Depuis Powershell 3.0, l'aide des cmdlets n'est pas entièrement incluse avec le package d'installation Powershell. Il est nécessaire d'utiliser la commande “Update-Help” pour la mettre à jour (par défaut, elle est récupéré depuis internet). Cela permet entre autre de récupérer l'aide avec la langue qui nous intéresse. Grâce à ce paramètre, on peut dorénavant spécifier une source comme un partage de fichier. Néanmoins, l'utilisateur a toujours la possibilité de changer le comportement en indiquant lui même une valeur lors de l'exécution de la commande via le paramètre “SourcePath”.

Tous ces paramètres sont disponibles dans la configuration ordinateur et utilisateur de la GPO.

Transcript

La génération de transcript n'était jusqu'à présent fonctionnelle que dans la console Powershell. Grâce aux cmdlets “Start-Transcript” / “Stop-Transcript”, il est désormais possible de générer des fichiers de traces aussi via Powershell ISE.

Powershell ISE avec Powershell 4 :

Powershell ISE transcript v4

Powershell ISE avec Powershell 5 :

Powershell ISE transcript v5

PSEdit

Une nouveauté fait son apparition dans Powershell ISE et le PSRemoting : PSEdit. Cet outil existait déjà et permettait d'ouvrir script dans un nouvel onglet dans Powershell ISE lorsque l'on exécutait la commande suivante : PSEdit chemin_de_mon_script.

Cependant, dans cette nouvelle version de Powershell ISE, il est possible d'ouvrir des fichiers à distances. Il n'y a donc plus besoin d'ouvrir Powershell ISE sur la machine où se trouve le script pour l'éditer. Il suffit d'ouvrir une PSSession puis d'exécuter PSEdit.

Cette fonctionnalité est facilement testable même en local en simulant une session distante :

PSEdit Remote file

Il n'y a pas besoin de connaître le chemin exact du script puisque l'auto complétion est disponible pour le retrouver.

Enumérations

La dernière nouveauté expliquée dans cet article est plus orientée scripting. Les énumerations font leurs apparitions dans Powershell. Pour cela un nouveau mot clé est disponible : “enum”. Celles-ci vont nous permettre de réaliser plus rapidement de la validation de paramètres.

Prenons le cas du paramètre ErrorAction disponible sur toutes les commandes Powershell. Il n'est possible de fournir qu'un certain nombre de valeurs : Continue, Ignore, Inquire, SilentlyContinue, Stop, Suspend. Ceux-ci correspondent à une énumération.

La syntaxe d'une énumération est la suivante : Pour utiliser cette dernière dans une fonction :

Nous pouvons remarquer que les choix disponibles sont proposés par le système d'auto complétion.

EnumEnfin, si l'on souhaite récupérer les valeurs d'une énumération, il faut exécuter la commande suivante :

 

Conclusion

Powershell 5.0 et Windows 10 sont riches en nouveautés pour le langage de scripting de Microsoft. Certaines d'entre elles n'ont pas été abordées mais feront l'objet d'articles dédiées :

  • La création de classes d'objets personnalisés.
  • Les améliorations de Desired State Configuration comme la gestion des configurations partielles permettant de segmenter celles-ci en plusieurs fichiers (exemple : par fonctionnalité).
  • PowershellGet : à l'instar de OneGet qui permet de récupérer des packages, ce dernier offre la possibilité de récupérer des modules depuis internet ou depuis sa propre source. Ainsi, une société peut créer sa bibliothèque de modules Powershell.