PI Services

Le blog des collaborateurs de PI Services

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); }

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.

Script Powershell–Scom: Surveillance consommation reguliere de fichiers dans un dossier

 

Le script ci-dessous surveille la consommation (création / suppression) régulière de fichiers dans un dossiers en excluant potentiellement des noms de fichiers et des heures de dernieres modification puis remonte l’état a SCOM.

Lien du script plus bas.

##################################################################################################### #SCRIPT DE SUPERVISION DU CHANGEMENT DE CONTENU DU DOSSIER ARRIVEE POUR L'APPLICATION INVENTAIRE #ETAT KO SI DES FICHIERS SONT PRESENT APRES 15 minutes (CES FICHIERS SONT CENSES ETRE RAPIDEMENT CONSOMMES) ##################################################################################################### #NB: L'INTERVALLE DE TEMPS DE COMPARAISON EST CELLE DE L'INTERVALLE D'EXECUTION DU SCRIPT #SONT EXCLUS DANS LES CRITERES DE RECHERCHE LES FICHIERS CREES ENTRE 22:00 ET 00:59 Param( [string]$computerName, [string]$DirPath, [regex]$excludedfiles="^(FILETOEXCLUDE)|(FILETOEXCLUDE)$", [regex]$filename="^.*(.*)$", [regex]$excludetime="^(22:).*|(23:).*|(00:).*$" ) $scriptname="CheckDirFileConso" #API Scom $api = new-Object -ComObject 'Mom.ScriptAPI' #Verification de l'existence d'une source ayant le nom du script dans l'eventlog operation manager pour loguer certains events Function NewEventSource { if(!(Test-Path "HKLM:\SYSTEM\CurrentControlSet\services\eventlog\Operations Manager\$scriptname")) { New-EventLog -LogName "Operations Manager" -Source $scriptname } } #Verification de l'existence du dossier $DirPath if (!(test-path -Path $DirPath)) { write-host "le dossier $DirPath est introuvable" NewEventSource Write-EventLog -LogName "Operations Manager" -Source $scriptname -EntryType Error -EventId 1004 -Message "le dossier $DirPath est introuvable" Exit } $Files=Get-ChildItem -Path $DirPath | Where-Object {$_.name -match $filename -AND $_.name -notmatch $excludedfiles -AND $_.lastwritetime -lt (get-date).AddMinutes(-15) -AND $_.LastWriteTime.ToLongTimeString() -notmatch $excludetime} | Select-Object -Property Name -ExpandProperty Name If ($Files) { write-host -ForegroundColor yellow -BackgroundColor black "Les fichiers suivants sont présent depuis 15 minutes dans le dossier $DirPath:" foreach ($file in $Files) { write-host $file } NewEventSource Write-EventLog -LogName "Operations Manager" -Source $scriptname -EntryType Warning -EventId 1005 -Message "Les fichiers suivants sont présent depuis 15 minutes dans le dossier $DirPath: $Files" $status="KO" write-host "" write-host -ForegroundColor yellow -BackgroundColor black "ETAT $status" } Else { write-host -ForegroundColor green "Tout les fichiers présents il y a 15 minutes dans le dossier $DirPath ont été consommés" NewEventSource Write-EventLog -LogName "Operations Manager" -Source $scriptname -EntryType Information -EventId 1000 -Message "Tout les fichiers présent il y a 15 minutes dans le dossier $DirPath ont été consommés" $status="OK" write-host "" write-host -ForegroundColor green "ETAT $status" } #Envoi de l'état a SCOM $bag = $API.CreatePropertyBag() If ($status -eq "KO") { $bag.AddValue("Status","Warning") } Else { $bag.AddValue("Status","Success") } $bag

 

 

PowerShell - Générer un rapport au format HTML (1/2)

Contexte

Cet article a pour objectif de fournir les principales commandes PowerShell afin de créer un rapport, qui, exécuté avec une tâche planifiée, permet de générer automatiquement un rapport HTML envoyé par mail.

Dans cette série de deux articles, nous verrons comment créer deux scripts PowerShell qui permettent de remonter les principales informations pour :

  • Une liste d’un ou plusieurs serveurs HYPER-V,
  • Les machines virtuelles présentes sur un ou plusieurs serveurs HYPER-V.

Compatibilité :

Les scripts présentés dans cette série ont étés testés sur :

  • HYPER-V pour Windows Server 2012R2
  • HYPER-V pour Windows Server 2012

Dans ce premier article nous verrons les principales commandes à maitriser pour générer un rapport HTML à l’aide de PowerShell, ce prérequis est commun aux scripts de rapport des VMs ainsi qu’au script de rapport des Hyperviseurs.

Générer un rapport HTML en utilisant PowerShell

Afin de mieux nommer le fichier HTML l’idéal est de récupérer dans des variables la date et l’heure afin nommer le fichier de manière unique lors de chaque exécution :

image

Pour ajouter le code HTML depuis PowerShell, j’utilise la même variable tout au long du code dans laquelle le code HTML est ajouté à l’aide de l’operator “+=”. Une fois le script terminé, la variable contenant le code HTML est écrite vers le fichier HTML créé.

La ligne suivante permet de créer le fichier HTML vide sur lequel le code HTML vas être écrit :

image

Une fois le fichier HTML créé, il faut – comme pour toute page HTML – commencer par ouvrir les principales balises (html, head) ainsi que préciser l’encodage utilisé. On peut également en profiter pour définir le style désiré pour certaines balises types, ce qui évite d’avoir à préciser les mêmes éléments lors de l’utilisation de ces balises :

image

On peut remarquer l’utilisation de l’expression @" et de "@ qui nous permettent pour une variable au format string d’utiliser plusieurs lignes, ce qui permet d’avoir un code HTML correctement agencé.

Afin d’ajouter le contenu de la variable dans le fichier HTML, il faut utiliser la commande “Add-Content” :

image

Maintenant que le début du fichier HTML est créé, le script doit maintenant récupérer les informations que l’on souhaite faire apparaitre dans le rapport HTML (nous verrons ce point dans la partie suivante de ce post) dans des tableaux que l’on génère au fur et à mesure dans une boucle qui parcoure toutes les ressources (VM ou Hoster) à interroger afin de créer ce type de vue :

image

Le rapport présenté ci-dessus contient 4 tableaux des ressources qui sont regroupés dans un tableau pour des raisons d’affichage.

Afin de maitriser la taille en largeur des tableaux HTML des ressources, on commence par récupérer le nombre de tableau que l’on va générer que l’on divise par la taille du bloc. De cette manière, les tableaux des ressources auront la même taille :

image

La génération des tableaux des ressources est faite à l’aide d’une boucle qui va pour chaque machine de la liste récupérer ses informations puis créer un tableau pour chaque ressource. Avant la boucle, un tableau vide est créé, il faut bien veiller à fermer ce tableau après la sortie de la boucle :

image

Conclusion

Dans cet article, nous avons vu comment faire à l’aide de PowerShell pour générer des rapport HTML.

Le plus important est de bien maitriser l’ordre de génération du code HTML de manière à ce que les balises respectent les règles du format HTML.

Dans l’article suivant, nous verrons comment récupérer les principales informations pour une VM et un hôte HYPER-V afin de les ajouter aux tableaux composant le rapport HTML.

PowerShell - Générer un rapport au format HTML (2/2)

Contexte

Cet article a pour objectif de fournir les principales commandes PowerShell afin de créer un rapport, qui, exécuté avec une tâche planifiée, permet de générer automatiquement un rapport HTML envoyé par mail.

Dans cette série de deux articles, nous verrons comment créer deux scripts PowerShell qui permettent de remonter les principales informations pour :

  • Une liste d’un ou plusieurs serveurs HYPER-V,
  • Les machines virtuelles présentes sur un ou plusieurs serveurs HYPER-V.

Compatibilité :

Les scripts présentés dans cette série ont étés testés sur :

  • HYPER-V pour Windows Server 2012R2
  • HYPER-V pour Windows Server 2012

Dans l’article précédent nous avons vu comment utiliser PowerShell pour générer un fichier HTML. Cet article présenteras les principales commandes PowerShell pour la génération d’un rapport affichant les principales informations des VMs ainsi que des Hyperviseurs.

Créer la liste des serveurs

Afin de préciser le noms des hyperviseurs qui seront interrogés, sans entrer leur noms en dur dans le script – ce qui obligerais à modifier lors de l’ajout ou la modification de serveurs cible – nous passerons par un fichier texte qui seras utilisé par le script. Chaque ligne du fichier contient le nom d’un serveur :

image

 

 

 

 

 

Afin de charger le contenu du fichier texte, il suffit d’en spécifier l’emplacement dans une variable :

image

 

Pour utiliser le fichier dans une boucle, il faut utiliser la commande “Get-Content” :

image

Récupérer les informations des VMs

La fonction “retrieve_virtualmachine_informations” permet pour une VM ($vmname_) et un hyperviseur ($server_) donné de récupérer les informations suivantes :

  • Nom de la VM,
  • Nom de l’hyperviseur,
  • Nombre de vcpu,
  • Informations de la RAM,
  • Nombre d’interfaces réseau,
  • Nombre de disques,
  • Temps d’activité de la VM,
  • Etat de la VM,
  • Délai de démarrage de la VM.

Voici la fonction :

image

Récupérer les informations des hyperviseurs

 

Informations générales :

Récupérer le temps d’activité de la machine :

image

Récupérer les informations de la commande “Systeminfo” et convertir au format CSV avec la fonction “Get-SystemInfo” :

image

Cette fonction seras ensuite utilisée pour récupérer le nom de la machine et son modèle :

image

RAM :

La fonction “Get-SystemInfo” est également utilisée pour récupérer les informations de mémoire disponible et maximum :

image

Disques :

Cette commande permet de récupérer tous les disques :

image

Une fois tous les disques récupérés, il faut pour chaque disque récupérer ses informations :

imagev

Créer les bornes d’avertissement

Afin de disposer d’un rendu visuel permettant de rapidement identifier un problème sur un serveur, il est possible (à l’aide de balises HTML) de colorier des cellules en fonction de la valeur contenue. Cela permet par exemple de rapidement identifier un serveur avec un faible stockage restant ou bien peu de RAM :

image

Tout d’abords, il faut créer les variables contenant la valeur des bornes :

image

Ensuite, lors de la génération du code HTML, il faut sous PowerShell, avec le switch “if” vérifier les trois différents cas (OK, Warninig et Critique), puis à l’aide de la balise HTML “bgcolor” préciser la couleur de la cellule :

image

Quelques commandes Powershell utiles pour Exchange

Contexte

Avec les cmdlets de base d’Exchange il est relativement simple d’obtenir certaines informations. Mais il est possible d’aller beaucoup plus loin dans le traitement de ces informations en combinant plusieurs cmdlet Exchange.

Les différentes commandes ci-dessous sont des cas concrets que j’ai eu à gérer au quotidien dans l’exploitation d’Exchange 2010.

Cmdlets

Rechercher un mail sur tous vos serveurs HUB à la fois :

Get-TransportServer SRV-EXCH-HUB-0* | Get-MessageTrackingLog -ResultSize Unlimited -Start "06/02/2014 19:00:00" -End "06/03/2014 01:00:00" –Sender “mon-adresse-mail@mon-domaine.fr”

Voir tous les droits sur une BAL :

Get-MailboxPermission login-bal | Where {$_.user -notlike "S-1-5*"} | Sort user | FT user,AccessRights,IsInherited –a

Voir les droits Send-As d’une BAL :

Get-Mailbox login-bal | Get-ADPermission | Where {($_.ExtendedRights -like “*Send-As*”) -and -not ($_.User -like “NT AUTHORITY\SELF”) -and ($_.User -notlike "S-1-5*")} | FT user,identity,IsInherited –a

Voir les statistiques des appareils ActiveSync d’un utilisateur :

Get-ActiveSyncDevice –mailbox login-bal | Get-ActiveSyncDeviceStatistics | Fl DeviceModel,DeviceType,FirstSyncTime,LastSyncAttemptTime,LastSuccessSync

Voir les BAL déconnectées d’un serveur :

Get-MailboxDatabase EXC-MDB-001 | Get-MailboxStatistics  | Where { $_.DisconnectDate -ne $null } | Select DisplayName,MailboxGuid,Database,DisconnectDate,DisconnectReason

Obtenir le top 5 de toutes les files d’attentes de vos HUB :

Get-TransportServer SRV-EXCH-HUB-0* | Get-Queue | Sort MessageCount -desc  | Select QueueIdentity,NextHopDomain,MessageCount,LastError -First 5

Voir les rôles Exchange d’un utilisateur :

Get-ManagementRoleAssignment -GetEffectiveUsers | ?{$_.EffectiveUserName -eq "Amaury AUSSIERE"} | Select Role

Voir d’un coup d’œil l’état de migration d’une liste d’utilisateurs d’un fichier CSV :

Import-Csv D:\MBXtoQuarantaine.csv -Delimiter ";" | %{Get-MoveRequestStatistics $_.samaccountname} | Group status | Select name,count

Obtenir la taille de plusieurs BAL (exemple : BAL de journalisation) avec un avertissement si dépassement d’un seuil :

Get-Mailbox BAL-Journalisation_* | Sort name | Get-MailboxStatistics | Select-Object DisplayName,@{Name="TotalSize(MB)"; Expression={$_.TotalItemSize.Value.tomb()}},@{Name="Warning?"; Expression={if($_.TotalItemSize.Value.tomb() -gt 500){"Warning!"}}}| ft –a

Vérifier les différentes URL d’un serveur CAS :

$monserveur = “SRV-EXCH-CAS-001”
Get-ClientAccessServer $monserveur | Get-ActiveSyncVirtualDirectory | fl server,*lur*
Get-ClientAccessServer $monserveur | Get-ClientAccessServer | fl server,*lur*
Get-ClientAccessServer $monserveur | Get-EcpVirtualDirectory | fl server,*lur*
Get-ClientAccessServer $monserveur | Get-OabVirtualDirectory | fl server,*lur*
Get-ClientAccessServer $monserveur | Get-OwaVirtualDirectory | fl server,*lur*
Get-ClientAccessServer $monserveur | Get-WebServicesVirtualDirectory | fl server,*lur*
Get-ClientAccessServer $monserveur | Get-AutodiscoverVirtualDirectory | fl server,*lur*

Vérifier les interfaces réseaux utilisées pour les réplications au travers d’un DAG :

Get-MailboxDatabase EXC-MDB-001 | Sort name | Get-MailboxDatabaseCopyStatus -ConnectionStatus | Select Name,MailboxServer,DatabaseName,OutgoingConnections,IncomingLogCopyingNetwork | Sort MailboxServer,DatabaseName

Conclusion

Au travers de ces quelques commandes Powershell, vous obtiendrez des informations pertinentes et rapidement sur l’état des serveurs Exchange.

Libre à vous de les adapter suivant vos besoins et votre environnement, le but étant de vous donner des idées pour votre administration au quotidien ou pour vos scripts.

Equilibrage des BAL sur les bases Exchange

Contexte

Dans un environnement de production avec Exchange, il peut arriver que l’ensemble des boites aux lettres utilisateurs ne soient pas bien réparties sur l’ensemble des bases. Afin d’éviter tout déséquilibre, il convient de rééquilibrer les bases. Mais ce travaille peut s’avérer fastidieux et long suivant votre organisation.

Je vais donc partager ici la solution mise en œuvre chez un client pour corriger cela très simplement.

Solution

Voici comment le script fonctionne pour répartir les BAL sur l’ensemble des bases :

  1. Récupération de toutes les BAL stockées sur les bases à répartir
  2. Calcul du nombre moyen de BAL par base
  3. Classement des bases suivant le nombre de BAL actuel
  4. Répartition des BAL suivant cette règle : Si le nombre de BAL dans une base est supérieur à la moyenne calculée, alors déplacement des BAL dans une base sous allouée, jusqu’à obtenir l’équilibre dans cette base. Cette règle est appliquée pour chaque base au dessus de la moyenne.
  5. A la fin du script, un fichier script PowerShell est généré avec les commandes New-MoveRequest qui vont bien.
  6. Il ne reste plus qu’a lancer ce script pour obtenir un équilibrage parfait.

 

Script

Le script ci dessous utilise le fichier “Source-DBBalanceScript.txt” qui doit être disponible dans le même dossier que le script. Voici le contenu de ce fichier :

Identity
EXCH-MBX-DAG1-DB01
EXCH-MBX-DAG1-DB02
EXCH-MBX-DAG1-DB03
EXCH-MBX-DAG1-DB04

A vous de mettre dans ce fichier les bases que vous voulez équilibrer. Les bases qui ne sont pas mises dans ce fichier, ne seront pas traités. Idéal si vous avez une ou deux bases de tests qui ne doivent pas être utiliser en production.

Conclusion

Avec ce script, l’ensemble de vos bases sont correctement réparties afin de corriger les dérives.

Attention, ce script ne prend en compte que le nombre de BAL par base Exchange. La volumétrie des BAL n’entre pas en compte dans le calcul de l’équilibrage. Il s’agit là d’un équilibrage sur le nombre de BAL et pas sur le volume.

Obtenir des statistiques sur les appareils ActiveSync connectés à votre serveur Exchange

Contexte

Si vous ne disposez pas de logiciel de reporting pour votre infrastructure Exchange et que vous n’avez pas spécialement changer les paramètres de base pour ActiveSync, sachez que chaque utilisateur peut synchroniser jusqu’a 10 appareils en même temps.

Suivant votre infrastructure, cela peut poser certains problèmes de performances ou de sécurité si ce protocole n’a pas été prise en compte lors du déploiement et que vous avez publié ActiveSync par la suite.

Script

Voici comment obtenir la liste de tous les périphériques enregistrés pour chaque compte utilisateur. Vous obtiendrez par exemple les modèles, date de synchronisation, etc., pour chaque appareil. Tout ce qu’il faut pour faire des statistiques avec votre tableur préféré.

Conclusion

Grâce à ce script, vous allez pouvoir obtenir l’ensemble des informations nécessaire pour connaitre tous les appareils ayant accès à vos serveurs Exchange.

Au vue des résultats de ce script, vous aurez probablement des questions sur les usages et performances ActiveSync sur vos serveurs. N’hésitez pas à nous contacter, nous pouvons vous aider à définir des stratégies et/ou revoir votre infrastructure dans le cadre d’une mode très tendance, je parle du BYOD !