Visualize your PowerShell reports with PowerShell charts
I am so excited to share with you PowerShell charts. It took me a lot of time and effort to generate charts as a result of running PowerShell script.
I think one of the most interesting things when writing PowerShell scripts, is to make the results shine by including visuals and charts. If you are going to show disk space info, nothing more than a nice chart, will worth looking at. If you are sending a report to your management, nothing will take their attention more than charts. I love getting charts as a high level output, and perhaps put some tables or attach a csv file for drilling down.
Why this is different than others?
Because this script is a wrapper around the dirty stuff that you do not want to worry about, or may be you are new to PowerShell and just what the chart to get generated. This script is so powerful that you can give it some data, choose the type of chart you want to generate, and guess what, you are done!
To make this happen, the machine in which you running your PowerShell scripts, should have two components:
Microsoft chart controls is the components that get invoked by this wrapper function, to generate the outcome chart. It is a light component, and there is no harm installing it.
Script details
This wrapper function wants some information from you. It needs an X-axis and Y-axis. I thought a lot of how I can feed the script those coordinates, and I realized it is best to construct the input outside the wrapper.
To do that, the wrapper will expect a parameter called DATA. This parameter expects an array of objects. Each object should have at least two properties that can represent an X-axis and Y-axis.
The wrapper function then expect a parameter called Obj_Key which is the name of the object property that should be mapped to the X-axis and Obj_Value to learn which object property to be considered Y-axis.
It might seem complex but believe me it is so easy. I will give you a simple example:
Suppose that you want to have a chart that represents 3 cities and their population. So you will have an excel sheet with two columns City_Name and City_Population
To create a chart for this type of input data, we need to create a PowerShell object per city, that has two properties:
- City_Name
- City_Population
#creating array that holds all objects $array_of_city_objects = @() #object properties or the X-axis and Y-axis in the chart $properties = @{ City_Name = "" City_Population = 0} #Creating London City object $city1 = New-Object -TypeName psobject -Property $properties $city1.City_Name = "London" $city1.City_Population = 15000000 #Creating London City object $city1 = New-Object -TypeName psobject -Property $properties $city1.City_Name = "London" $city1.City_Population = 15000000 #Creating Madrid City object $city1 = New-Object -TypeName psobject -Property $properties $city1.City_Name = "Madrid" $city1.City_Population = 600000 $array_of_city_objects+= $city1 #Creating Berlin City object $city1 = New-Object -TypeName psobject -Property $properties $city1.City_Name = "Berlin" $city1.City_Population = 5420000 $array_of_city_objects+= $city1 #Creating London City object $city1 = New-Object -TypeName psobject -Property $properties $city1.City_Name = "London" $city1.City_Population = 15000000 $array_of_city_objects+= $city1 #$array_of_city_objects now holds three objects, each object has two properties $city_name and $city_population Get-Corpchart-LightEdition -data $array_of_city_objects -obj_key "City_Name" -obj_value "City_Population" -FilePath C:\graph.png
Script features
There are new features that are added to the wrapper function script:
- Sortable data option via -sort parameter.
- Fix label alignment via -fix_label_alignment parameter.
- Exposing X and Y axis intervals via parameters.
- Show data as percentage via -show_percentage_pie parameter.
- Collected threshold to group data items below the threshold into one item called ‘Others‘.
- Customizing chart data column colors via -chart_color parameter.
- Dynamic dimension depending on the number of items in the input data.
You can download the script from Microsoft TechNet Gallery.
Examples
You can decide which PowerShell charts type to produce. There are alot of chart types available as part of the Microsoft Chart Controls for Microsoft .NET Framework 3.5. Specifying chart type as pie chart type can be accomplished by running this command:
PS C:\> Get-Corpchart-LightEdition -data $cities -obj_key "Name" -obj_value "Population" -filepath "c:\chart.png" -type Pie
You can also decide if you want to show the legend by using the -showlegend parameter.
PS C:\> Get-Corpchart-LightEdition -data $cities -obj_key "Name" -obj_value "Population" -filepath "c:\chart.png" -type Pie -showlegend
You can decide which PowerShell charts type to produce . For example, to use the SplineArea chart type instead of the pie chart:
PS C:\> Get-Corpchart-LightEdition -data $cities -obj_key "Name" -obj_value "Population" -filepath "c:\chart.png" -type SplineArea
You can decide which PowerShell charts type to produce. For example, here we will be specifying chart type as Bar chart type, and specifying the title for the chart using the -title parameter, and specifying the name of each axis on the chart by using the -chartarea_Xtitle and –chartarea_Ytitle parameters:
PS C:\> Get-Corpchart-LightEdition -data $cities -obj_key "Name" -obj_value "Population" -filepath "c:\chart.png" -type Bar -title_text "people per country" -chartarea_Xtitle "cities" -chartarea_Ytitle "population"
You can decide which PowerShell charts type to produce. For example, here we will be specifying chart type as Column chart type. Applying the -showHighLow switch to highlight the max and min values with different colors. This means that if you have like 12 cities with their populations, the lowest and highest cities will be highlighted.
PS C:\> Get-Corpchart-LightEdition -data $cities -obj_key "Name" -obj_value "Population" -filepath "c:\chart.png" -type Column -showHighLow
You can also include the percentage of the values, instead of the values themselves if you are working on the Pie or Doughnut chart types:
PS C:\> Get-Corpchart-LightEdition -data $cities -obj_key "Name" -obj_value "Population" -filepath "c:\chart.png" -type Doughnut -Show_percentage_pie
If the chart type is Pie or Doughnut, you can specify a threshold (percentage) that all data values below it, will be shown as one data item called (Others). Say for example you have like 100 cities with their population. There are almost 85 cities with population under 1 million. You want all those 85 cities to be represented as one city called Others, by setting 1 million as a threshold. The chart then will show 16 cities only instead of 100 cities, focusing thus on those with over 1 million population.
PS C:\> Get-Corpchart-LightEdition -data $cities -obj_key "Name" -obj_value "Population" -filepath "c:\chart.png" -type Doughnut -CollectedThreshold 1000000
You can color your chart columns if you are using the Column chart type. To color columns with green:
PS C:\> Get-Corpchart-LightEdition -data $cities -obj_key "Name" -obj_value "Population" -filepath "c:\chart.png" -chart_color Green
Hello Ammar,
thanks a lot for this function 🙂 .
however i have been trying to use your script, but it seems something is wrong
here is an example:
Missing expression after ‘,’.
At C:Userswhkc4736DesktopGet-CorpChart_v2.ps1:240 char:33
+ [Parameter(Position = 2, <<<< `
+ CategoryInfo : ParserError: (,:String) [], ParseException
+ FullyQualifiedErrorId : MissingExpressionAfterToken
could you please advice?
thanks alot
Hi
Can you please email me on me@ammarhasayen.com with the full command you are using as the error indicates something about position 2 parameter.
Also have you installed the chart controls prereq as mentioned in the blog post?
Hello Ammar,
thanks for your reply
i was trying to load the function [copy/past into the power-shell console] that’s where the error came up
am i doing something wrong?
and yes MScharts control is installed
thanks for your help
Let me trace this with you tomorrow and get back
ok thanks alot
Hello ammar,
do you have any news ? 🙂
I sent you an email. pls check it
i have sent the reply, plz check it
thanks alot, Ammar for your help
now it’s working fine 🙂
Thanks for the wrapper Ammar, I’m looking into using it to display data received from my arduino weather station. Nice work!
Glad u liked it. Pls tell me if you need any help
Hey Ammar, technet scriptcenter was shutdown. do you still have a copy of this by chance? Thank u
Hi Ammar,
Looks like I’ve got it working fine! I’ve got some nice graphs of my greenhouse, telling me about temperature, light (IR & LUX), Humidity, air pressure (millibar), battery levels, solar input (voltage). All thanks to your graphs script!
I noticed that I needed to make a few small modifications to run it on Windows 7 (ran fine on win8.1).
It compains about line 615 (color) and I had to comment out line 207. Also some errors reported where you used ` to go to a new line, which seemed fine to me, but ISE complained about some spaces being used there, not sure why. As I said: it’s minor.
Anyhow, that’s not what I’m writing, just thought I’d mention it, as you may want to fine tune you source.
My question: I’d like to ask if the following to options are possible somehow:
1. I’d like to put emphasis on a certain area in the graph; for example, I’m using millibar in a line graph, which is a value typically somewhere between 900 and 1100. Righ now the Y value of the graph goes from 0 – 1100.. I’d like it to have a MIN (900) and MAX (1100). Is that possible?
2. I’m setting time (X axis) against a certain value (humidity, temperature, dewpoint)
As dewpoint and temperature are both in Celcius on the Y axis, would it be possible to show both lines somehow? And to take that a bit further (but I guess that’s is quite a bit harder) could I somehow add humidity (a percentage) also? (for example with it’s scale from 0 to 10% o the right)… I know I know that last one is a tough one 😉
————————–
note related to the above, but since I’m rambing now anyway…
By the way, I found that hashvalues & date/time do’n sort well. For thise who may find it useful; this how I ended up fixing that:
First simply fill a $hashtable with data staring with a time field. For example:
DateTime;BatteryVolume;Temp;Humidity%;milliBar;LightFull;LightIR;LightLux
18-04-2014 18:01;099;21.00;72.10;1017;2959;1338;856
Now use the following:
[code]
$template = ‘dd-MM-yyyy HH:mm’
$mytable = $HashTable.GetEnumerator() | Sort-Object {[DateTime]::ParseExact($_.Name, $template, $null)}
[/code]
Now use $mytable in Get-Corpchart, Corpchart may complain it’s not a hashtable, simply use -obj_key ‘Name’ -obj_value ‘Value’ to make it work.
Ya i can understand your comment. I spent long time trying to draw in powershell and finally i got it working for me with lots of tweaks. What i tried to do here is to build a wrapper as perfect as possible.
When you want to input data, the most logical way to do it is by using hash tables as they are key pairs. The problem is that only PowerSehll 3.0 i guess where they introduced sorted hashtable. Not everyone has this version, that is why i came out with an object input with two properties of your own selections. you can sort an array of objects and input them to the function to get a sorted data.
After all, to get professional graphs, some sort of skills is required to do your own tweaking. My script aims to give you the starting point and all my experience so you can reverse engineer it and tweak it the way you like.
I use graphs as much as i can in my scripts as people especially management people would like to see nice graphs instead of long raw data.
I am preparing my next version of Exchange Dashbord with this new function as now graphs will expand automatically depending on the number of input pairs. This is HUGE step as i got so many feedback from people asking about so crowded graphs on my previous Exchange report.
I am glad you took the time to go through the code and figure your own way
Regarding your request about emphasis, im only using .NET to do the graphing. The options that is available is to emphasis high and low only.
If you go through the .NET library, or ask a true developer who deals with the charts library, you will certainly get his input as it is large area.
And if this is an option, well, you can easily integrate it with my code and it will reflect your new chart needs. You can do magic with that library, just browse the documentation or ask a dev person and he may help. For my case, i did not need that.
Other option that i will go for here is to leave bring the data using PowerShell or any other means and send them to native .NET code where a developer can take that array of object data and use it to do the graphs in native .NET using any framework he liked. I did one time such integration where i pulled the data using PowerShell to a SQL DB, and then a .NET code inspect the data from SQL and view it in ASP page for nice GUI web interface.
Again, with PowerShell , you will not get the full features since in the background it uses .NET to do the GUI part.
Hi Ammar,
I am trying to run the below code, however values (multiple values) stored in $aDomain or $Domain1.DomainNames variable are not showing in chart, it comes as empty chart
Is it possible to call multiple value stored in variable like here in $aDomain
$aDomain=Get-MsolDomain | select name
$aCapabilities=Get-MsolDomain | select capabilities
#creating array that holds all objects
$array_of_Domains = @()
#object properties or the X-axis and Y-axis in the chart
$Domainproperties = @{ DomainNames = “”
Domain_capabilites = 0}
#Creating Domain object
$Domain1 = New-Object -TypeName psobject -Property $Domainproperties
$Domain1.DomainNames = $aDomain
$Domain1.Domain_capabilites = $acapabilities
$array_of_Domains+= $Domain1
#$array_of_city_objects now holds three objects, each object has two properties $city_name and $city_population
C:\Get-Corpchart-LightEdition.ps1 -data $array_of_Domains -obj_key “DomainNames” -obj_value “Domain_capabilites” -FilePath C:\graph1.png -showlegend
Thanks in advance for your assistance.
Well, it should work, let me try to run this and see. If you can meet me online and share your screen, It will be better.
Hi Ammar,
Thank you very much. Please let me know your preferred time, I will be available and give you a call as well, if required.
Thank you again for your guidance.
Regards,
Gautam