For reporting purposes, I maintain an Excel sheet containing information on my server base. I update this sheet on a weekly basis. Part of the information displayed in this sheet comes from a PowerShell script I have created to extract the required data from our vCenters.
This script pulls the following information for every VM running the vCenter environment: VM Name, Hardware version, VMware tools status, guest OS, number of vCPU’s, amount of assigned RAM, the host the VM runs on, the cluster the VM is assigned to, the folder it lives in, the power status, number of NICs, the NIC types and the vCenter it runs on (in case you have more than 1).
Maybe this script is sufficient for your needs. If not, it should be straight forward enough for you to adjust.
A requirement for this script to work is the VMware PowerCLI PowerShell module, which can be installed with this PowerShell command:
1 | Install-Module -Name VMware.PowerCLI -Scope CurrentUser |
See https://blogs.vmware.com/PowerCLI for more information about VMware PowerCLI.
In order for this script to work for your environment, make sure to adjust variable $vCenterServers to match your vCenter server(s).
Also have a look at variable $VMList. The script below simply gets information about all your virtual machines. But off course you can limit the number of queried virtual machines by using a filter. I have left an example as comments.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | If (-not (Get-Module -Name 'VMware.PowerCLI')) { Import-Module VMware.PowerCLI } # Set-PowerCLIConfiguration -DefaultVIServerMode Multiple -Scope Session # Needs to be set only once !!! # Set-PowerCLIConfiguration -DefaultVIServerMode Multiple -Scope User # Needs to be set only once !!! # Set-PowerCLIConfiguration -InvalidCertificateAction ignore -confirm:$false $DateTime = $((Get-Date).ToString('yyyy-MM-dd_hh-mm-ss')) $OutputPath = "$env:USERPROFILE\Documents\Reports" If ( -Not (Test-Path -Path $OutputPath)) { New-Item -ItemType directory -Path $OutputPath } Set-Location $OutputPath $Outputfile = "$DateTime-All-VMs-Output" Function Connect-vCenter { Param ( [Parameter(Mandatory = $True)] $vCenterServer, [System.Management.Automation.PSCredential]$Credential ) If ($Credential) { # Add-PSSnapin VMware.VimAutomation.Core Connect-VIServer $vCenterServer -Credential $Credential } Else { # Add-PSSnapin VMware.VimAutomation.Core Connect-VIServer $vCenterServer } } # Prompt for Credentials and verify them using the DirectoryServices.AccountManagement assembly. Write-Host "Please provide your credentials so the script can continue." Add-Type -AssemblyName System.DirectoryServices.AccountManagement # Extract the current user's domain and also pre-format the user name to be used in the credential prompt. $UserDomain = "$env:USERDOMAIN" #$UserName = "$UserDomain\$env:USERNAME" $UserName = "$env:USERNAME" # Define the starting number (always #1) and the initial credential prompt message to use. $Attempt = 1 $CredentialPrompt = "Enter your domain account password (attempt #$Attempt out of $MaxAttempts):" # Set ValidAccount to false so it can be used to exit the loop when a valid account is found (and the value is changed to $True). $ValidAccount = $False # Loop through prompting for and validating credentials, until the credentials are confirmed, or the maximum number of attempts is reached. Do { # Blank any previous failure messages and then prompt for credentials with the custom message and the pre-populated domain\user name. $FailureMessage = $Null $Credentials = Get-Credential -UserName $UserDomain\$UserName -Message $CredentialPrompt # Verify the credentials prompt wasn't bypassed. If ($Credentials) { # If the user name was changed, then switch to using it for this and future credential prompt validations. If ($Credentials.UserName -ne $UserName) { $UserName = $Credentials.UserName } # Test the user name (even if it was changed in the credential prompt) and password. $ContextType = [System.DirectoryServices.AccountManagement.ContextType]::Domain Try { $PrincipalContext = New-Object System.DirectoryServices.AccountManagement.PrincipalContext $ContextType, $UserDomain } Catch { If ($_.Exception.InnerException -like "*The server could not be contacted*") { $FailureMessage = "Could not contact a server for the specified domain on attempt #$Attempt out of $MaxAttempts." } Else { $FailureMessage = "Unpredicted failure: `"$($_.Exception.Message)`" on attempt #$Attempt out of $MaxAttempts." } } # If there wasn't a failure talking to the domain test the validation of the credentials, and if it fails record a failure message. If (-not($FailureMessage)) { $ValidAccount = $PrincipalContext.ValidateCredentials($UserName, $Credentials.GetNetworkCredential().Password) If (-not($ValidAccount)) { $FailureMessage = "Bad user name or password used on credential prompt attempt #$Attempt out of $MaxAttempts." } } # Otherwise the credential prompt was (most likely accidentally) bypassed so record a failure message. } Else { $FailureMessage = "Credential prompt closed/skipped on attempt #$Attempt out of $MaxAttempts." } # If there was a failure message recorded above, display it, and update credential prompt message. If ($FailureMessage) { Write-Warning "$FailureMessage" $Attempt++ If ($Attempt -lt $MaxAttempts) { $CredentialPrompt = "Authentication error. Please try again (attempt #$Attempt out of $MaxAttempts):" } ElseIf ($Attempt -eq $MaxAttempts) { $CredentialPrompt = "Authentication error. THIS IS YOUR LAST CHANCE (attempt #$Attempt out of $MaxAttempts):" } } } Until (($ValidAccount) -or ($Attempt -gt $MaxAttempts)) # If the credentials weren't successfully verified, then exit the script, otherwise pass them through for further use. Write-Host "" If (-not($ValidAccount)) { Write-Host -ForegroundColor Red "You failed $MaxAttempts attempts at providing a valid user credentials. Exiting the script now... " EXIT } Else { #Write-Host 'Your confirmed credentials have been saved to the $Credentials variable and is available after this script finishes.' $Global:Credentials = $Credentials } $vCenterServers = @('vcenter01.yourdomain.local','vcenter02.yourdomain.local','vcenter03.yourdomain.local') # Remove or add vCenter's as required Connect-VCenter $vCenterServers $Credentials $VMList = $null $VMList = Get-VM # Get's all the VM's running in the specified vCenter(s) #$VMList = Get-VM | Where-Object {$_.Name -like "*text*"} # User this line to get info on specified VM's $VMList = $VMList | Sort-Object -Property Name # Sort the VM list on alphabetical order $Counter = 1 $Report = @() While ($Counter -lt $VMList.Count) { ForEach ($VM in $VMList) { Write-Host $Counter"/"($VMList).Count "[$VM]" $VMView = $VM | Get-View $VMNICs = (Get-NetworkAdapter -VM $VM) $VMInfo = { } | Select-Object Name, PowerState, HardwareVersion, vCenter, Host, Cluster, ToolsStatus, GuestOS, NumCPU, MemGB, NumNICs, NIC0Type, NIC0IP, NIC0Mac, NIC1Type, NIC1IP, NIC1Mac, NIC2Type, NIC2IP, NIC2Mac, NIC3Type, NIC3IP, NIC3Mac, Folder $VMInfo.Name = $VM.Name $VMInfo.HardwareVersion = $VM.HardwareVersion $VMInfo.ToolsStatus = $VMView.Guest.ToolsStatus $VMInfo.GuestOS = (Get-VMGuest -VM $VM).OSFullName $VMInfo.NumCPU = $VM.NumCpu $VMInfo.MemGB = $VM.MemoryGB $VMInfo.Host = $VM.VMHost.Name $VMInfo.Cluster = $VM.VMHost.Parent.name $VMInfo.Folder = $VM.Folder.Name $VMInfo.PowerState = $VM.PowerState $VMInfo.NumNICs = $VMNICs.Count $VMInfo.NIC0Type = $VMNICs.Type[0] $VMInfo.NIC0IP = $VM.Guest.IPAddress[0] $VMInfo.NIC0Mac = $VMNICs.MacAddress[0] $VMInfo.NIC1Type = $VMNICs.Type[1] $VMInfo.NIC1IP = $VM.Guest.IPAddress[1] $VMInfo.NIC1Mac = $VMNICs.MacAddress[1] $VMInfo.NIC2Type = $VMNICs.Type[2] $VMInfo.NIC2IP = $VM.Guest.IPAddress[2] $VMInfo.NIC2Mac = $VMNICs.MacAddress[2] $VMInfo.NIC3Type = $VMNICs.Type[3] $VMInfo.NIC3IP = $VM.Guest.IPAddress[3] $VMInfo.NIC3Mac = $VMNICs.MacAddress[3] $VMInfo.vCenter = $VM.Uid.Substring($VM.Uid.IndexOf('@') + 1).Split(":")[0] $Report += $VMInfo $Counter++ } } $Report | Export-Csv "$Outputfile.csv" -NoTypeInformation -UseCulture Disconnect-VIserver $vCenterServers -Confirm:$False |
As always, please keep in mind this script is tailored to my environment, but can be used as a template for your environment. I do not pretend to be a PowerShell guru and as such my script may not be perfect. I am open to suggestions 🙂
If you found this script useful, I’d appreciate it if you leave a comment.
Works a treat. Thank you very very much!!