Generating Graphical Charts with VMware PowerCLI & PowerShell

Charts are awesome – they can help make sense of endless reams of text and data and they generally look pretty. So my question to myself was: “How do I get useful data I generate using PowerCLI into a nice, neat little chart?” I had a quick google and found a couple of different solutions. The one that stood out as being the easiest to start off with for me was to use the “Microsoft Chart Controls for Microsoft .NET Framework 3.5

I read a few blog posts around detailing how to create these custom .NET charts in PowerShell, but this tends to be quite a tedious process – akin to creating a Windows Forms GUI in PowerShell manually – basically a complete pain. The blog posts I read definitely helped me understand how to create charts and soon I was able to generate some pretty cool charts based off data from PowerCLI (or PowerShell) data. I wanted to ultimately automate the creation of Charts for my PowerCLI and PowerShell scripts, so I decided to create myself a Function that could be used anywhere to generate a Bar or Pie Chart on the fly.

httpv://youtube.com/watch?v=EvQ2znWr0lk

Enter Create-Chart. This is the Function I have made that accepts a bunch of Parameters to create a custom Chart and outputs this to a .PNG file. The data needs to be fed in to the function via a Hash Table (this could be changed) so I also created a “helper” Function called Create-HashTable which also does the work of generating a hash table for use with the Create-Chart Function. You could of course also just feed the Create-Chart function with a manually created HashTable too – this is useful to know because my Create-HashTable function is fairly basic and is not too flexible. Here are a couple of examples of Charts I created using these Functions:

Pie Chart of VMs and their configured Memory Resource settings
The same data but now in a Bar chart
Host Chart created with a manually created Hash Table (Name and MemoryUsageMB Properties)

Download the two functions below to give them a try! Please do suggest any improvements – my parameter handling on the Create-Chart script needs work – they are not specified as mandatory, although all parameters are mandatory – I couldn’t get the Function to work correctly when I did make them mandatory. The Create-HashTable function could also be improved in that at the moment you can only specify Cmdlets for the “Cmdlet” parameter that do not have any double quotation marks inside the cmdlet or any $_ variables. This is because of the way I am using the Invoke-Expression cmdlet inside the function. A simple cmdlet parameter such as “Get-VM | Select Name, MemoryMB” would work just fine for example. Remember that the Create-Chart function needs to be fed with a Hash Table. This could be generated yourself, or by using the Create-HashTable function below. Here are the downloads:

Don’t forget the Microsoft Chart Controls – a requirement to run these functions
Download the functions here:

https://www.shogan.co.uk/wp-content/uploads/Create-Chart.zip

https://www.shogan.co.uk/wp-content/uploads/Create-HashTable.zip

Once you have the Functions loaded, here are some examples to show you how to use them:

Pie Chart of VMs and their MemoryMB setting:

Create-Chart -ChartType Pie -ChartTitle "Sean's Awesome VM Chart" -FileName seanchart3 -XAxisName "VMs" -YAxisName "MemoryMB" -ChartWidth 750 -ChartHeight 650 -DataHashTable (Create-HashTable -Cmdlet "Get-VM" -NameProperty Name -ValueProperty MemoryMB)

Bar Chart of ESXi Hosts and their Memory Usage (MB) values:

Create-Chart -ChartType Bar -ChartTitle "Sean's Awesome Host Chart" -FileName seanchart4 -XAxisName "VM Hosts" -YAxisName "Memory Usage (MB)" -ChartWidth 750 -ChartHeight 650 -DataHashTable (Create-HashTable -Cmdlet "Get-VMHost" -NameProperty Name -ValueProperty MemoryUsageMB)

Use your own Hash Table to input the data:

Create-Chart -ChartType Bar -ChartTitle "Custom Chart" -FileName seanchart5 -XAxisName "My Objects" -YAxisName "My Object Values" -ChartWidth 750 -ChartHeight 650 -DataHashTable $HashTable

So there you have it – a fairly easy way to Chart the data you can get from your PowerCLI or PowerShell cmdlets! I wrote these Functions as part of a larger report that I am working on for another soon to come blog post! As I mentioned above, there is plenty of room for improvement – so if you do make any improvements or changes, please be sure to post them in the comments section.

Something different – 100th post

 

For my 100th post, I thought I would put something totally different up. Introducing PowerCLI bot!

 

PowerCLI Bot

 

I recently purchased a Wacom Bamboo tablet and have been doodling around with it – last night I decided to create a little bot for a custom 404 error page I would like to set up for Shogan.tech. I was looking at the PowerCLI logo at the time and thought I quite liked the colour combination. Anyway, things progressed and I thought I would create a little “PowerCLI Bot” as I have recently been thoroughly enjoying working with PowerCLI and PowerShell.

 

I’ll be changing him a bit for my custom 404 error page so keep an eye open for his distant cousin 🙂

 

ESXi 5.0 / ESXi 5.1 Host Backup & Restore GUI Utility (PowerCLI based)

 

This is a little bit of  a fun project I have been working on in bits of spare time I find. It is all written in PowerCLI 5.0 / 5.1 / PowerShell and the GUI was laid out using Primal Forms Community Edition.

 

Updates (17-02-2013) – version 1.3:

  • Hosts are retrieved using a new method (for both backup and restore options)

Updates (29-12-2012) – version 1.2:

  • Added ESX/ESXi host validation into utility – will now test that the host is valid and either connected or in maintenance mode before attempting backup or restore (See the script’s new “Check-VMHost” function for those interested)
  • Minor UI improvements

Updates (29-10-2012) – version 1.1:

  • This utility has been tested on ESXi 5.1 Hosts and confirmed to be able to successfully create a backup archive file of these.
  • Be sure your DNS is working correctly on the system you run the Backup utility on – it relies on DNS to find your ESXi hosts as they are named in the dropdown when you select the host to backup. (See comments for troubleshooting)
  • Restore to new hardware (force restore) option added
  • Fixed labels and connection box label description

 

What it is essentially, is a GUI that allows you to Backup ESXi 5.0 or ESXi 5.1 hosts to a destination of your choice on a local drive. It also allows you to restore ESXi Host configuration bundle backups taken, to other Hosts. I had other plans to integrate cloud storage options in (Amazon S3) as a backup target, but I thought that this doesn’t really offer anything valuable and I would just keep it relatively simple for now – therefore I have disabled this functionality. The PowerCLI script is fairly long – and I know there are plenty improvements I could make to better it and shorten the code, but for now it does the job. I have added various catches for exceptions / errors so you should get visual feedback if you have entered an invalid path, or username for example.

 

Anyway, hopefully this proves useful to some! As always, take care using the backup / restore functionality of this utility. The restore functionality works by first putting the ESXi host into Maintenance mode (if it isn’t already in this mode) and then applying a backup bundle to the host (Restore). The Host will reboot immediately following this. The Backup and Restore is implemented using Get-VMHostFirmware and Set-VMHostFirmware cmdlets so you can read the help descriptions for an idea on how exactly these work. The Host Backup Bundles are stored in a path of your choice and when restoring from a path the cmdlet works by looking for a bundle filename that matches the name of your ESXi host selected to restore to. Note that the file browser module I have implemented here (used to select paths) is a modification of the work done by Ravikanth Chaganti on his PowerShell Help Browser GUI. I simply adapted his code to list the contents of local drives in a tree view instead of PowerShell Help cmdlets. The only limitation here is that I have not implemented code to browse further than one level into the root of each drive. If you can provide this modification yourself, please feel free to contribute in the comments! I have just not spent the extra time to do this myself yet.

 

Here are a couple of quick screenshots of the Utility / GUI:

 

 

ESXi 5.0 Host Backup & Restore GUI Utility & Path Browser

 

Current version (1.3):

(Version 1.3) [download id=”25″]

 

Previous versions:

(Version 1.2) [download id=”21″]

(Version 1.1) [download id=”20″]

(Version 1.0) [download id=”9″]

 

Enjoy!

 

PowerCLI – Fetch Interesting stats or configuration for a list of VMs

Now and then I find that I need to retrieve some useful information from a variety of VMs, this usually involves me doing a Get-VM with some selections and criteria to search for. However sometimes the information I require about a VM is listed in the advanced configuration and not as easy to get to with a single cmdlet. I thought it would be really handy to have a PowerCLI function that would easily pull the useful information out for me and summarise it for any given VM or set of VMs.

 

With that said, I recently read a great blog post by Jonathan Medd (Basic VMware Cluster Compatibility Check), and after reading it I thought it would be a great idea to create a set of functions that provide me with the information I often use. To start, I thought I would do a function that lists the most useful or common information about VMs that I often search for. As well as speeding up the process of retrieving information about VMs, I thought it would also be good PS/PowerCLI practise for me to write more functions. The reason being that I often tend to do PowerCLI reporting scripts rather than actual functions that accept input from the pipeline or other parameters. Below is my function to collect some useful information about Virtual Machines – you can specify a VM with the -VM parameter or pipe a list of VMs to it, using Get-VM | Get-VMUsefulStats. Jonathan’s post also had an interesting section about the order in which output is displayed. You’ll need to pipe the output to Select-Object to change the order the information is fed back in, otherwise it will list the information in the default order. This is not really a problem anyway, just good to know if you are fussy about the order in which the output comes back in!)

 

So, here is the first function (Get-VMUsefulStats):

 

[download id=”7″]

 

function Get-VMUsefulStats {
<#
.SYNOPSIS
Fetches interesting or useful stats about VMware Virtual Machines

.DESCRIPTION
Fetches interesting or useful stats about VMware Virtual Machines

.PARAMETER VM
The Name of the Virtual Machine to fetch information about

.EXAMPLE
PS F:\> Get-VMUsefulStats -VM FS01

.EXAMPLE
PS F:\> Get-VM | Get-VMUsefulStats

.EXAMPLE
PS F:\> Get-VM | Get-VMUsefulStats | Where {$_.Name -match "FS"}

.LINK
http://www.shogan.co.uk

.NOTES
Created by: Sean Duffy
Date: 18/01/2012
#>

[CmdletBinding()]
param(
[Parameter(Position=0,Mandatory=$true,HelpMessage="Name of the VM to fetch stats about",
ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
[System.String]
$VMName
)

process {

$VM = Get-VM $VMName

$VMHardwareVersion = $VM.Version
$VMGuestOS = $VM.OSName
$VMvCPUCount = $VM.NumCpu
$VMMemShare = ($VM.ExtensionData.Config.ExtraConfig | Where {$_.Key -eq "sched.mem.pshare.enable"}).Value
$VMMemoryMB = $VM.MemoryMB
$VMMemReservation = $VM.ExtensionData.ResourceConfig.MemoryAllocation.Reservation
$VMUsedSpace = [Math]::Round($VM.UsedSpaceGB,2)
$VMProvisionedSpace = [Math]::Round($VM.ProvisionedSpaceGB,2)
$VMPowerState = $VM.PowerState

New-Object -TypeName PSObject -Property @{
Name = $VMName
HW = $VMHardwareVersion
VMGuestOS = $VMGuestOS
vCPUCount = $VMvCPUCount
MemoryMB = $VMMemoryMB
MemoryReservation = $VMMemReservation
MemSharing = $VMMemShare
UsedSpaceGB = $VMUsedSpace
ProvisionedGB = $VMProvisionedSpace
PowerState = $VMPowerState
}
}
}

 

You can use the cmdlet to very easily retrieve information about a single VM or list of VMs. Examples:

 

Get-VMUsefulStats -VM NOOBS-VC01

Get-VM | Get-VMUsefulStats

 

To format the output in a neat table, pipe the above to Format-Table (ft) like so:

 

Get-VM | Get-VMUsefulStats | ft

 

The “MemShare” value is interesting – it is something I was specifically interested in, as some VMs I have worked with in the past have needed memory sharing to be specifically disabled, and this is something that needs to be changed with an advanced parameter on the VM. Therefore most (default) VMs will not have this entry at all and will appear blank in the output. (the parameter I am referring to for those interested is sched.mem.pshare.enable). Of course this most likely won’t be of any use to you, so feel free to omit this bit from the function, or feel free to customise the function to return information useful to your VMware deployment VMs. Here is an example of the output for one VM.

 

 

Anyway, I hope someone finds this useful, and please do let me know if you think of any improvements or better way of achieving a certain result.

 

Get vCenter User Sessions and Idle times with PowerCLI

Today I was looking into a small “nice to have” notification system for users that had left their vSphere clients open and logged into vCenter. I found this great bit of script to list currently logged in users over at blog.vmpros.nl and thought I would expand on this in my own way to generate a handy list of logged in users and their current idle time – similar to the way the “Sessions” tab in the vSphere client displays user session information. When I got home this evening I expanded on the original script from vmpros.nl to create the following:

 

$Now = Get-Date
$Report = @()
$svcRef = new-object VMware.Vim.ManagedObjectReference
$svcRef.Type = "ServiceInstance"
$svcRef.Value = "ServiceInstance"
$serviceInstance = get-view $svcRef
$sessMgr = get-view $serviceInstance.Content.sessionManager
foreach ($sess in $sessMgr.SessionList){
   $time = $Now - $sess.LastActiveTime
   # Our time calculation returns a TimeSpan object instead of DateTime, therefore formatting needs to be done as follows:
   $SessionIdleTime = '{0:00}:{1:00}:{2:00}' -f $time.Hours, $time.Minutes, $time.Seconds
   $row = New-Object -Type PSObject -Property @{
   		Name = $sess.UserName
		LoginTime = $sess.LoginTime
		IdleTime = $SessionIdleTime
	} ## end New-Object
	$Report += $row
}
$Report

 

[download id=”6″]

 

Here is an example of the output of the script:

 

Using this bit of PowerCLI script, it should be easy for you to create your own notification system based on user session idle time, or some functionality that would disconnect idle users. Let me know if you do improve on the above, or if you have any other suggestions.