Advancing the Function

AdvFunctionRecently I had to grab some general info on a group of VMs in a particular folder within vSphere.  Typical stuff like, Guest OS, # vCPUs, RAM, Disk, etc. I looked around my scripts folder as I was sure I had written a small script to accomplish this task previously but came up empty. No problem, I’ll just whip something up I thought. Then my mind starts racing, will the script output to csv? html? Excel? Word? I could include all options (and code) and let the user choose? What parameters will I need and how will I validate them? This script was getting cumbersome already and I hadn’t even thought about the simple info I needed to query. Then it dawned on me…all I needed was the data. I decided to strip the function down to simply gathering the information I needed. If I wrote a proper advanced function, then I could just return the gathered objects down the pipeline and from there format the output as needed.

Simply put, an advanced function acts very much like a standard cmdlet.

This allows me to create simple one-liners that will a) select the VMs I’d like to query and b) format the output however I would like.  Unlike having to create a new full script each time you want to accomplish a task, an advanced function is flexible, versatile and possibly most importantly – easily reusable. This makes them ideal for inclusion into modules that load any time you fire up PowerShell.

Below is the code for the (simple) advanced function I created – Get-VMInfo. As you can see the code is pretty simple though it makes for a great example. You feed it a list of VMs via the pipeline and it returns the info you requested via custom objects. Let’s see how we could utilize the function assuming we are connected to vCenter and have PowerCLI loaded.

Gather a list of all VMs and pipe to Get-VMInfo

Get-VM | Get-VMInfo

Gather a list of VMs in a particular cluster and pipe to Get-VMInfo

Get-Cluster MyCluster | Get-VM | Get-VMInfo

Gather a list of VMs in a particular vSphere folder and pipe to Get-VMInfo

Get-Folder Servers | Get-VM | Get-VMInfo

Now lets do something more with the output.

Gather a list of all VMs, pipe to Get-VMInfo then pipe to Export-Csv

Get-VM | Get-VMInfo | Export-Csv -NoTypeInformation -Path E:\VMInfo.csv

Gather a list of all VMs, pipe to Get-VMInfo, pipe to ConvertTo-HTML then pipe to Out-File

Get-VM | Get-VMInfo | ConvertTo-HTML | Out-File E:\VMInfo.html

As you can see, by using an advanced function I actually have more options available to me then if I had hard coded all these options into one mega script. It also saved me a lot of time.


Function Get-VMInfo {
<#
.SYNOPSIS
Gather general information about a group of VMs.
.DESCRIPTION
This function returns general information gathered from a set of one or more VMs.
Data returned – Folder, Name, PowerState, FullName, GuestOS, IP, NumCPU, MemoryGB, DiskGB, DiskUsedGB, DiskFreeGB, Notes
.PARAMETER VMs
VM object (Get-VM)
.EXAMPLE
Get-VM | Get-VMInfo
Returns info for all VMs
.EXAMPLE
Get-Folder Servers | Get-VM | Get-VMInfo
Returns info for all VMs located within the Servers folder
.NOTES
Author: Shawn Masterson
Created: Aug 2014
Version: 1.0
#>
[CmdletBinding()]
param(
[Parameter(Mandatory=$True,
ValueFromPipeline=$True)]
[array]$VMs
)
Begin {
$output = @()
}
Process {
Foreach ($VM in $VMs) {
Write-Verbose "Processing $VM"
$tempvm = @{}
$tempvm.Folder = $VM.Folder
$tempvm.Name = $VM.Name
$tempvm.PowerState = $VM.PowerState
$tempvm.NumCPU = $VM.NumCPU
[int]$tempvm.MemoryGB = $VM.MemoryGB
$tempvm.DiskGB = [Math]::Round((($vm.HardDisks | Measure-Object -Property CapacityKB -Sum).Sum * 1KB / 1GB),2)
$tempvm.DiskFreeGB = If (![Math]::Round((($vm.Guest.Disks | Measure-Object -Property FreeSpace -Sum).Sum / 1GB),2)) `
{"Tools Not Running\Unknown"} Else {[Math]::Round((($vm.Guest.Disks | Measure-Object -Property FreeSpace -Sum).Sum / 1GB),2)}
$tempvm.DiskUsedGB = If ($tempvm.DiskFreeGB -eq "Tools Not Running\Unknown") `
{"Tools Not Running\Unknown"} Else {$tempvm.DiskGB – $tempvm.DiskFreeGB}
$tempvm.Notes = $VM.Notes
$tempvm.GuestOS = If (!$VM.Guest.OSFullName) {"Tools Not Running\Unknown"} Else {$VM.Guest.OSFullName}
$tempvm.IP = If (!$VM.Guest.IPAddress[0]) {"Tools Not Running\Unknown"} Else {$VM.Guest.IPAddress[0]}
$tempvm.FullName = If (!$VM.Guest.hostname) {"Tools Not Running\Unknown"} Else {$VM.Guest.hostname}
$temp = New-Object –TypeName PSObject –Prop $tempvm
$output += $temp
}
}
End {
$output | Select Folder, Name, PowerState, FullName, GuestOS, IP, NumCPU, MemoryGB, DiskGB, DiskUsedGB, DiskFreeGB, Notes | Sort Folder, Name
}
}

view raw

Get-VMInfo

hosted with ❤ by GitHub

Leave a Reply

Your email address will not be published. Required fields are marked *