PowerShell étant basé sur le Framework .NET il est possible d’utiliser Microsft Chart Controls directement en important les assemblies adaptées. L’objectif étant lors d’automatisation de tâches de pouvoir grapher les résultats les rendant ainsi beaucoup plus lisibles.
Le but étant de pouvoir générer des graphs de ce type



Ce dont on a besoin :
- PowerShell V1 (ou supérieur)
- Framework .NET 3.5
- Microsoft Chart Controls
Première étape, on importe les assemblies
[void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms.DataVisualization")
Pour générer notre graph nous allons simuler un traitement par lot ayant retourné des codes retours de 3 types: OK, ERROR, UNKNOW
$nbError = random(1..10)
$nbOK = random(1..3)
$nbUnknow = random(1..10)
$labelError = "Erreur ("+$nbError.toString()+")"
$labelOK = "OK ("+$nbOK.toString()+")"
$labelUnknow = "Unknow ("+$nbUnknow.toString()+")"
Nous créons une liste contenant nos labels ainsi que le nombre qui lui est associé en fonction de son type
$resultList = @{$labelError=$nbError.toString();
$labelOK=$nbOK.toString();
$labelUnknow=$nbUnknow.toString(); }
Nous créons maintenant l’objet graph et définissons sa taille
$Chart = New-object System.Windows.Forms.DataVisualization.Charting.Chart $Chart.Width = 500 $Chart.Height = 400 $Chart.Left = 50 $Chart.Top = 30
On crée ensuite un chartarea dans lequel on ajoutera le graph
$ChartArea = New-Object System.Windows.Forms.DataVisualization.Charting.ChartArea $Chart.ChartAreas.Add($ChartArea)
On ajoute les données du graph à partir de la liste
[void]$Chart.Series.Add("Data")
$Chart.Series["Data"].Points.DataBindXY($resultList.Keys, $resultList.Values)
On définit le type de graph
$Chart.Series["Data"].ChartType = [System.Windows.Forms.DataVisualization.Charting.SeriesChartType]::Pie
On définit ensuite les couleurs pour les données du  graph. Par exemple ici, nous définissons que la valeur minimum sera en rouge (et max en bleu) en utilisant la méthode FindMinByValue FindMaxByValue)
$maxValuePoint = $Chart.Series["Data"].Points.FindMaxByValue() $maxValuePoint.Color = [System.Drawing.Color]::lightblue $minValuePoint = $Chart.Series["Data"].Points.FindMinByValue() $minValuePoint.Color = [System.Drawing.Color]::Red
On définit les options du graph
$Chart.Series["Data"]["PieLabelStyle"] = "Outside" $Chart.Series["Data"]["PieLineColor"] = "Black" $Chart.Series["Data"]["PieDrawingStyle"] = "Concave" ($Chart.Series["Data"].Points.FindMaxByValue())["Exploded"] = $true
Pour afficher le graph, il est nécessaire de créer un objet de type Windows.Form.Form dans lequel on ajoutera l’objet graph
$Form = New-Object Windows.Forms.Form
$Form.Text = "Powershell/MSChart"
$Form.Width = 600
$Form.Height = 500
$Form.controls.add($Chart)
$Form.Add_Shown({$Form.Activate()})
$Form.ShowDialog()
Et voila le résultat

Pour plus d’informations sur MSChart je viens invite a visiter cette page ou vous pourrez aussi trouver des samples (vbs/C#)
Appeler des fonctions PowerShell depuis du WPF
De la même façon, il est possible d’utiliser du WPF depuis PowerShell en important les assemblies adaptées. Dans cet exemple nous allons créer un mini Task-Manager permettant d’afficher les ressources utilisées par un processus.
On importe l’assembly
[Reflection.Assembly]::LoadWithPartialName("PresentationFramework")
Il est nécessaire de créer une interface en XAML pour notre interface, Expression blend est parfait pour faire ça

On stocke le code XAML généré par blend
$xaml = [xml]' Selectionner un process '
On récupère la liste des processus en cours d’exécution. Pour simplifier la suite du code, je fais fi des doublons en utilisant le pipe unique
$Processes = Get-Process | unique | Sort-Object -Property WS | Select-Object Name,WS,ID
$ProcNames = @(foreach($Proc in $Processes){$Proc.Name})
On utilise le code XAML pour créer notre fenêtre
$XAML=(New-Object System.Xml.XmlNodeReader $xaml) $XAMLR=[Windows.Markup.XamlReader]::Load($XAML)
On bind nos variables
$PR = $Form.FindName('ComBoxProcess')
$OU = $Form.FindName('TextBoxProcess')
On itére sur les processus pour les ajouter à notre liste
foreach ($row in $ProcNames) {
[void]$PR.Items.Add($row)
}
On utilise la méthode add_SelectionChanged pour que lorsque qu’un processus différent est sélectionné, le TextForm soit actualisé avec les bonnes données.
$PR.add_SelectionChanged({
$OU.clear()
$Proc = Get-Process -Name $PR.SelectedItem | unique
$disp = (($Proc.WS)/1MB).tostring()
$disp +=" MB"+[environment]::NewLine
$disp += ($Proc.Handles).tostring()
$disp +=" Handles"+[environment]::NewLine
$OU.AppendText($disp)
})
Et enfin, on affiche !
[void]$XAMLR.ShowDialog()
Et voila le résultat

Voila pour cette introduction aux interfaces et au graph au travers de Powershell, dans un prochain billet, je reviendrais plus en détail sur les synergies .NET/Powershell




Bonjour,
Merci pour cette présentation intéressante.
J’aimerais juste ajouter quelques précisions:
- l’alias « random » (Get-Random) n’est pas disponible avec Powershell v1, il faut passer par l’assemblage System.Random du Framework .Net
- les exemples WPF ne peuvent pas fonctionner avec Powershell v1 : il faut utiliser le mode STA (Single Threaded Apartment) de Powershell v2
Bonne continuation.