VM Management through Power CLI and C#

Posted in software by Christopher R. Wirz on Tue Feb 06 2018



PowerCLI is VMware's client automation library for Windows PowerShell. This module has many dependencies, most importantly VMware.VimAutomation.Core. It is featured in PowerShellGallary, meaning that if you have PowerShellGet (like NuGet, but for PowerShell), it can be installed from the PowerShell prompt.

Note: In this article, all commands must be issued in PowerShell, not from the command prompt. It is also assumed that PowerShellGet is installed.

Using PowerShellGet from the PowerShell prompt, PowerCLI can be installed as follows:


Install-Module -Name VMware.PowerCLI -RequiredVersion 6.5.4.7155375 

From there, VM roll-back and power on can be demonstrated.


# Do not participate in giving feedback
Set-PowerCLIConfiguration -Scope User -ParticipateInCEIP $false -Confirm:$false

# Login (do not specify https:// or /sdk in the server parameter)
$server = Connect-VIServer -Server 'ip.address' -User 'username' -Password 'password' -Verbose

# Get the VM by name
$vm = Get-VM -Name "vmName"

# Only modify the VM if it is Powered Off (not in use)
if ($vm.PowerState -eq "PoweredOff") {  #Better than saying (-not ($vm.PowerState -eq "PoweredOn"))

    # Get the latest snapshot (assumed working)
    $snap = Get-Snapshot -VM $vm | Sort-Object -Property Created -Descending | Select -First 1

    # Revert to snapshot this may return
    # "Current license or ESXi version prohibits execution of the requested operation"
    Set-VM -VM $vm -SnapShot $snap -Confirm:$false

    # Start the vm this may return
    # "Current license or ESXi version prohibits execution of the requested operation"
    Start-VM -VM $vm
}

# Log out of the server
Disconnect-VIServer -Server $server -Force -Confirm:$false # Disconnect-VIServer -Server * -Force -Confirm:$false

Although there is not NuGet package for automation in Visual Studio, the PowerShell modules will suffice. Since PowerShell's entry point has some abstraction, the C# code is a little different.

Note: Your C# project must reference
C:\Program Files\WindowsPowerShell\Modules\VMware.VimAutomation.Core\6.5.2.6234650\VMware.Vim.dll
or the currently installed version.

Ultimately, the following code could be contained within a class method:


VMware.Vim.VimClient client = new VMware.Vim.VimClientImpl();

// Add this line to ignore validation errors
System.Net.ServicePointManager.ServerCertificateValidationCallback += (se, cert, chain, sslerror) => true;

// Note the difference in how the server URI is written, it has https:// and /sdk
var session = client.Login("https://ip.address/sdk", "username", "password");
var vm = client.FindEntityViews(typeof(VMware.Vim.VirtualMachine), null, null, null)
	.Cast<VMware.Vim.VirtualMachine>()
	.FirstOrDefault(v => v.Name == "vmName");
var host = client.FindEntityViews(typeof(VMware.Vim.HostSystem), null, null, null)
	.Cast<VMware.Vim.HostSystem>()
	.FirstOrDefault(h => h.Name== "hostName");

// Only perform operations on the VM if it is off.
if (vm?.Guest?.GuestState == "notRunning")
{
	try
	{
		vm?.RevertToCurrentSnapshot(host?.MoRef, true);
		vm?.PowerOnVM(host?.MoRef);
	}
	catch (Exception ex)
	{
	// the error may state
	// "Current license or ESXi version prohibits execution of the requested operation"
	}
}

Note: If you do not have a licensed version of ESXi, you will have read-only rights and will recieve the exception
"Current license or ESXi version prohibits execution of the requested operation"