Charts and PowerShell !! PowerShell Wrapper “Light Edition”

Check Out the Light Edition of this PowerShell Wrapper : Get-CorpCharts-FullEdition

I think one of the most interesting things when writing PowerShell scripts, is to make the results appear in a nice chart or couple of them. 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, with more tables and data for extra details.

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.

You can just give it some data, and charts will start decorating your screen , ready to be emailed maybe to someone else to look at the data in a nice way.

The script

The script is FULL with examples and information of how to use it. Do not panic if you find the code long or complex for you. Just look at the examples and you will find your way.

Do not forget that you need to install two things before running the script on your machine :

So how the script works?

You have to enter a parameter called (-data) that is essentially an array of objects.

Suppose you have an object called (City) with two properties : City_Name, and City_Population

and let us say you have ten of those objects and they are stored in an array called $Cities

So now, all what you have to do is to give the $Cities array to the function as -Data parameter, and supply the -Obj_Key parameter as “City_Name”, and -Obj_Value as “City_Population”

So the command will be : Get-CorpCharts-LightEdition -data $Cities  -Obj_Key  City_Name  -Obj_Value City_Population -FilePath C:\graph.png

Charts_PowerShell

Download version 2

You can download version 2 of the script from here: Get-CorpCharts

New in Version 2

  • 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.

Charts with PowerShell 1

Charts with PowerShell 2

Charts with PowerShell 3

Charts with PowerShell 4Charts with PowerShell 5

Charts with PowerShell 6

 Examples

.EXAMPLE   

Chart by supplying array of objects as input. We are interested in the Name and Population properties of the input objects. In this case, we should also use the -obj_key and -obj_value parameters to tell the function which properties to draw. Default chart type ‘column’ is used.

PS C:\> Get-Corpchart-LightEdition -data $array_of_city_objects  -obj_key “Name” -obj_value “Population”

-filepath “c:\chart.png”

.EXAMPLE 

Specifying chart type as pie chart type.

PS C:\> Get-Corpchart-LightEdition -data  $cities  -obj_key “Name” -obj_value “Population”

-filepath “c:\chart.png” -type Pie

.EXAMPLE

Specifying chart type as pie chart type. legend is shown.

PS C:\> Get-Corpchart-LightEdition -data $cities -obj_key “Name” -obj_value “Population”

-filepath “c:\chart.png” -type Pie -showlegend

.EXAMPLE 

Specifying chart type as SplineArea chart type.

PS C:\> Get-Corpchart-LightEdition -data $cities -obj_key “Name” -obj_value “Population”

-filepath “c:\chart.png” -type SplineArea

.EXAMPLE   

Specifying chart type as bar chart type, and specifying the title for the chart and x/y axis.

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”

.EXAMPLE  

Specifying chart type as column chart type. Applying the -showHighLow switch to highlight the max and min values with different colors.

PS C:\> Get-Corpchart-LightEdition -data $cities -obj_key “Name” -obj_value “Population”

-filepath “c:\chart.png” -type Column -showHighLow

 .EXAMPLE 

Chart with percentages shown on the pie/doughnut charts.

PS C:\> Get-Corpchart-LightEdition -data $cities -obj_key “Name” -obj_value “Population”

-filepath “c:\chart.png” -type Doughnut -Show_percentage_pie

.EXAMPLE  

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).

PS C:\> Get-Corpchart-LightEdition -data $cities -obj_key “Name” -obj_value “Population”

 -filepath “c:\chart.png” -type Doughnut  -CollectedThreshold 16

.EXAMPLE 

Column chart with green columns.

PS C:\> Get-Corpchart-LightEdition -data $cities -obj_key “Name” -obj_value “Population”

-filepath “c:\chart.png” -chart_color Green

Get Server Up Time in a smart way (WMI)

This function will take a server name or array of server names, and return Server Up Time in form of TimeSpan data type.

Why this is different ?

What makes this script different than other scripts is two things:

– Faster : Instead of getting all WMI data from Win_OperatingSystem name space, we will only get the server up time property, so less data transfer the wire

– Returns object with two properties : ComputerName, and UpTime.

– Better error handling : Even if there is trouble getting WMI data from the remote computer, the uptime property will be replaced with “n/a” instead of throwing exception.

– Returns TimeSpan : So the UpTime property will be TimeSpan, so you can browse its properties and get uptime in days, minutes, seconds, or even more accurate information.

– Flexible Input Data: Can take input from the pipeline in form of single server or array of server names.

Download the script

You can download the script from here  Get-CorpUpTime

Get-CorpUpTime_34534

Get WMI data the right way – Get Disk info using WMI

You can find many scripts out there digging and getting WMI data, especially disk space stuff.  I was searching online for a PowerShell function to get disk space information, and there are two interesting things (not problems for sure), but things that I didn’t like and I will share with you what I think.

First point is that most scripts out there, will deal with errors and timeouts in different ways. Most of the time they will either throw exception, write something in the screen or in a verbose stream, or in best case scenarios, they will write the name of that computer in an error log file.

Get-CorpDiskInfo_444334

The below figure shows my own point of view of how I think the first point should be handled. If I requested WMI Disk information about a computer, I expect an object back representing information about this computer.

  • I do not care if the computer is reachable or if there is problem querying wmi data.
  • I do not want to see or handle exceptions.
  • I do not want to look at log files.
  • JUST GIVE ME AN OBJECT BACK SIMPLY. Leave the technical stuff for yourself dear script and shut up.

Get-CorpDiskInfo2322

So, an object should be returned silently. If the remote computer is not reachable, then I will still get an object with “n/a” for the disk information property.

It is the calling function job then to receive that object and investigate the fields. This level of abstraction allows the calling function to deal with all results coming back from the WMI function in the same way. The calling function should always receive an object silently.

The second interesting thing is that most of those scripts online will throw disk info objects on the pipeline, with a computername property for you to distinguish. So you will receive an object for each disk (not computer). Something like the below figure.

Get-CorpDiskInfo464

Well, all what I wanted is information about two machines, so I expect two objects in return ,an object per computer, not an object per disk. Why shall I do some house cleaning on behalf of such scripts?

The answer to this issue is to return an object per computer. This object will contain two properties:

  • ComputerName
  • Child Object : containing disk information

Get-CorpDiskInfo4634

The Script

Taking into consideration the above points, the script will get the following information:

  • ComputerName
  • Child object called (Disks)  with the following properties:
    • Drive
    • VolumeName
    • Size in GB
    • Free space in GB
    • Free space percentage

As you can see from the below figure, we will get one object back, containing child object for the disks.

Get-CorpDiskInfo

Same thing when we query two computers, we will get two object back .In case of error when doing the WMI query, the child object called (disks) will be replaced by the string “n/a”

Get-CorpDisks_123

Download the script

You can download the script from here : Get-CorpDisks

The script is using (Get-WmiObject) to get disk info. I recommend that you replace the Get-WmiObject  with (Get-CorpCimInfo). This way, the script will try to use Get-CimSession, then remoting then DCOM to retrieve wmi data. Have a look to my Get-CorpCimInfo script here.

Windows 8.1 AD Based Activation “Invalid product key or license mismatch” error

I was trying to add Windows 8.1 Key to Active Directory that day using Volume Activation Management Tool (VAMT) to enable AD based activation,  and i get the “Invalid product key or license mismatch”error when trying to add the Windows 8.1 KMS key using AD based activation.

Doing a quick search, i found this hot fix from Microsoft http://support.microsoft.com/kb/2885698/en-us under the title of (Update adds support for Windows 8.1 and Windows Server 2012 R2 clients to Windows Server 2008, Windows 7, Windows Server 2008 R2, Windows 8, and Windows Server 2012 KMS hosts). Installing the fix on the server where VAMT is installed solves the issue and saves the day!

PowerShell – script to get WMI data, try CIM, then remoting then RPC

Get-CorpCimInfo

There are many scripts to get WMI data in the internet, but this script will use a unique technique. It will try getting remote data using many methods, preferring new ones and falling back to old legacy ones.

What is unique about this script is the amount of customization you can do with it. You can customize it completely just by adding one the script parameters and you are done.

If you run the script using -verbose mode, you will be presented with the right information for you to discover the power and logic of the script. Running the script by its own will not do anything as it is a wrapper function for you to use in other places where you need to get WMI data.

The script will basically get computer name or names, try to collect WMI information from them.

The script is smart enough to test if the remote computer is running PowerShell 3.0 at least and supports WS-MAN 3.0. If this is the case, the script will try to get WMI information by creating CIM session (Get-CIMSession).

If the script cannot connect to remote computer using CIM Session, then PowerShell remoting will be tried. If this fails too, the script will try to fall back to RPC call to get WMI data.

Get-CorpCIMInfo_232

Version 2 of the script

After a quick chat with Jeffery Hicks (@JeffHicks) who i based my script upon his own version, Jeff suggested couple of modifications on my version of the script, specifically the concept of always returning objects instead of strings or other types. After tweaking the script to do that and add more verbose and exception additional information, i came with version 2 of the script.

Download Get-CorpCimInfo_v3  

PowerShell Tools for Visual Studio

 

I love Visual Studio, and i love writing code. I have come across PowerShell Tools for Visual Studio this morning, and i tried it out. The tool simply allows you to write your PowerShell Scripts from within Visual Studio (2012) or (2013).

I was so excited to try it out. So i downloaded the tools which is still in beta from the below link:

(http://visualstudiogallery.msdn.microsoft.com/c9eb3ba8-0c59-4944-9a62-6eee37294597

PowerShell Tools for Visual Studio

 

If you are familiar with Visual Studio, you are going to love it. Nevertheless, i guess since the tool is still in beta, it needs some time to mature. I got couple of termination errors and it is hard to evaluate complex variables when in debug mode. For example, if i have an array variable, i cannot get its content in debug mode, which leaves me to get back to my ISE environment for now.

After all, great work from Adam Driscoll Indeed !

PowerShell Tools for Visual Studio3

PowerShell ISE Extension – Make your script environment more intelligent

If you are working on PowerShell ISE alot, and you find your self searching for functions and variables, looking into a big script block about occurrences and calls to those items, then this PowerShell Module/Extension is something you should look at. This tools is created by PowerShell MVP Doug Finke and it is called “PSharp”

You can download it from here https://github.com/dfinke/PSharp

PSharp

Active Directory AutoRecovery from Dirty Shutdown

The Problem

I found couple of events in a Windows 2012 Domain Controller that indicates a problem in the DFS replication. The event looks like this :

AD AutoRecovery 

It turned out that Microsoft had published a hotfix  http://support.microsoft.com/kb/2663685 that will disable the ability to AutoRecovery after dirty shutdown. I am sure that the domain admin will not always updated if one of his domain controllers suffered a power failure, which will cause DFS to be broken and SYSVOL to stop replication. 

The bad news, is that Microsoft made this the default behavior for Windows 2012 !

How to solve this

Find out what drive holds your DFS folders, if it is the C drive, then type the following to know what is the volume ID :

Mountvol C:   /L

Then :

wmic /namespace:\\root\microsoftdfs path dfsrVolumeConfig where volumeGuid=”{Volume-ID}” call ResumeReplication   

(do not include the “{” and “}” when replacing the volume-id

Finally, run :

wmic /namespace:\\root\microsoftdfs path dfsrmachineconfig set StopReplicationOnAutoRecovery=FALSE