Le blog technique

Toutes les astuces #tech des collaborateurs de PI Services.

#openblogPI

Retrouvez les articles à la une

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.