It’s always a good idea to get a high level overview of what’s going on with your VMware environment. When it comes to VMs, the command Get-VM, has a lot of useful information regarding your virtual machines. Today we’re going to develop a script that builds on top of that. The Get VMInformation script is useful if you want an export of where everything is located, network names and guest OS. This Powershell script will even check if vmtools is up to date so you can see which VMs need an update. I had a lot of fun developing the script so let’s get to it.
Get VMInformation Using Powershell and PowerCLI
Function Get-VMInformation { <# .SYNOPSIS Get information from a VM object. Properties inlcude Name, PowerState, vCenterServer, Datacenter, Cluster, VMHost, Datastore, Folder, GuestOS, NetworkName, IPAddress, MacAddress, VMTools .NOTES Name: Get-VMInformation Author: theSysadminChannel Version: 1.0 DateCreated: 2019-Apr-29 .EXAMPLE For updated help and examples refer to -Online version. .LINK https://thesysadminchannel.com/get-vminformation-using-powershell-and-powercli - #> [CmdletBinding()] param( [Parameter( Position=0, ParameterSetName="NonPipeline" )] [Alias("VM")] [string[]] $Name, [Parameter( Position=1, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, ParameterSetName="Pipeline" )] [PSObject[]] $InputObject ) BEGIN { if (-not $Global:DefaultVIServer) { Write-Error "Unable to continue. Please connect to a vCenter Server." -ErrorAction Stop } #Verifying the object is a VM if ($PSBoundParameters.ContainsKey("Name")) { $InputObject = Get-VM $Name } $i = 1 $Count = $InputObject.Count } PROCESS { if (($null -eq $InputObject.VMHost) -and ($null -eq $InputObject.MemoryGB)) { Write-Error "Invalid data type. A virtual machine object was not found" -ErrorAction Stop } foreach ($Object in $InputObject) { try { $vCenter = $Object.Uid -replace ".+@"; $vCenter = $vCenter -replace ":.+" [PSCustomObject]@{ Name = $Object.Name PowerState = $Object.PowerState vCenter = $vCenter Datacenter = $Object.VMHost | Get-Datacenter | select -ExpandProperty Name Cluster = $Object.VMhost | Get-Cluster | select -ExpandProperty Name VMHost = $Object.VMhost Datastore = ($Object | Get-Datastore | select -ExpandProperty Name) -join ', ' FolderName = $Object.Folder GuestOS = $Object.ExtensionData.Config.GuestFullName NetworkName = ($Object | Get-NetworkAdapter | select -ExpandProperty NetworkName) -join ', ' IPAddress = ($Object.ExtensionData.Summary.Guest.IPAddress) -join ', ' MacAddress = ($Object | Get-NetworkAdapter | select -ExpandProperty MacAddress) -join ', ' VMTools = $Object.ExtensionData.Guest.ToolsVersionStatus2 } } catch { Write-Error $_.Exception.Message } finally { if ($PSBoundParameters.ContainsKey("Name")) { $PercentComplete = ($i/$Count).ToString("P") Write-Progress -Activity "Processing VM: $($Object.Name)" -Status "$i/$count : $PercentComplete Complete" -PercentComplete $PercentComplete.Replace("%","") $i++ } else { Write-Progress -Activity "Processing VM: $($Object.Name)" -Status "Completed: $i" $i++ } } } } END {} }
Copy the script to a folder and let’s go over some of the usage and examples. Since Get-VM already displays the basic info such as CPU, memory etc.. in the default output, I didn’t think it was necessary to add those properties in the script.
Get-VMInformation Examples and Usage
First things first, we’ll need to load the function into memory and connect to a vcenter server in order to query the information that we’re looking for. If you’re not connected, the script will output an error saying its unable to continue.
#import the PowerCLI module Import-Module VMware.PowerCLI #Connect to a vcenter server Connect-VIServer -Server vcenter.thesysadminchannel.com #Load the function into memory. This is assuming your file is located in C:\Scripts . 'C:\Scripts\Get-VMInformation.ps1' #Get vm information for PAC-DC01. PS C:\> Get-VMInformation -Name PAC-DC01 Name : PAC-DC01 PowerState : PoweredOn vCenter : vcenter.thesysadminchannel.com Datacenter : US Cluster : Cluster-01 VMHost : esx.thesysadminchannel.com Datastore : ESX_Local Folder : VMs GuestOS : Microsoft Windows Server 2012 (64-bit) NetworkName : DPortGroup IPAddress : 10.0.0.100 MacAddress : xx:xx:xx:xx:xx:xx VMTools : guestToolsCurrent
Since the function allows for pipeline input, we can get an array in VMs from a cluster or datacenter and just pipe it to the function. We will just have to make sure the Get-VM cmdlet is used before the Get-VMInformation to get the objects.
#EXAMPLE 1 - Gets the VM information for all VMs that are in the specified cluster within the US Datacenter and VCSA01 vcenter server. Get-Cluster Cluster-01 -Server vCSA01 -Location US | Get-VM | Get-VMInformation #EXAMPLE 2 - Gets VM information for VMs 1 and 2 Get-VM VM1, VM2 | Get-VMInformation #EXAMPLE 3 - Gets VM information for VMs 1 and 2 Get-VMInformation -Name VM1, VM2
I hope you found as much value in the Get-VMInformation script as I did. Let me know in the comments if you would like me to develop a script that has some usefulness to the general population.
For more VMware related articles take a look at VMware Gallery or stop by our Youtube Channel with VMware Videos
Hi Paul, How could I add the Memorym CPU, and Disk Allocations to the data returned?
This function is extremely helpful! Thank you for posting it. I added an VM attribute for ‘$secureBootSetting’ (EFI) which I needed because of the Feb 2023 bug from Microsoft. I also piped the output to a .csv
try {
$vCenter = $Object.Uid -replace “.+@”; $vCenter = $vCenter -replace “:.+”
$secureBootSetting = if ($vm.ExtensionData.Config.BootOptions.EfiSecureBootEnabled) { “enabled” } else { “disabled” }
[PSCustomObject]@{
Name = $Object.Name
PowerState = $Object.PowerState
vCenter = $vCenter
Datacenter = $Object.VMHost | Get-Datacenter | select -ExpandProperty Name
Cluster = $Object.VMhost | Get-Cluster | select -ExpandProperty Name
VMHost = $Object.VMhost
Datastore = ($Object | Get-Datastore | select -ExpandProperty Name) -join ‘, ‘
FolderName = $Object.Folder
GuestOS = $Object.ExtensionData.Config.GuestFullName
SecureBoot = $secureBootSetting
NetworkName = ($Object | Get-NetworkAdapter | select -ExpandProperty NetworkName) -join ‘, ‘
IPAddress = ($Object.ExtensionData.Summary.Guest.IPAddress) -join ‘, ‘
MacAddress = ($Object | Get-NetworkAdapter | select -ExpandProperty MacAddress) -join ‘, ‘
VMTools = $Object.ExtensionData.Guest.ToolsVersionStatus2
}
Get-VM | Get-VMInformation | Select-Object Name,PowerState,vCenter,Datacenter,Cluster,VMHost,Datastore,FolderName,GuestOS,SecureBoot,NetworkName,IPAddress,MacAddress,VMTools | Sort-Object Name | Export-Csv -Path “C:\Temp\AllVMInformation.csv” -NoTypeInformation
This is great. very helpful. how can I also get the notes from the VM’s
How would I change the output to columns where you have rows? Your output flows like this:
Name
PowerState
vCenter
Datacenter
Cluster
VMHost
Datastore
FolderName
GuestOS
NetworkName
IPAddress
MacAddress
VMTools
For me it would be much better if each of those rows was a column.
Thanks!
You can do this one of 2 ways. Open Powershell as a full windows and add | ft -Autosize
Or you can export the output to csv.
I am piping all of the vm’s from my vCenter through the function like this:
Foreach ($VM in $VMs) {Get-VMInformation -Name $VM}.
Are you saying that I could achieve the desired format with this:
Foreach ($VM in $VMs) {Get-VMInformation -Name $VM | ft -Autosize }.
Thanks for the quick reply!
You won’t get the desired results in a foreach loop. However with this function you can do
Get-VMInformation -Name $VMs | ft -Autosize
or
$VMList = Foreach ($VM in $VMs) {Get-VMInformation -Name $VM}
$VMList | ft -autosize
with this many attributes I would personally export it to csv.
Foreach ($VM in $VMs) {Get-VMInformation -Name $VM | export-csv $home\desktop\vminformation.csv -notypeinformation -append}
Thanks much that works like a charm!
What about the VM ID? Can you add that into the listing of data returned?