Skip to content

VMware PowerCLI

Overview

PowerCLI is a Powershell module used to manage VMware ESXi and VCenter servers. To start, install it, then run the following to configure it:

Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -ParticipateInCeip $False

This will ignore invalid certificates, which VMware servers have out-of-the-box, and disable the "Customer Experience Improvement Program" telemetry.

Note that there's a variety of ways to reference VMs, and I switch between them throughout this document, to help illustrate them. In general, it's a good idea to stick to a specific style.

Connect to Server

$powercli_creds = Get-Credentials
Connect-VIServer -Server 'esxi.for.example' -Protocol 'https' -Credential $powercli_creds

List VMs

Once connected to a server, you can run Get-VM to get a list of VMs, optionally restricting them to specific criteria, like location (-Location), or tags (-Tag), etc.

Start/Stop VMs

The Start-VM and Stop-VM cmdlet are used for this purpose:

$foo = Get-VM -Name foo
Start-VM -VM $foo
Stop-VM -VM $foo

Create Snapshot

Get-VM -Name foo | New-Snapshot -Name "Foo-Snapshot-$(Get-Date -Format FileDateTimeUniversal)"

Create Linked Clone From Snapshot

New-VM -Name LinkedToBaz -LinkedClone -ReferenceSnapshot (Get-Snapshot -Name 'To-Clone' -VM 'Baz') -VM 'Baz'

Create a Virtual Network

This one has 2 steps - Create the virtual switch, and create the port group associated with it.

$NetworkName = 'Foonet'
$vswitch = New-VirtualSwitch -Name $NetworkName -VMHost '192.0.2.127'
$vportgrp = New-VirtualPortGroup -Name $NetworkName -VirtualSwitch $vswitch

Create a Fresh VM with an OS Installer ISO

To start with, you'll want to know a few things about the VM, including the guest OS identifier PowerCLI uses.

Per this answer on VMware's VMTN Comminities, you can get a list of all valid values for this with the following:

[VMware.Vim.VirtualMachineGuestOsIdentifier].GetEnumValues()

Note that this list is long - on my setup, it has 195 entries, though I suspect that varies depending on the exact version of PowerCLI. I'd recommend piping the above command into Select-String to filter down to what you actually want - e. g. for an Ubuntu guest, I might run the following:

[VMware.Vim.VirtualMachineGuestOsIdentifier].GetEnumValues() | Select-String 'ubuntu'

If you are installing from an ISO file on the datastore, you will also want the path to the ISO file in question.

The way I found that was a bit convoluted, and as someone used to the Unix-like approach to file-systems, I found it surprising. For context, I knew that within my environment, I stored ISO files in a directory called isos on datastore2, and that the ISO file I wanted was the only one in the directory with ubuntu at the start of its name. With that knowledge, I got the path to an ISO file with the following:

$ds2 = Get-Datastore -Name 'datastore2'
$ISO = (Get-ChildItem ($ds2.DatastoreBrowserPath) | Where-Object {$_.Name -eq 'isos'} | Get-ChildItem | Where-Object {$_.Name.StartsWith('ubuntu')})

With that knowledge, and those variables defined, you can then use the following, changing the values as appropriate:

$NewVMParams = @{
  'Name' = 'ubuntu.22.04.server.base'
  'VMHost' = '192.168.7.13'
  'Datastore' = 'datastore1'
  'DiskGB' = 24
  'DiskStorageFormat' = 'Thin'
  'MemoryGB' = 3
  'GuestId' = 'ubuntu64Guest'
  'HardwareVersion' = 'vmx-17'
  'NumCpu' = 2
}
$VM = New-VM @NewVMParams

$NewCDDriveParams = @{
  'VM' = $VM
  'IsoPath' = $ISO.DatastoreFullPath
  'StartConnected' = $true
}
New-CDDrive @NewCDDriveParams
New-NetworkAdapter -NetworkName '480-WAN' -VM $VM
Start-Sleep 10s
Start-VM -VM $VM

Note that the above snippet was based on this serverfault question, replacing the deprecated Version field with HardwareVersion, which is its more modern counterpart, and changing the field values to those I actually used for my class lab. I also replaced Sleep with Start-Sleep, as the former is an alias and I'd rather use the full form in a script or in documentation and notes. I also omitted the Notes parameter for the New-VM cmdlet.

Once the OS was installed, I shut off the VM and removed the ISO using the following 2 cmdlets:

Stop-VM -VM $VM -Confirm:$false
Get-CDDrive -VM $VM | Set-CDDrive -NoMedia -Confirm:$false