How to use PowerCLI to obtain information and adjust settings in vCenter, including examples..

Table of Contents

Synopsis

PowerCLI has been a mainstay for automating all things VMware for a very long time. PowerCLI can be an extremely powerful tool but highly frustrating if you don’t understand it. As I have progressed through my career I have gone from someone who was confused and frustrated to someone who completely loves PowerCLI. I hope this document can take some who are in the first group and move them into the second group. As you get into PowerCLI you will find the information I have included here just scratches the surface, for more information please reference VMware’s Cmdlets reference guide.

Syntax

As with all API and coding syntax is king! If you have the syntax incorrect then you will end up making incorrect calls and either get no results or invalid results. Keeping that in mind, after we connect to our vCenter(s) we will need to make calls out, these calls are typically one of two major groups, “Get-VMhost” and “Get-VM”. Both of these calls pull specific information for either the hypervisor(s) or VM(s). We can group these results by also using calls for other objects (ie. - datacenters, resource pools, clusters, etc) by using “Get-Datacenter”, “Get-Resourcepool” or “Get-Cluster” at the beginning of the call. To put these together to call for specific information we would use them like this:

Get-Datacenter -Name My-DC-Name | Get-VMhost
Get-Resourcepool -Name My-Resourcepool-Name | Get-VM

Generally speaking PowerCLI is not case sensitive. For example, you can use either “Get-Datacenter” or “get-datacenter” as they are both considered equal within PowerCLI on Windows. However, when it comes to the specific objects where you are specifying a name, it is recommended to keep the case the same. For example, if your datacenter is called “MyDataCenter” within the vCenter then you will want to keep the case, do not try “mydatacenter” as this is not an accurate representation of the name.

NOTE: Basic groupings can be done via specific get case-insensitive requests, “Get-Datacenter” “Get-Resourcepool” “Get-Cluster” and many others.

Obtain more details.

After connecting to our vCenter(s) if we run the command “Get-Datacenter -Name My-DC-Name | Get-VM” there is a lot of information that is returned, however not all possible information will be included. A general set of detailed information about your VMs will be returned but you will find details about them missing, for example no IP addresses are listed. With a little knowledge from the PowerCLI calls we find that this information is obtainable via a “select” statement. To put these together to call for specific information we would use them like this:

Get-Datacenter -Name My-DC-Name | get-vm | Select name,@{N="IP Address";E={@($_.guest.IPAddress)}}

NOTE: Select statements allow you to pull additional information not normally viewable with basic calls.

It is very important that if a variable within your configuration has a space in it that you surround it with parenthesis. For example, if you have a datacenter called Older Hypervisors the you will need to specify that datacenter as “Older Hypervisors”.

NOTE: Use parenthesis to properly call objects with a space or special characters in them.

Output viewing.

There are four basic ways which we can view our output: default, format-list, out-gridview, and export to file. Each of these has their own quirks but all are highly usable. The first one, default, requires no additional calls as it is simply the default output. The output will be displayed within the PowerCLI window and fully depends on how many variables being called as to how easy or hard it is to read the results. For example, if you are just trying to get the list of all VMs and their CPU allocation, then this result will be sufficient for most. However, if you are getting a full list of VM details then you will see a lot of fields are truncated which leaves your results lacking.

This is when we can bring in “format-list” at the end of the call line. This call puts the results in a nicely formatted view within the PowerCLI window. While these results are great, if you are going to try to put them into a formatted email or doc then this will require a lot of re-work with the copy/paste. It also does not allow you to sort the results within the window once they are outputted, this means you have to drop them into another tool in order to facilitate that work.

If we want to be able to sort the results or have them in a more usable format then we move onto out-gridview. When adding this in we now get a brand new popup box that is displaying the results of our call. The columns are now sortable and we can even remove columns as needed. This allows us a much easier time in displaying the exact results we want and copy/pasting from this window is extremely easy.

Last way of viewing the results is to export the output to a csv file. With large returns or a requirement to send the information in a more usable format this is typically the default method used. It is critical that a file path and name are provided when using this method and the user running powershell requires access to create a new file within the directory specified. The CSV file can easily be used or modified within any spreadsheet tool like excel or openoffice.

In summary, there are three advanced ways to display the data from a get request:

 | format-list
 | out-gridview
 | export-csv -path C:\Output\Output.csv

One line PowerCLI references.

Now onto the exiting part, using the PowerCLI itself. Whenever we want to run these commands we will first want to launch the PowerCLI interface, either 64-bit or 32-bit will work. Once the interface is started we will need to connect to our vCenter. When we connect it is suggested to use the same DNS name used for the SSL certificate configured for vCenter, this way no certificate errors are displayed, but it is not a hard requirement. Example: If your vCenter is configured with a valid SSL certificate and a DNS entry for vcenter.nuthouse.us then connect via that name. You can also connect via the IP address of the vCenter but an SSL error will be displayed. When you connect it will prompt you for a username/password. It is always recommended that you use an administrator account so that all expected results are returned. For security compliance I recommend an ldap user or user specifically created @vsphere.local to do this and avoid the administrator@vpshere.local account.

Connect-VIServer vcenter.nuthouse.us

Now that you are authorized on your vCenter we can start to run the commands. Here are the commands that I have used most often in order to get various bits of information from my vCenters.

NOTE: Remember that you can change the output type to one of those listed above for easier viewing and/or sorting.

VM Specific Calls:

Return VM Details (more) for all the VMs within the datacenter “My-DC-Name”

Get-Datacenter My-DC-Name | get-vm | Select @{N="DnsName"; E={$_.ExtensionData.Guest.Hostname}}, Name, NumCpu, MemoryMB, ProvisionedSpaceGB, UsedSpaceGB, @{N="IP Address";E={@($_.guest.IPAddress)}}, Guest | export-csv -path C:\Output\Output.csv

Return VM Details (Less) for all the VMs within the datacenter “My-DC-Name”

Get-Datacenter My-DC-Name | get-vm | Select Name, NumCpu, MemoryMB | out-gridview

Return VM tools version for all VMs within the datacenter “My-DC-Name”

Get-Datacenter My-DC-Name | get-vm | % { get-view $_.id } | select Name, @{Name="ToolsVersion"; Expression={$_.config.tools.toolsVersion}},@{ Name="ToolStatus"; Expression={$_.Guest.ToolsVersionStatus}},@{Name="Version"; Expression={$_.Config.Version}} | out-gridview

Hot-Plug enabled for all the VMs within the datacenter “My-DC-Name”

Get-Datacenter My-DC-Name | get-vm | % { get-view $_.id } | select Name, @{N="CPU Hot Add Enabled";E={$_.Config.CpuHotAddEnabled}}, @{N="CPU Hot Remove Enabled";E={$_.Config.CpuHotRemoveEnabled}}, @{N="Memory Hot Add Enabled";E={$_.Config.MemoryHotAddEnabled}} | out-gridview

VM Tools and Hot-Plug for all the VMs within the datacenter “My-DC-Name” (This combines the two previous commands)

Get-Datacenter My-DC-Name | get-vm | % { get-view $_.id } | select Name, @{Name="Hardware Version"; Expression={$_.Config.Version}}, @{Name="ToolsVersion"; Expression={$_.config.tools.toolsVersion}},@{ Name="ToolStatus"; Expression={$_.Guest.ToolsVersionStatus}},@{Name="Version"; Expression={$_.Config.Version}}, @{N="CPU Hot Add Enabled";E={$_.Config.CpuHotAddEnabled}}, @{N="CPU Hot Remove Enabled";E={$_.Config.CpuHotRemoveEnabled}}, @{N="Memory Hot Add Enabled";E={$_.Config.MemoryHotAddEnabled}} | out-gridview

Return VM Name and IP addresses for all the VMs within the datacenter “My-DC-Name”

Get-Datacenter My-DC-Name | get-vm | Select name,@{N="IP Address";E={@($_.guest.IPAddress)}} | out-gridview

Return VM Datastore Location for all the VMs within the datacenter “My-DC-Name”

Get-Datacenter My-DC-Name | get-vm | [-Datastore <Datastore[]>] [-Location <VIContainer[]>] | Format-Table -AutoSize

Return vSockets, Cores/Socket and Total CPU, RAM in MB for all the VMs within the datacenter “My-DC-Name”

Get-Datacenter My-DC-Name | get-vm | % { get-view $_.id } | Select Name, @{N="vSockets";E={[math]::Round($_.Config.hardware.NumCPU/$_.Config.hardware.NumCoresPerSocket)}}, @{N="Cores/Socket";E={$_.Config.hardware.NumCoresPerSocket}}, @{N="Total CPUs";E={$_.Config.hardware.NumCPU}}, @{N="MB RAM";E={$_.Config.hardware.MemoryGB}} | out-gridview

Return VM Snapshot Tree Details for all the VMs within the datacenter “My-DC-Name”

Get-Datacenter My-DC-Name | get-vm | get-snapshot | Select VM, Created, Description, Name, SizeGB, PowerState | export-csv -path C:\Output\Output.csv

VM Network Adapater Type for all the VMs within the datacenter “My-DC-Name”

Get-Datacenter My-DC-Name | Get-VM | Get-NetworkAdapter | Select @{N="VM";E={$_.Parent.Name}},Name,Type | out-gridview

Checks for memory limits for all the VMs within the datacenter “My-DC-Name”

Get-Datacenter My-DC-Name | Get-VM | Get-VMResourceConfiguration | where {$_.MemLimitMB -ne "-1"} | out-gridview

Return VM UUID by VM Name:

Get-vm -Name "Full-VM-Name" | foreach-object { write-host "$_.Name `t" (get-view $_.Id).config.uuid }

Return UUIDs for all VMs by Datacenter:

Get-Datacenter My-DC-Name |  Get-vm | foreach-object { write-host "$_.Name `t" (get-view $_.Id).config.uuid }

Return UUIDs for all VMs by Resource Pool within a datacenter:

Get-Datacenter My-DC-Name | Get-ResourcePool -Name My-Resource-Pool-Name | Get-vm | foreach-object { write-host "$_.Name `t" (get-view $_.Id).config.uuid }

Return which hypervisors the VMs are running on:

Get-Datacenter My-DC-Name | get-vm | select name,host

Return if vShield Agent is installed on the VMs:

Get-Datacenter My-DC-Name | get-vm | Select Name,@{N="vShield Agent present";E={$output -match "vnetflt"}}

Hypervisor Specific Calls:

Return hypervisor hardware information and patch level:

Get-Datacenter My-DC-Name| Get-VMHost | Select Name,Version,Build,Manufacturer,Model,NumCpu,ProcessorType,MemoryTotalGB | export-csv -path C:\Output\Output.csv

Return DRS rules for a specific datacenter:

Get-Datacenter -Name My-DC-Name | Get-Cluster | Get-DrsRule | Select Name, Enabled, Mandatory, Type, Cluster, KeepTogether, VMIDs

Return pathing policies for all LUNs:

Get-Datacenter My-DC-Name | Get-VMhost | Get-ScsiLun -LunType disk | Select VMHost, CanonicalName, Vendor, Model, RuntimeName, CapacityGB, MultipathPolicy | out-gridview

Return hypervisors with vMotion enabled and the ports it is enabled on in a specific datacenter:

Get-Datacenter My-DC-Name | Get-VMHost | Get-VMHostNetworkAdapter | Where {$_.VMotionEnabled -eq "True"} | select VmHost,IP,Name,Mac

Return hypervisors with vMotion enabled and the ports it is enabled on in a specific HA/DRS cluster:

get-cluster "My HA DRS Cluster Name" | Get-VMHost | Get-VMHostNetworkAdapter | Where {$_.VMotionEnabled -eq “True”}

Return IP information for vmk0 in HA/DRS cluster:

get-cluster "My HA DRS Cluster Name" | Get-VMHost | Get-VMHostNetworkAdapter -Name vmk0

Disables vMotion for vmk0 in HA/DRS cluster:

get-cluster "My HA DRS Cluster Name" | Get-VMHost | Get-VMHostNetworkAdapter -Name vmk0 | Set-VMHostNetworkAdapter -VMotionEnabled $false

Return various Load Balance policy on virtual switches:

Get-Datacenter -Name 933624 | get-vmhost | ForEach-Object -Process {Tee-Object -InputObject $_ -Variable Temp | Get-VirtualSwitch -name vSwitch3 | Get-NicTeamingPolicy | Select @{N="VMHost";E={$Temp.Name}},ActiveNIC, LoadBalancingPolicy} | out-gridview
Get-Datacenter -Name 933624 | get-vmhost | Get-VirtualSwitch -name vSwitch3 | Get-NicTeamingPolicy | Select VirtualSwitch, ActiveNIC, LoadBalancingPolicy | out-gridview
Get-Datacenter -Name 933624 | get-vmhost | Get-VirtualSwitch -name vSwitch3 | Get-NicTeamingPolicy | Select VMHostID, VirtualSwitchID, VirtualSwitch, ActiveNIC, NetworkFailoverDetectionPolicy, FailbackEnabled, NotifySwitches, LoadBalancingPolicy

Return UUID by Hypervisor Name:

Get-vmhost “full-hypervisor-name” | get-view | %{ $_.Summary.Hardware} | Select Uuid

Return all accounts with “ReadOnly” permissions from vCenter:

Get-VIPermission | Where {$_.Role –eq “ReadOnly”} | Select Role, Principal, Entity, UID | Export-CSV C:\Output\Output.csv

Perform Actions against configurations.

Since PowerCLI is simply an API call to the vCenter we can also execute commands against hypervisors and VMs. There are many of these out there and here are a couple of examples.

Add hypervisor to vCenter:

Add-VMHost "FQDN" -Location "Cluster/DC/Folder" -User root -Password <PW> -force

Create new port groups:

get-cluster "My HA DRS Cluster Name" | get-vmhost | get-virtualswitch -name "vswitch0" | new-virtualportgroup -name "New-Network-VLAN936" -VLanID 936 

There are many more available and I hope to write a document for them in the future.