PowerCLI - Disk Space Utilization - vSphere Object
Referencing documentation is one of those things that seems overwhelming at first, but ends up becoming fundamental. I’m working on a series of posts where I take specific tasks and show how to refer to the documentation to accomplish the task.
In this blog, we’ve been tasked with reporting information about a VM’s disk space and its associated filesystem. We’ll be working with the vSphere objects. vSphere objects are vSphere Web Services API based, which means that we’ll be using a different set of documents to pull the same data. This document is known as the vSphere Web Services API Reference.
For more information about this blog series, see the following kickoff blog post: PowerCLI - Documentation Overview
Disk Space Utilization - vSphere Object
Taking a look at our request from the vSphere API level, we will again want to start at the VirtualMachine Managed Object. We can immediately notice a larger amount of data available to consume, since accessing the API gives us access to all of the available information. We’ll first want to start in the storage property, which leads us to the VirtualMachineStorageInfo data object. We can see there’s a property of perDatastoreUsage which is related to the VirtualMachineUsageOnDatastore object. This object has two properties we’re interested in, committed and uncommitted. The committed property will represent the used space amount, while the sum of committed and uncommitted will represent the provisioned space amount. Note, both of those properties are referenced in bytes so there will need to be some conversion done later.
Next, we’re looking for information about the hard disk itself. This is a multi-step process. Referencing the VirtualMachine object, we can see the layoutEx property contains information about the files that comprise a VM. The layoutEx property aligns with the VirtualMachineFileLayoutEx object, which has the property of disk. This disk property aligns with the VirtualMachineFileLayoutExDiskLayout object which gives us a key property. By reading the description of the key property, we can see that this key matches up to a VirtualDevice object which also has a key property. In reading through the available properties, we’re missing the property we’re looking for, which is a capacity-based property. This is where the ‘DynamicData’ comes into play. At the bottom of the properties, it specifies that some additional properties could be inherited by “DynamicData”. This is where the “Extended by” section comes into play. For our request, we can see that the VirtualDevice object is extended by the VirtualDisk object. When we look at the VirtualDisk object, we see the property that we’re looking for: capacityInBytes! At this point, we have our property but we don’t know how to retrieve it. Using the “Property of” section, we can backtrack to the VirtualMachine object. VirtualDisk is extended by the VirtualDevice object. The VirtualDevice object is a property of the VirtualHardware object. The VirtualHardware object is a property of the VirtualMachineConfigInfo object. Which takes us back to the VirtualMachine object, since the VirtualMachineConfigInfo is a property of the VirtualMachine object.
Last, we’re looking for filesystem-based information. Similarly to the .Net object, the VirtualMachine object has a guest property which is a GuestInfo object. The GuestInfo object has a property of disk, which is a GuestDiskInfo object. The GuestDiskInfo object has the capacity, diskPath, and freeSpace properties we’re looking for.
Attempting a quick recap, based on the request for hard disk and filesystem of a VM, we’re going to be interested in the following properties of the vSphere objects:
Object | Property |
---|---|
VirtualMachineUsageOnDatastore | committed |
VirtualMachineUsageOnDatastore | uncommitted |
VirtualMachineFileLayoutExDiskLayout | key |
VirtualDisk | capacityInBytes |
GuestDiskInfo | diskPath |
GuestDiskInfo | capacity |
GuestDiskInfo | freeSpace |
Since we’re only going to be working with the root VirtualMachine object, we can move right over to the code. We can access the vSphere object in two ways, either through the usage of the Get-View cmdlet or through an object’s Extension Data. Once we have established that object in a variable, the experience is the same.
The two ways to retrieve the vSphere object for a particular VM can actually be extended into three ways, depending on what you are most comfortable with:
# Option 1: Using a .Net object’s ExtensionData
$vm = Get-VM -Name $vmName
$vm.ExtensionData
# Option 2: Piping a .Net object to the Get-View cmdlet
$vm = Get-VM -Name $vmName
$vmView = $vm | Get-View
# Option 3: Using Get-View and filtering for the desired VM
Get-View -ViewType VirtualMachine -Filter @{"Name" = $vmname}
We can break it down to be the following cmdlets and properties:
Cmdlet | Property Path |
---|---|
Get-VM | Get-View |
Get-VM | Get-View |
Get-VM | Get-View |
Get-VM | Get-View |
Get-VM | Get-View |
Get-VM | Get-View |
Get-VM | Get-View |
Here’s what it looks like in PowerCLI code:
# Establishing the connection to our vSphere object
$vm = Get-VM -Name $vmName
$vmView = $vm | Get-View
# Creating a new PowerShell custom object to easily output properties
$output = New-Object -TypeName PSCustomObject
# Adding desired properties to the new PowerShell object
$diskCommit = $vmView.Storage.PerDatastoreUsage.Committed
$diskUncommit = $vmView.Storage.PerDatastoreUsage.Uncommitted
Add-Member -InputObject $output -MemberType NoteProperty -Name UsedSpaceGB -Value ($diskCommit / 1GB)
Add-Member -InputObject $output -MemberType NoteProperty -Name ProvisionedSpaceGB -Value (($diskCommit + $diskUncommit) / 1GB)
$diskKey = $vmView.LayoutEx.Disk.Key
$diskCapacity = $vmView.Config.Hardware.Device | Where-Object {$_.key -eq $diskKey} | Select-Object -ExpandProperty capacityInBytes
Add-Member -InputObject $output -MemberType NoteProperty -Name CapacityGB -Value ($diskCapacity / 1GB)
Add-Member -InputObject $output -MemberType NoteProperty -Name GuestPath -Value $vmView.Guest.Disk.DiskPath
Add-Member -InputObject $output -MemberType NoteProperty -Name GuestCapacityGB -Value ($vmView.Guest.Disk.Capacity / 1GB)
Add-Member -InputObject $output -MemberType NoteProperty -Name GuestFreeSpaceGB -Value ($vmView.Guest.Disk.FreeSpace / 1GB)
# Viewing the output
$output
Here’s what it looks like in our PowerShell session: