9

Get VMInformation Using Powershell and PowerCLI

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.

Get VMInformation - Connect to a vcenter server Error - PowerCLI

#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

5/5 - (8 votes)

Paul Contreras

Hi, my name is Paul and I am a Sysadmin who enjoys working on various technologies from Microsoft, VMWare, Cisco and many others. Join me as I document my trials and tribulations of the daily grind of System Administration.

9 Comments

  1. Hi Paul, How could I add the Memorym CPU, and Disk Allocations to the data returned?

  2. 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

  3. 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}

Leave a Reply

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