| |

Protecting your Citrix desktops on Nutanix using powershell

3 min read

Another week, another idea comes up to check if I could make it happen with Powershell. I wanted to write a script that checks my current machine catalog and puts VMs that are not in a Nutanix Protection Domain in a PD to make sure that we can protect those VMs using the policies Nutanix offers.

The following tasks had to be automated using powershell:

  • Check if a machine catalog is persistent
  • Get all desktops in the machine catalog
  • Check if there’s a Nutanix Protection Domain available with a certain prefix (read more here).
  • Check if the VM isn’t already protected
  • Check if the VM can be added there
    • If so: Add the VM
    • If not: create a Protection Domain and add the VM(s) there

I took the liberty of borrowing bits and pieces of Steven Poitras that is published on the Nutanix GitHub here:NTNX-Protect-VM.ps1 (Powershell script) and Sandeep has been helped me by answering my questions patiently. 

 

Here’s the script:

<# 
.SYNOPSIS 
Will fetch all desktops from a machine catalogs and put them into protection domains 
.DESCRIPTION 
Will fetch all desktops from a machine catalogs and put them into protection domains but it will asume at least one PD with the prefix is there.
.EXAMPLE 
PS C:\PSScript > .\XD_PD_v1.ps1
.INPUTS
None.  You cannot pipe objects to this script.
.OUTPUTS
No objects are output from this script.  
.NOTES
NAME: XD_PD_v1.ps1
VERSION: 1.0
AUTHOR: Kees Baggerman with some help from Sandeep MP and Steven Potrias a
LASTEDIT: August 2017
#>

[CmdletBinding(SupportsShouldProcess = $False, ConfirmImpact = "None", DefaultParameterSetName = "") ]

Param(      
    # Nutanix cluster IP address
    [Parameter(Mandatory = $false)]
    [Alias('IP')] [string] $nxIP,
    # Nutanix cluster username
    [Parameter(Mandatory = $false)]
    [Alias('User')] [string] $nxUser,
    # Nutanix cluster password
    [Parameter(Mandatory = $true)]
    [Alias('Password')] [Security.SecureString] $nxPassword
    )

# Importing the proper cmldlets and snapins
Import-Module "C:\Program Files (x86)\Nutanix Inc\NutanixCmdlets\Modules\NutanixCmdletsPSSnapin.dll"
Add-PSSnapin Nutanix*, Citrix*

# Defining script variables
$DDC = ""
$nxIP = ""
$nxUser = ""
$pdPrefix = "XenDesktop-PD"
$vmPerPD = ""
$MachineCatalog = ""

# Connecting to the Nutanix Cluster IP
Connect-NutanixCluster -Server $nxIP -UserName $nxUser -Password $nxPassword -AcceptInvalidSSLCerts

# Checking if the Machine catalog is persistent
$persistentMCs = Get-BrokerCatalog | where {$_.PersistUserChanges -eq "OnLocal"}

if($persistentMCs.name -match $MachineCatalog) {

# Collecting the Persistent Machine Catalog and putting them into a variable
$VMs = get-brokermachine -adminaddress $ddc -CatalogName $machinecatalog

foreach ($VM in $VMs) {
        $VMName = $VM.MachineName.Split("\")[1]

        # Get existing PDs matching prefix
        $pds = Get-NTNXProtectionDomain | where {$_.name -match $pdPrefix} 

        # Get Un-protected VMs
        $unProtectedVM = Get-NTNXUnprotectedVM | where {$_.vmName -eq $VMName}

        # Stop the script when there's no unprotected VMs
        if ($unProtectedVM.count -gt 0) {
            Write-Host "Found $($unProtectedVM.count) unprotected vms..."
        } else {
            Write-Host "No unprotected VMs found, exiting..."
        break

        }
        # Getting the PDs count and determine next action
        if ($pds.Count -gt 0) {
        
        # Matching PDs exist
            Write-Host "Found $($pds.Count) matching existing PDs with space..."
    
          [int]$existingPDSpace = 0
    
        # Find available space in existing PDs
        $pdsWithSpace = $pds | where {($_.vms).count -lt $vmPerPD}
    
        $pdsWithSpace | %{
        
        # Find available space
        $l_pdSpace = $vmPerPD - ($_.vms).count
        
        # Add available space to counter
        $existingPDSpace += $l_pdSpace
        }
    
        # Find starting increment from existing
        $startingInt = (($pds.name).split("-") -match "^[0-9]+$" | measure -Maximum).maximum + 1
        } else {
            Write-Host "Found $($pds.Count) matching existing PDs with space..."
            $startingInt = 0
        }
        
        # Find needed space
        $newPDSpace = if ($existingPDSpace -lt $unProtectedVM.Count) {$unProtectedVM.Count - $existingPDSpace}

        # Find number of new PD required
        $numNewPD = [Math]::Round($newPDSpace/$vmPerPD)

        # Create $numNewPD Protection Domains
        $pdsWithSpace | %{
            
        # Get avail space
        $l_availSpace = $vmPerPD - ($_.vms).count }

        # Find number of new PD required
        $numNewPD = [Math]::Round($newPDSpace/$vmPerPD)

        # Create $numNewPD Protection Domains
        Write-Host "Creating $numNewPD new PDs..."

        if ($numNewPD -gt 0) {
            for($i = 0;$i -lt $numNewPD;$i++)
            {
                       # $l_pdName = $pdPrefix+"-"+$i
                       $l_pdName = "$pdPrefix-$i"

         # Create PD
         Write-Host "Creating PD: $l_pdName"
         $l_PD = Add-NTNXProtectionDomain -value $l_pdName
        
        # Add cron schedule to PD
        $pdsWithSpace += $l_PD
         }
        }
            $pdsWithSpace | %{
        # Get avail space
        $l_availSpace = $vmPerPD - ($_.vms).count }
        
        # Add VMs to PD (either existing or new)
        if ($Pds.name -notmatch $pdPrefix) {
        Write-Host "Adding $($l_vmObj.count) VMs to PD: $($_.name)"
        Add-NTNXProtectionDomainVM -Name $VMName -PdName $($_.name)
        }
        else {
        Write-Host "Adding VMs to PD: $($pds.name)"
        Add-NTNXProtectionDomainVM -Name $VMName -PdName $($pds.name)
        }

        break
        }
        }
        else { write-host "No persisent machine catalog defined"}

 

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

One Comment

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.