PowerShell: ESX/vCenter Inventory for Virtual Appliance (vApp)

Summary

PowerShell script to return a machine inventory from vCenter and export it in CSV format.

Issue

I was asked to perform an inventory of all virtual machines running on a customer managed virtual appliance for accounting purposes, they required a specific set of data in a CSV format.

This presented a good opportunity for a real world case of using PowerShell to return an inventory from vCenter.

Solution

Setting up your technician machine to connect to vCenter is not within the scope of this article but a good guide can be found here:

The client required the following information for their inventory:

VM Name
vApp Pool
Number of vCPUs
Memory (Gb)
Operating system running on the VM
All assigned IP addresses
All associated hard disks (Gb)

The script can however be modified to include any other properties you require.

Most of this information can simply be extracted from the Get-VMGuest commandlet

Get-VM -Location $strVApp

You will notice that Hard Disks are stored in an property HardDisk, in order to extract each individual hard disk we will extract each member and store it separately.

FOREACH ($objHardDisk in $objVM.HardDisks){
    Add-Member -InputObject $objVMInfo –MemberType NoteProperty -Name $objHardDisk.Name -Value $objHardDisk.CapacityGB
}

In order to return information from within the Guest itself such as IP Address and Operating System we will be utilising the Get-VMGuest commandlet.

Get-VMGuest -VM $objVM.Name

If a VM is not online the IP information will not be returned, as such we also query the state of the current machine so this scenario can be identified

IF($objVMGuestQuery.IPAddress.Count -eq 0){
   # No IP returned give machine state instead
   $strIPAddress = $objVMGuestQuery.State | Out-String
   Add-Member -InputObject $objVMInfo –MemberType NoteProperty -Name IPAddress -Value $strIPAddress
} ELSE {
   $strIPAddress = $objVMGuestQuery.IPAddress | Out-String
   Add-Member -InputObject $objVMInfo –MemberType NoteProperty -Name IPAddress -Value $strIPAddress
}

This information then needs to be passed into an object to be used with a built in commandlet Export-CSV so we build a simple array of objects (each object being an individual VM).

However you will find not all the information is displayed, this is because the Export-CSV commandlet takes the first object passed to it as the header information to be used in the CSV. Any objects with additional members will have them omitted.

To resolve this we will order the objects within in descending order based on the number of members in each object.

Sort-Object -Property @{expression={$_.psobject.properties.count}}-Descending

We then pipe this information into the Export-CSV commandlet and you will have a CSV with an inventory of Virtual Machines in a given virtual appliance.

Implementation

# Script to list virtual machines within a given vApp
# Copyright (C) 2015  Adil Dean
# Script Name: vCenterListVMs.ps1
# Script Version: 1.0.0
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
#(at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see .
#
# ============================================================================
# Change History:
# 0.0.1 - 17/03/2015 - Adil Dean
#		- Script created
# 0.0.2 - 17/03/2015 - Adil Dean
#       - Clean-up variable names
#       - Export to CSV
# 0.0.3 - 18/03/2015 - Adil Dean
#		- Fix export to CSV to order based on number of members in an object
#		- Remove debug code
# 1.0.0	- Release version
#		- Remove ConfigMonkey specific data
#       
# ============================================================================
# Known Bugs:
#
# ============================================================================
# Requirements:
# - Script is not signed (requires necessary permissions)
# Usage Instructions:
# \vCenterListVMs.ps1
#
# Comments:
#
# ============================================================================
# Parameters/Arguments
$strVCenterAddress = "vCenter.configmonkey.co.uk"	# vCenter/ESX Address
$strVCenterProtocol = "https"				# Connection Protocol (https/http)
$strVApp = "ConfigMonkeyApp"				# Virtual appliance name
# ============================================================================
# Initialize Variables
$objVMQuery = @()	# All vms in given query
$objVM = @()		# Current VM being processed
$objVMGuestQuery = @()  # Current VM Guest being processed
$objHardDisk = @()  # Current Hard Disk being processed

$objVMInfo = New-Object –TypeName PSObject  # Object to hold VM Details for export to CSV
$aVMList = @()
$strIPAddress = $null
# ============================================================================

Clear-Host

# Connect to VSphere or ESx
Connect-VIServer -Server $strVCenterAddress -Protocol $strVCenterProtocol

# Get all VMs from vSphere matching a query based on a Virtual Appliance name
$objVMQuery = Get-VM -Location $strVApp

FOREACH ($objVM in $objVMQuery){
    $objVMInfo = New-Object –TypeName PSObject
          
    Add-Member -InputObject $objVMInfo –MemberType NoteProperty –Name Name –Value $objVM.Name
	# Get Guest VM Details
	$objVMGuestQuery = Get-VMGuest -VM $objVM.Name
    
		IF($objVMGuestQuery.IPAddress.Count -eq 0){
            # No IP returned give machine state instead
            $strIPAddress = $objVMGuestQuery.State | Out-String
            Add-Member -InputObject $objVMInfo –MemberType NoteProperty -Name IPAddress -Value $strIPAddress
        } ELSE {
            $strIPAddress = $objVMGuestQuery.IPAddress | Out-String
            Add-Member -InputObject $objVMInfo –MemberType NoteProperty -Name IPAddress -Value $strIPAddress
        }
	Add-Member -InputObject $objVMInfo –MemberType NoteProperty -Name OS -Value $objVMGuestQuery.OSFullName
	Add-Member -InputObject $objVMInfo –MemberType NoteProperty -Name vApp -Value $objVM.VApp
	Add-Member -InputObject $objVMInfo –MemberType NoteProperty -Name NumCpu -Value $objVM.NumCpu
	Add-Member -InputObject $objVMInfo –MemberType NoteProperty -Name Memory -Value $objVM.MemoryGB
	FOREACH ($objHardDisk in $objVM.HardDisks){
		Add-Member -InputObject $objVMInfo –MemberType NoteProperty -Name $objHardDisk.Name -Value $objHardDisk.CapacityGB
	}
    
    Write-Output $objVMInfo
    
    $aVMList += $objVMInfo
   
}

$aVMList| Sort-Object -Property @{expression={$_.psobject.properties.count}}-Descending | Export-csv "VMInventory.csv" -NoTypeInformation

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s