| |

Automating Citrix PVS on Nutanix AHV with PoSH

4 min read

PoSHWith the current announcement of running Citrix XenDesktop on Nutanix Acropolis Hypervisor I was really exited to start playing around with the options the Nutanix platform gives us to automate a lot of processes. Currently Nutanix provides a couple of ways to automate, one of them being good ol’ PoSH.

When we look at the current ways to interact with the Nutanix environment we basically can define 3 ways of doing so in a programmatically way:

  • REST API
  • CLI – ACLI & NCLI
  • Scripting interfaces (PoSH)

Both the scripting interfaces as the CLI follow the REST API, the REST API will be able to provide the full feature set of the Prism UI. This is important to understand as it will enable automation frameworks like Puppet, Chef, vRealize, etc to automate and orchestrate workflows within Nutanix.

Luckily Citrix PVS comes with PoSH as well, although the current implementation of the Citrix PVS PoSH cmdlets can be somewhat challenging I’ve been told that there will be a lot of focus on this in the newer release of PVS, which is available in TP. That being said, if you combine those two the easy to follow steps are as following:

  1. Create a target VM following your specifications
  2. Provide this target VM to our Image Service
  3. Run the provided script, it will search the image service for available images and it will clone the VM according to your needs.
  4. The script will then create a Target VM within the PVS console according to the naming scheme you have provided and it will fetch the MAC address from the VM and add it to the PVS console.

Although this is not fully integrated it gives you an idea of the capacities this platform has and how we can make things easier if we automate tasks.

The script:

# Both the PVS cmdlets as the Nutanix cmdlets have to be installed

Add-PSSnapin -Name McliPSSnapIn
Add-PSSnapin -Name NutanixCmdletsPSSnapin

# Connecting to the Nutanix AHV Cluster and the Citrix PVS server

Connect-NTNXCluster AAA.BBB.CCC.DDD -AcceptInvalidSSLCerts
Mcli-Run SetupConnection -p server=AAA.BBB.CCC.DDD, port=54321
 
# Create VMs in AHV

 
 ##########################
 ## Get inputs & Defaults
 ##########################
 
 # Get vms array once
 $vmid = Get-NTNXVM
 
 # Create array for clone tasks
 $cloneTasks = @()

 # Get available images
 if ($vmid.vmName -contains $image.vmName) {
 Write-Host "Image found!"
 Write-Host "$($vmid.vmName)"
 }

 # Select Image
 if ([string]::IsNullOrEmpty($image)) {
 $image = Read-Host "Please enter an image name "
 } 

 # Get VM prefix if not passed
 if ([string]::IsNullOrEmpty($prefix)) {
 $prefix = Read-Host "Please enter a name prefix and int structure [e.g. myClones-###] "
 }
 
 # Get starting int if not passed
 if ([string]::IsNullOrEmpty($startInt)) {
 $startInt = Read-Host "Please enter a starting int [e.g. 1] "
 }
 
 # If ints aren't formatted
 if ($prefix -notmatch '#') {
 $length = 3
 } else {
 $length = [regex]::matches($prefix,"#").count
 
 # Remove # from prefix
 $prefix = $prefix.Trim('#')
 }
 
 # Get VM quantity if not passed
 if ([string]::IsNullOrEmpty($quantity)) {
 $quantity = Read-Host "Please enter the desired quantity of VMs to be provisioned "
 }
 

 1..$quantity | %{
 
 $l_formattedInt = "{0:D$length}" -f $($_+$startInt-1)
 
 $l_formattedName = "$prefix$l_formattedInt"
 
 Write-Host "Creating clone $l_formattedName"
 
 # Create clone spec

 
 $spec = New-NTNXObject -Name VMCloneSpecDTO
 $spec.name = $l_formattedName
 
 foreach ($p in $vmid) {
 $task = Clone-NTNXVirtualMachine -Vmid $p -SpecList $spec
 
 $cloneTasks += $task
 
 }
}



# PARAMETERS

# hostname of one PVS Server

$pvshost ="PVSServerHostname"

# Parameters which have to be edited according to environment - check for correct silo name

$description= "Description of the vDisk"
$OU="OU=computers,DC=contoso,DC=local"

# Parameters which have to be edited according to PVS Device Collection
$collection= "PVS Device Collection Name"
$site_1= "PVS Site 1"

# Get the VM Names, the MAC addresses and create targets in PVS

$vmid = get-ntnxvm
 
 foreach ($p in $vmid) {
 $mac = get-ntnxvmnic -vmid $p
 $p.vmName
 $mac.macAddress
 Mcli-Add Device -r deviceName=$($p.vmName), collectionName=Collection, siteName=Site, deviceMac=$($mac.macAddress)
}

 

Of course you’ll need to change the cluster IP and the PVS server IP from AAA.BBB.CCC.DDD and some other variables to your own environment but the rest should work out of the box. I realise that the script itself could be enhanced to be more flexible but this is more like a demonstration of the possibilities when we start combining PoSH cmdlets.

Special thanks goes out to Pankaj Sinha who helped out with some Q&A on the script.

The following two tabs change content below.

Kees Baggerman

Kees Baggerman is Senior Technical Director — Performance & Solutions Engineering R&D at Nutanix, where he leads a global team responsible for defining how enterprise applications are delivered on the Nutanix platform. A former Citrix Technology Professional and NVIDIA Enterprise Platform Advisor, he has spent 15+ years driving EUC strategy and technical direction across architecture, product, and customer success. He has been writing here since 2011 — sharing what he learns at the intersection of platform engineering and enterprise IT.
Kees Baggerman

Kees Baggerman

Senior Technical Director at Nutanix - Former Citrix CTP - NVIDIA Enterprise Platform Advisor - 15+ years in EUC

Kees Baggerman is Senior Technical Director — Performance & Solutions Engineering R&D at Nutanix, where he leads a global team responsible for defining how enterprise applications are delivered on the Nutanix platform. A former Citrix Technology Professional and NVIDIA Enterprise Platform Advisor, he has spent 15+ years driving EUC strategy and technical direction across architecture, product, and customer success. He has been writing here since 2011 — sharing what he learns at the intersection of platform engineering and enterprise IT.

Similar Posts

2 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.