Image: Shutterstock/SidorArt

As someone who administers a VMware virtual environment and has been through several company mergers, running inventory audits is second nature to me. It’s always a good idea to maintain a current inventory of your virtual machines in order to best manage the environment, but due to the ever-changing nature of technology, where systems are built or decommissioned at a regular pace, it can be like trying to hit a moving target.

As usual, scripting is the key here. This VMware-based PowerShell script can help make collecting your inventory data quick and easy. My colleague Brad Doran, senior technical account manager at Amazon Web Services, provided me this script and I am using it here with his permission. You can copy and paste it to a local file called VMware_Inventory.ps1, for instance.


Use Windows 10 (it’s theoretically possible to run this in Windows 7, but you may experience headaches with outdated PowerShell versions since this script requires PowerShell 4.0 at minimum).

Run Windows PowerShell ISE as Administrator (you can also use regular PowerShell, but I find ISE best for maximum results as well as error evaluation).

Install the VMware PowerCLI module using this comment within the PowerShell ISE Window:

Install-Module -Name VMware.PowerCLI

If you get an error that you need NuGet provider version 2.8.201 just click Yes and the process will download and install it for you. It will take a few moments and you’ll then need to click Yes to proceed, and in a few more moments you will see the program installing the related VMWare.PowerCLI packages.

SEE: Microsoft PowerShell: Learn how to automate your workday (TechRepublic Academy)

Since the script requires the VMware.VimAutomation.Core module also make sure it’s the latest version (as of October 2021) installed via this command:

Install-Module -Name VMware.VimAutomation.Core -RequiredVersion

Click Yes to proceed and in a few more moments you will see the program installing the related VMWare package.

If you receive an error stating: “PackageManagementInstall-Package : Authenticode issuer ‘CN=VeriSign Class 3 Public Primary Certification Authority – G5, OU=”(c) 2006 VeriSign, Inc. – For authorized use only”, OU=VeriSign Trust Network, O=”VeriSign, Inc.”, C=US’ of the new module ‘VMware.VimAutomation.Core’ with version ‘’ is not matching with the authenticode issuer ‘CN=DigiCert Trusted Root G4,, O=DigiCert Inc, C=US’ of the previously-installed module ‘VMware.VimAutomation.Core’ with version ‘’. If you still want to install or update, use-SkipPublisherCheck parameter”

run this command:

Install-Module -Name VMware.VimAutomation.Core -RequiredVersion -SkipPublisherCheck

You can also go here and download the latest version to (“C:Program Files (x86)VMWareInfrastructurePowerCLIModules”):

Customizing the script

The script relies on these variables (Figure A):

$vcs = @(“vCenterFQDN”) # FQDN of your vCenter server.
$logFile = “C:TempVMInventory.csv” # Where you want to save the CSV file
$vcsCluster = “*” # Filters which cluster you want to pull VM stats from
$businessUnitName = “Element” # Name of business unit that the script is gathering stats for

Figure A

For $vcs, you can replace @(“vCenterFQDN”) with the name of your vCenter server in quotes; otherwise the script will prompt you to enter the name.

For $logFile, the logfile path and name can be changed accordingly.

For $vcsCluster you can specify the cluster to gather data from, or leave this line as is to pull information from all clusters.

For $businessUnitName, replace the example “Element” entry with your business unit, department or group.

SEE: Checklist: Server inventory (TechRepublic Premium)

Running the script

Click File then Open and browse to where you saved the script file to select it then load it into PowerShell ISE. Hit the green button to execute it.

If you get an error related to security policies or the script being unsigned, run this command to allow local scripts and remote signed scripts:

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned

If you left the $vcs variable as is you will be prompted to enter the vCenter server name (Figure B).

Figure B

Once you enter the name you’ll be prompted to authenticate to vCenterj (Figure C). Make sure to use an account with administrator-level credentials.

Figure C

You will then see the script running and actively gathering data (Figure D).

Figure D

The script will display the results, as well as save the details to “C:TempVMInventory.csv” if you left the related variable as is (Figure E).

Figure E

(Note I have removed the FQDN entries that were listed since this was run against an active business environment.)

Thank you, Brad, for an excellent tool every VMware administrator should have in their toolkit!

Please contact me via the email link below (to the left of “Full Bio | See all of Scott’s content”) if you have any questions or issues running this script.

#Requires -Version 4
#Requires -Modules VMware.VimAutomation.Core

<# .SYNOPSIS Create an inventory in CSV format of virtual machines in vCenter. .DESCRIPTION This script is meant to perform an inventory of Virtual Machines. It can connect to multiple vCenters to pull statistics from and it can pull statistics from multiple Host Clusters. This script performs read-only operations. Output is formatted as CSV using a standard layout. Variable Details $vcs - An array containing the list of vCenter servers to connect to. $logFile - The location of where to save the output in CSV format. $vcsCluster - The name of the cluster. It accepts wildcard characters, but it cannot be empty. $businessUnitName - the busines unit, group or department which owns/supports this environment Credential Requirements $vcsCreds - A user credential that has access to login to vCenter with Read-Only rights at a minimum. $wmiCreds - A user credential that has access to perform WMI queries locally on the Windows Virtual Machines #>


# Edit these variables for your specific environment
$vcs = @("vCenterFQDN") # FQDN of your vCenter server.
$logFile = "C:TempVMInventory.csv" # Where you want to save the CSV file
$vcsCluster = "*" # Filters which cluster you want to pull VM stats from.
$businessUnitName = "Element" # Name of Business Unit that the script is gathering stats for

if($vcs -contains "vCenterFQDN"){
$vcs = Read-Host -Prompt "FQDN of vCenter Server"
$vcsCreds = Get-Credential -Message "vCenter Credentials"
#$wmiCreds = Get-Credential -Message "WMI Credentials"

Import-Module VMware.VimAutomation.Core
Connect-VIServer $vcs -Credential $vcsCreds | Out-Null

$vms = Get-Cluster -Name $vcsCluster | Get-VM
$count = 0
$results = @()
$Script:ProgressPreferenceOriginal = $ProgressPreference
foreach($vm in $vms){
# Progress Bar setup
$percentComplete = [math]::Round(($count / $vms.Count) * 100,1)
Write-Progress -Activity "Collecting info on $($vm.Name)" -Status "$percentComplete% Complete" -PercentComplete $percentComplete

# Store VM stat info in PSObject
$object = New-Object PSObject
Add-Member -InputObject $object -MemberType NoteProperty -Name BusinessUnit -Value $businessUnitName
Add-Member -InputObject $object -MemberType NoteProperty -Name Name -Value $vm.Name
Add-Member -InputObject $object -MemberType NoteProperty -Name Domain -Value (($vm.Guest.Hostname.Split('.') | Select-Object -Skip 1) -join '.')
Add-Member -InputObject $object -MemberType NoteProperty -Name Location -Value " "
Add-Member -InputObject $object -MemberType NoteProperty -Name IPAddress -Value ($vm.Guest.IPAddress -join ", ")
Add-Member -InputObject $object -MemberType NoteProperty -Name Function -Value " "
Add-Member -InputObject $object -MemberType NoteProperty -Name PorV -Value "Virtual"
Add-Member -InputObject $object -MemberType NoteProperty -Name vCluster -Value ($vm | Get-Cluster).Name
Add-Member -InputObject $object -MemberType NoteProperty -Name vHost -Value $vm.VMHost
Add-Member -InputObject $object -MemberType NoteProperty -Name Make -Value "N/A"
Add-Member -InputObject $object -MemberType NoteProperty -Name Model -Value "N/A"
Add-Member -InputObject $object -MemberType NoteProperty -Name SerialNumber -Value "N/A"
Add-Member -InputObject $object -MemberType NoteProperty -Name CPU -Value $vm.NumCpu
Add-Member -InputObject $object -MemberType NoteProperty -Name vSocket -Value ($vm.NumCpu / $vm.CoresPerSocket)
Add-Member -InputObject $object -MemberType NoteProperty -Name CoreCount -Value $vm.CoresPerSocket
Add-Member -InputObject $object -MemberType NoteProperty -Name MemoryGB -Value $vm.MemoryGB
Add-Member -InputObject $object -MemberType NoteProperty -Name OperatingSystem -Value $vm.Guest.OSFullName
Add-Member -InputObject $object -MemberType NoteProperty -Name UsedSpaceGB -Value ([math]::Round($vm.UsedSpaceGB, 0))
Add-Member -InputObject $object -MemberType NoteProperty -Name ProvisionedSpaceGB -Value ([math]::Round($vm.ProvisionedSpaceGB,0))
Add-Member -InputObject $object -MemberType NoteProperty -Name Environment -Value " "
# Stores the PSObject containing VM stats in to an PSObject array
$results += $object

# The Sort-Object is specifically set up so that the Export-Csv and Out-GridView do not truncate the properties of the individual PSObjects in
# the array.
$results | Out-GridView
$results | Export-Csv -Path $logFile -NoTypeInformation
Write-Host "Output saved to $logFile"

Disconnect-VIServer -Server * -Confirm:$false -Force | Out-Null

  • More must-read Microsoft coverage (TechRepublic on Flipboard)
  • Manage Active Directory with these 11 PowerShell scripts (TechRepublic Premium)
  • Top 5 programming languages for systems admins to learn (free PDF) (TechRepublic)