PowerCLI by VMWare is becoming the ubiquitous interface for hypervisor virtualization administrators of ESXi supported hardware. Learning how to manage VMware via PowerShell and PowerCLI is a strong addition to your toolkit. In this PowerCLI tutorial, you’re going to learn how to do just that.
Not a reader? Watch this related video tutorial!In this tutorial, you will learn:
- the basics of connecting to VMware infrastructure with PowerCLI
- familiarize yourself with cmdlets for working with VMware objects
- empower yourself with the knowledge to explore
- manage VMware further via PowerCLI
Let’s get to it!
What You Need to Have and Know
Before you get too far in this PowerCLI tutorial, it’s always important to ensure you and I are both on the same page. For this article, I’m going to be assuming that:
- You have basic PowerShell experience. You don’t have to be a PowerShell expert, by any means, but any PowerShell familiarity you have will serve you well.
- You have a VMware ESXi host or vCenter appliance for connecting to and testing
- You’re working on a Windows (Or Mac / Linux) workstation
- You have PowerCLI already installed and are connected. If not, check out this PowerCLI installation article.
I’ll be using PowerCLI v 11.4.0. I will be working from a Windows 10 workstation with Windows PowerShell 5.1, but you’re welcome to use PowerShell 6 instead as there’s feature parity for this tutorial.
Gather Information on ESXi Hosts with PowerCLI
Before you dive into the virtual layer of our vSphere environment, it is a good idea to review the physical hardware layer. VMware PowerCLI provides a cmdlet directly for this purpose, to gather detailed information called Get-VMHost
.
While you’re connected to your vCenter server or ESXi host, run the following cmdlet.
PS51> Get-VMHost
Since I am connected to a vCenter Server Appliance which is managing two separate ESXi hosts, I am provided with some basic information about the hosts being managed. The Get-VMHost
allows you to review the hardware capabilities of your virtualization hosts. But, by default, Get-VMHost
doesn’t return all the information it can.
If you pipe the Get-VMHost
cmdlet to Format-List
, you will get console output for all information about the given hosts.
Alternatively, you can be pickier and only select individual properties on the VMHost object you’re working with like:
PS51> Get-VMHost | format-list -Property State,LicenseKey,Version
Leveraging this more verbose output will provide an even greater view of the underlying hardware running your virtualized workloads. Some of the information, in particular, would be:
- License validation info
- CPU/Memory totals
- Hardware vendor model
- DNS hostname
After review, this can be compiled into a CSV file perhaps using the Export-CSV
cmdlet.
Inspecting VMs with PowerCLI
Let’s now dive into another topic in this PowerCLI tutorial by reviewing virtual hosts is reviewing which virtual machines are currently present on a given ESXi host.
The Get-VM
command is a handy command you can use to review VM information.
PS51> Get-VMHost -Name <Host FQDN> | Get-VM
The output of this cmdlet will look something like below:
The output above provides a full status list of currently running VMs on a given host. If you were to choose to not specify an individual host, as I have done above, you’ll receive a table of information for each subsequent host and the VMs on each.
If you are ever troubleshooting an issue and need to know the number of virtual machines on a given host or have a need to use VMware PowerCLI to gather ESXi host information, you can use these cmdlets going forward. The reporting functionality you have at your fingertips is starting to expand!
Inspecting Virtual Switches with PowerCLI
For those of us charged with configuring or administering the virtual networks of a vCenter cluster, there is a full range of networking cmdlets for any use case. If you wish to see the virtual switches configured in your vSphere environment, you will use the following:
PS51> Get-VirtualSwitch
Depending on the number of virtual networks and virtual switches you have, your resulting list may be quite large. In my case, as you see below, I have a single DSwitch which is a Distributed Virtual Switch.
In an Enterprise vSphere implementation where there are many ESXi hosts in a cluster, DSwitches simplify the deployment of virtual switches and port groups across a multitude of hosts with the same configuration. This saves on the manual labor of creating identical network configurations on each host manually, and is a great way to scale your cluster!
Finding VMs Attached to a Virtual Network with PowerCLI
While attempting to narrow down the scope of an issue, you may wonder which VMs are connected to which networks. To figure that out, you can use the Get-VirtualPortGroup
command. Let’s learn about this cmdlet in this PowerCLI tutorial.
A port group is essentially a virtual network. To display all port groups, run Get-VirtualPortGroup
without any parameters. You should then see a listing of all virtual port groups present in your vSphere environment.
To find all of the VMs inside of that port group (DPortGroup in my case), you can run the below script. Be sure to replace the value DPortGroup with the name of your Virtual Port Group.
PS51> Get-VM | Where-Object { ($PSItem | Get-NetworkAdapter | where {$_.networkname -match "DPortgroup"})}
In this one-liner, we are getting a list of all virtual machines that exist in this vCenter appliance, and then filtering with the Where-Object
cmdlet to get only those VMs with a network name that matches our Port Group.
With this output, you’ll be able to define what machines are connected and configured for each network.
When asked to locate and analyze which VMs are connected to a particular network in VMware you will now be empowered to provide a PowerCLI reporting solution to this question.
Getting OS Version Information on your VMs with PowerCLI
The bulk of administrative work inside of VMware is done at the virtual machine level. You’re likely to receive countless requests for tasks like retrieving a list of all hard drive sizes on VMs or getting guest OS versions for all your servers among others.
These tasks are cumbersome at scale. PowerCLI is able to streamline these with a few important cmdlets to add to your arsenal so let’s cover them in this PowerCLI tutorial.
You may have been asked at some point in time, “How many Ubuntu servers do we have in our VMware cluster?”. You might have then spent way too much time clicking around in vCenter looking for an answer. PowerCLI can streamline this process by looking at the VM objects in vCenter and applying some PowerShell magic on the output.
Take a look at the following script that pulls together VM information. This snippet uses the Get-View
command which we will go into a bit later but for now, you should know that it is an advanced way to retrieve VMware object properties. In this case, we’re gathering nested properties that are most easily retrieved in this method.
PS51> Get-VM |
Sort-Object -Property Name |
Get-View -Property @("Name", "Config.GuestFullName", "Guest.GuestFullName") |
Select-Object -Property Name, @{N="Configured OS";E={$_.Config.GuestFullName}}, @{N="Running OS";E={$_.Guest.GuestFullName}}
The above code is retrieving a list of virtual machines via the PowerCLI Get-VM
cmdlet, sorting said list with the PowerShell Sort-Object
cmdlet, and then retrieving some of the object properties using the PowerCLI Get-View
cmdlet.
Running this in my environment yields the result below. You can see the name of the VM in vCenter, the Configured OS
which is how VMware’s virtual hardware is set to interpret the guest operating system, and the actual Running OS
that represents the actual OS.
With the VMs replicant and Scriptrunner are powered off in the cluster, you will not be able to see the Running OS
value for them. The OS is gathered by the VMware Tools service. If it’s not available, PowerCLI cannot pull the operating system information.
Creating CSV Reports with PowerCLI
VMware Tools is an in-guest service for both Windows and Linux VMs that provides the hypervisor additional information and administrative capabilities. Most commonly this will provide clean-shutdown, operating system information, and higher resolution console viewing of the VMs.
A convenient way to report on and provide this information would be to pipe the above script into the Export-CSV
cmdlet. Export-Csv
will create a CSV file with the same information you see in the console.
PS51> Get-VM | Sort-Object -Property Name | Get-View -Property @("Name", "Config.GuestFullName", "Guest.GuestFullName") |
Select -Property Name, @{N="Configured OS";E={$_.Config.GuestFullName}}, @{N="Running OS";E={$_.Guest.GuestFullName}} | Export-CSV C:\report.csv -NoTypeInformation
After running the above code, you should then be able to open the CSV file with Excel to review the report.
Inspecting Virtual Hard Disks with PowerCLI
The Get-Harddisk
command is another useful command to know. The Get-HardDisk
cmdlet allows you to inspect information about virtual hard disks attached to VMs.
For example, to query information about the virtual hard disk attached to the exchange1 VMs, you could run the following:
PS51> Get-VM -Name exchange1 | Get-HardDisk | Format-List
Some of this information may be redundant, such as the capacity in KB vs. GB. But there is value in knowing the StorageFormat
(thin/thick provisioning types). And knowing the VMDK file name.
For example, ff you see a common issue and all VM hard disks reside on the same datastore volume, this knowledge may expedite troubleshooting.
Inspecting Virtual Network Adapters with PowerCLI
In addition to reviewing hard disk information of your virtual machines, you may also want to check on the virtual network adapters. To check on these properties for a single VM, you can use the Get-NetworkAdpter
cmdlet.
PS51> Get-NetworkAdapter -VM myVM
While you had hunted earlier in this port for all VMs residing in the same network, this time you only want to see the adapters connected to a particular VM.
This is useful if troubleshooting VMs that have multiple network adapters connected. You can quickly and at a glance determine if those adapters are connected to the proper networks.
Running PowerShell Scripts in VMs with Invoke-VMScript
Using the Invoke-VMScript
, you can also run PowerShell code directly inside of the VM; no network connectivity necessary. If you have ever used PowerShell Direct within a Hyper-V environment, this will be a similar experience.
Instead of creating a PowerShell Remoting session or using the Invoke-Command
cmdlet over the network, the Invoke-VMScript
cmdlet can send commands directly to the VM without normal WinRM or SSH connectivity.
As an example, perhaps you’d like to perform a simple directory listing on a VM called exchange1. To do so, you would pass dir C:\
as the value for the ScriptText
parameter as shown below.
PS51> Invoke-VMScript -VM exchange1 -ScriptText "dir C:\"
The results are as if you had run the commands from the VM console itself. Invoke-VMScript
then relays all of the output the command that was run on the VM returns.
While this is a basic example, you can get as complicated as you would like. This PowerCLI cmdlet allows you to specify batch, PowerShell, or Bash types within the ScriptText
parameter.
You can get more advanced as well. Below you can see how to use Invoke-VMScript
to run PowerShell code using a separate $script
variable for the ScriptText
parameter input. This allows us to create more customized script input for the VM to process.
PS51> $script = 'Get-Disk'
$guestCredential = Get-Credential
Invoke-VMScript -ScriptText $script -VM VM -GuestCredential $guestCredential -ScriptType Powershell
The ScriptText
parameter value needs to a string. This is why the $script
variable has the single-outer-quotes as a necessity.
You may have also noticed the use of the GuestCredential
parameter. This parameter is used to authenticate into the VM operating system. This parameter is especially useful if you want to run the script as a different account.
Your script in action should result in output similar to below.
The result of this script provides us with the VM’s disk information. Based on that, you should know it’s a remote VM because of the VMware Virtual Disk
as the friendly name of the drive.
Getting Advanced with Get-View
You may have seen some of the basic cmdlets return a property called ExtensionData
. You can find this property by piping many PowerCLI cmdlets to the PowerShell Get-Member
cmdlet. If you were wondering what that was, now’s your chance to find out.
The next step in this venture is understanding the Get-View
cmdlet. VMware PowerCLI leverages many different queries to the VM to provide the pretty and simple output of Get-VM
. But there is a lot under the hood that is only accessible by using the Get-View
cmdlet.
You’re likely to see a lot of scripts using this cmdlet. It would behoove you to spend some time getting used to seeing this cmdlet in action. To familiarize yourself, use the Get-View
cmdlet to get some virtual machine information (exchange1 in this example).
You can see the Filter
options of this cmdlet require the use of a PowerShell hashtable and not individual string values. Be aware when building your own unique scripts!
PS51> Get-View -ViewType VirtualMachine -Filter @{"Name" = "myVMName"}
The result of the command above is a lot of nested configuration information and method options for taking actions against the VM or getting object properties.
If you use the same script above and send the output to a variable, you can inspect those nested options with dot notation. Here you can see and retrieve all of that additional information of the guest operating system, that you may want to report on via PowerCLI.
PS51> $VM = Get-View -ViewType VirtualMachine -Filter @{"Name" = "myVMName"}
PS51> $VM.Guest
Perhaps you’d like to select a single property. If so, you could run the following to narrow down an individual value.
PS51> $VM.Guest.GuestFullName
There are many Get-View
options for all types of VMware objects. Feel free to explore all of these options and review this informative article from VMware that goes in-depth on this powerful cmdlet!
VMware Code Capture – Learn from your Clicks
If you’d like to take advantage of PowerCLI but would rather not build code by typing, Code Capture in vCenter is here for you. Code Capture is a new developer tool that acts similarly to the Active Directory Administrative Center. Let’s cover Code Capture in this PowerCLI tutorial.
This tool records all actions you take within the GUI. It then transforms all of those actions and provides you with PowerCLI scripts.
By default, Code Capture is not turned on. To turn it on, open up your vCenter appliance and navigate to Menu –> Developer Center as shown below.
Once at the Developer Center tab, toggle the Enable Code Capture option.
When you enable Code Capture, you will then see a red Record button within your vCenter header. Once enabled, whenever you wish to have an action recorded and turned into PowerCLI output you must record the GUI activity by hitting the record button.
The red record button will appear next to your logged on user section of vCenter so that you can now record at any time.
To demonstrate Code Capture, go through the New Virtual Machine creation wizard.
- Click on the Record button to begin recording. This will cause the red Record button to begin pulsing.
- Right-click your VMware host, and Create a New Virtual Machine. Run through the resulting wizard creating a new virtual machine with all default values.
- Once the virtual machine is created, click on the record button and stop your recording.
The resulting output may be slightly more verbose than anticipated. The output even includes all actions of browsing the GUI before creating the VM. But you should see a section denoted in the comments starting with CreateVM_Task
. This is where the code begins to create a VM.
Below is a portion of the CreateVM_Task output of the New VM Wizard process in the GUI via Code Capture:
This output can be a little overwhelming, but it exposes you directly to the number of configuration options available to your virtual machines. Depending on your own needs, you’re now empowered to make adjustments in your own scripts and customize to your heart’s content.
The Code Capture utility isn’t limited just to VM creation. It can also build code for networking changes, small VM modifications, or host configuration changes. By being able to review the PowerCLI output of GUI actions you can take a shortcut on your journey to infrastructure deployed as code.
PowerCLI Tutorial Summary
In this article, you covered a lot of ground. Nice job! I hope that you’ve realized the power that PowerCLI brings to managing VMware infrastructure.
There are a lot of cmdlets in PowerCLI for a wide range of product bases but we only covered a few here. Be sure to stay tuned to this blog for more articles on this awesome tool!