Creare grafici con powershell e Microsoft Chart Control

Quasi tutti gli amministratori di Exchange si trovano ad avere a che fare con i file .csv. Abbiamo spesso l'esigenza di esportare una serie di dati dai nostri server Exchange e uno dei modi più comodi e più utilizzati consiste nell'utilizzo della commandlet Export-CSV, che permette appunto l'export dei dati di nostro interesse in un file "comma delimited".

In questo post vedremo come è possibile creare dei report, sfruttando powershell e i Microsoft Chart Control a partire appunto da una serie di dati contenuti in un file CSV.

Per prima cosa vediamo cosa sono i Microsoft Chart Control.

I Microsoft Chart Control per .NET Framework 3.5 non sono nient'altro che una libreria di .NET per la realizzazione di grafici in ASP.NET e  Windows Forms. Come abbiamo già visto in un altro post, ogni libreria .NET può anche essere sfruttata anche all'interno di powershell.

Quindi per prima cosa scarichiamo ed installiamo i Microsoft Chart Control. Ricordatevi che come prerequistito è necessaria la presenza di .NET Framework 3.5 (se per caso siete ancora su Exchange 2007).

Una volta installati, la prima operazione da fare è caricare la nostra libreria .NET

[void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms.DataVisualization")

Ok, ora è il momento di inizializzare il grafico:

$Chart = New-object System.Windows.Forms.DataVisualization.Charting.Chart
$Chart.Width = 700
$Chart.Height = 400
$Chart.Left = 40
$Chart.Top = 40

 Ora dobbiamo definire la area nella quale verra creato il grafico:

$ChartArea = New-Object System.Windows.Forms.DataVisualization.Charting.ChartArea
$Chart.ChartAreas.Add($ChartArea)

$Chart.ChartAreas["ChartArea1"].AxisX.Interval = 1 (questo serve per avere tutti i valori diponibili sull'asse X)

 Ok, ora il grafico è pronto in attesa di ricevere i nostri dati. Come abbiamo detto in precedenza, quello che vogliamo fare è prendere i dati di un file CSV e metterli in forma grafica.

Sicuramente una delle classiche esportazione riguarda la distribuzione delle caselle all'interno dei database di un nostro Exchange server

Avremo un file csv fatto nel seguente modo

 

NameDB MailboxNumber
MB_01 91
MB_02 80
MB_03 85

 

 

 

 

 

Per prima cosa importiamo i dati i una variabile

$data = import-Csv -Path <file.csv>

Creiamo lo spazio dove andare a mettere i valori che ci serviranno per creare il grafico.

[void]$Chart.Series.Add("Data")

e finalmente andiamo ad inserire i valori. I valori dovranno essere degli array, quindi utilizziamo il seguente modo per crearci due array ($xValue e $yValue) con i valori ricavati dal file csv e poi successivamente inseriamo i valori nel nostro grafico

$xValues = @(foreach($TempObj in $Data){$TempObj.NameDB})
$yValues = @(foreach($TempObj in $Data){$TempObj.MailboxNumber})

$Chart.Series["Data"].Points.DataBindXY($xValues, $yValues)

Il nostro grafico è pronto. Possiamo a questo punto aggiungere il titolo e nomi dei dati presenti sui due assi x e y

[void]$Chart.Titles.Add("Mailbox distribution per DB")
$ChartArea.AxisX.Title = "DB Name"
$ChartArea.AxisY.Title = "Number of Mailboxes"

Naturalmente possiamo gestire con completezza come il nostro grafico dovra essere: proviamo ad esempio a cambiare il Font e la dimensione del titolo

$titlefont = new-object system.drawing.font("Segoe UI Light",14,[system.drawing.fontstyle]::Regular)

$Chart.Titles["Title1"].Font = $titlefont

il font della label dei due assi

$ChartArea.AxisX.TitleFont = "Segoe UI Light"
$ChartArea.AxisY.TitleFont = "Segoe UI Light"

e il colore del nostro grafico.

$Chart.Series["Data"].Color = "Red"

Direi che siamo pronti per vedere il risultato, per visualizzarlo utilizziamo il metodo SaveImage

$chart.SaveImage(".\Mailboxdistribution.png","PNG")

Che produce il seguente risultato:

Naturalmente possiamo anche modificare il tipo di grafico (a questo link tutti quelli possibili). Poniamo ad esempio di voler visualizzare le dimensioni dei nostri database con l'informazione dello spazio libero disponibile per la creazione di nuove mailbox. In Exchange 2010 questa informazione è facilmente recuperabile sfruttando la commandlet Get-MailboxDatabase lanciata con il parametro -Status.

Avremo quindi un file CSV del tipo

Name DBSize AvailableSpace
MB_01 67 36
MB_02 70 34
MB_03 81 42

Per rappresentare informazioni di questo tipo possiamo utilizzare le Stacked Bar. Dopo aver importato il file CSV, andiamo a definire gli spazi dove metteremo I nostri valori e definiamo come il grafico ddi tipo "StackedBar". In questo caso avremo due serie di valori da inizializzare

[void]$Chart.Series.Add("Database Space")
$Chart.Series["Database Space"].ChartType = [System.Windows.Forms.DataVisualization.Charting.SeriesChartType]::StackedBar
[void]$Chart.Series.Add("Available New Space")
$Chart.Series["Available New Space"].ChartType = [System.Windows.Forms.DataVisualization.Charting.SeriesChartType]::StackedBar

Andiamo ad inserire le due serie di valori nel seguente modo:

$xValues = @(foreach($TempObj in $Data){$TempObj.Name})
$yValuesData1 = @(foreach($TempObj in $Data){$TempObj.DBSize - $TempObj.AvailableSpace})
$yValuesData2 = @(foreach($TempObj in $Data){$TempObj.AvailableSpace})
$Chart.Series["Database Space"].Points.DataBindXY($xValues, $yValuesData1)
$Chart.Series["Available New Space"].Points.DataBindXY($xValues, $yValuesData2)

Possiamo modificare I colori e il tipo di font, aggiungere I titoli nella stessa modalità vista in precedenza. Su un grafico di questo tipo potrebbe essere utile aggiungere anche una legenda.

$legend = New-object System.Windows.Forms.DataVisualization.Charting.Legend
[void]$Chart.Legends.Add($legend)

Ora possiamo salvare l'immagine ed ecco qua il nostro risultato.

Vediamo ora un ultimo esempio di come possiamo sfruttare i nostri Chart control. Poniamo ad esempio di aver un file csv che contenga i performance counter raccolti su un nostro Exchange Server

Il file CSV avrà la seguente struttura:

 

(PDH-CSV  4.0) (W. Europe Daylight Time)(-120) \\SERVER\Processor(0)\% Processor Time \\SERVER\Processor(1)\% Processor Time
10/25/12 7:01 AM    
10/25/12 7:01 AM 1.871161826 3.536126207
10/25/12 7:01 AM 26.60981527 7.898436728
10/25/12 7:02 AM 39.74910148 6.449813873
10/25/12 7:02 AM 42.09867862 5.091729946

 

 

 

 

 

 

 

L'idea è quella di rappresentare l'andamento di questi contatori su un grafico. Naturalmente sull'asse X avremo i dati della prima colonna (DateTime) e sull'asse Y avremo il valore del contatore. Scegliamo di rappresentare il contatore RPC Averaged Latency. La differenza rispetto ai grafici precedenti è che il tipo di dato in Asse X sarà di tipo DateTime. Per prima cosa configuriamo l'asse X in modo che sappia che la tipologia di valori sarà "DateTime" e formattiamo

$Chart.Series["Data"].xValueType = [System.Windows.Forms.DataVisualization.Charting.ChartValueType]::Datetime
$Chart.ChartAreas["ChartArea1"].axisX.LabelStyle.Format = "dd/MM/yyyy HH:mm"

 

Vediamo ora un metodo per trasformare i dati della prima Colonna in tipo DateTime.

$length = $data.length
$DateTime = @()
For ($i=0;$i -le ($length-1);$i++)
{
[DateTime]$temp = $data[$i]."(PDH-CSV 4.0) (W. Europe Daylight Time)(-120)"
$DateTime += $temp
}

$xValues = $DateTime

Così facendo avremo un array che conterrà valori di tipo DateTime, che potremmo utilizzare come valore dell'asse X per i nostri grafici. Per quanto riguarda i valori dell'asse Y creiamo il nostro array nella solita modalità

$yValues = @(foreach($TempObj in $Data){$TempObj." \\SERVER\MSExchangeIS\RPC Averaged Latency"})

Andiamo a caricare i nostri valori nel grafico nella solità modalità.

$Chart.Series["Data"].Points.DataBindXY($xValues, $yValues)

Come tipo di grafico, viene abbastanza natural pensare a un grafico a Linea. Andiamo quindi ad inizializzarlo nel solito modo

$Chart.Series["Data"].ChartType = [System.Windows.Forms.DataVisualization.Charting.SeriesChartType]::Line

A questo punto possiamo creare il nostro grafico di performance.

 

Nel prossimo post vedremo come sfruttare i Microsoft Chart control per creare dei report html. 

Claudio