Schedule Parallels RAS template updates with PowerShell

Automate the management and maintenance of templates.  

Administrators of Parallels RAS occasionally need to update templates to address system change requirements.  In this article, we’re going to show just how easy it is to use PowerShell to update RAS templates and use sample template scripts.   

What is a Parallels RAS template?  

A Parallels RAS template lets you capture the properties of an existing virtual machine (VM) to create guest VMs for publishing desktops, applications, documents, etc. Virtual desktop and Remote Desktop Session Host (RDSH) templates are essential to the Parallels RAS management features. In addition, templates provide a single place for administrators to update desktops, applications, and Windows Updates. 

What are template scripts for? 

Template scripts provide a way to schedule the release or update guest VMs after an administrator has updated the RDSH or virtual desktops template. This might be a task that the administrator wants to perform overnight or in a change window when users are not using the system. 

Here’s an example of how a script can work 

The main steps for using a script to update your template are: 

  1. Update your template by placing it into maintenance mode. 
  2. Exit maintenance mode when your updates are complete (don’t recreate it on exit). 
  3. Run the script at a scheduled time to update the guest VMs automatically. 

The template script follows these steps: 

  1. Finds any user sessions in the RDSH or VDI pool and logs them off. 
  2. Disables the RDSH Group. (RDSH servers are unregistered and removed from the RDSH Group. If it is a VDI template, the VMs are shut down.) 
  3. Enters maintenance mode. 
  4. Exits maintenance mode with updated guest VMs switch. 
  5. Recreates Guest VMs. 
  6. Enables RDSH Group. 
  7. Parallels RAS autoscaling adds RDSH servers back into the group and registers them in the Parallels RAS Console. 

Instructions 

Within the Parallels RAS Console, administrators can update virtual desktop, and remote desktop session host (RDSH) templates by first placing the template into maintenance mode (Fig 1). In maintenance mode, you can right-click the template and connect via RDP (Fig 2). 

Figure 1: Place the Parallels RAS template in Maintenance mode.

Figure 2: Right-click the template and choose Tools > Remote Desktop.

After you make the changes you want to your template, the next step is to exit maintenance mode.  

Note: When you are asked if you want to recreate the guest VMs, select No.
PRAS Powershell setup
 

IMPORTANT:  The RDSH group should have Autoscale enabled and a template assigned. 

The next step is to set up the script to run by scheduling it, checking that it is enabled, and ensuring that the next scheduled run is suitable. 

Prerequisites  

You will require the following: 

  1. Parallels RAS Farm. 
  2. RDSH or VDI pools with template. 
  3. Parallels RAS PowerShell module installed. 

Script Setup 

In order to set up the script for your Parallels RAS environment, find the #Variables section, as shown below, with username and password for an administrator service account.  This is a Windows account that has been given admin rights in the Parallels RAS Console. 

PRAS Powershell Variables

Enter the Parallels RAS connection broker hostname, Group ID, and template name. 

The log directory and file must also be set or created in the PS folder on the C:\ drive. 

You can find the Group ID in the Parallels RAS Console under Farm > RD. 

PRAS Powershell

 

RDSH Template Script 

The sample script shown below is for use at your own risk.  Parallels assumes no responsibility for use of this script.

 
  <# 
.SYNOPSIS 
    Parallels RAS script to schedule RDS template updates 
.DESCRIPTION 
    The script will look at a RDS group that has a template assigned.  Any user sessions will be logged off, the group disabled.       The template will then be put into maintenance mode and then maintenance mode will be exited with the recreate all instances switch. 
.PARAMETER   
    Parameter Name: None 
.INPUTS 
    None 
.OUTPUTS 
    Log file stored in C:\PS\computername.log 
.NOTES 
    Version: 1.0 
    Author: Paul Fisher, Freek Berson  
    Creation Date: 09/11/22 
    Purpose/Change: Initial script development 
#> 
#Variables 
$userName = "ENTER_USERNAME " 
$plainPassword = "ENTER_PASSWORD " 
$securePassword = $plainPassword | ConvertTo-SecureString -AsPlainText -Force 
$RASServer = "ENTER_A_RAS_CONNECTION_BROKER_HOSTNAME " 
$templateName = "ENTER_TEMPLATE_NAME " 
$groupID = 2 
$logDirectory = "C:\PS\" 
$logfile = "C:\PS\TemplateShedule_"+$templateName+"_"+$(get-date -f yyyy-MM-dd)+".log" 
#Import modules 
Import-Module 'C:\Program Files (x86)\Parallels\ApplicationServer\Modules\RASAdmin\RASAdmin.psd1' 
#Create log file if it does not exist 
If(!(test-path -PathType Container $logDirectory)){New-Item -ItemType Directory -Path $logDirectory} 
#Function to write to logfile 
function writeLog { 
    Param ([string]$logString) 
    $Stamp = (Get-Date).toString("yyyy/MM/dd HH:mm:ss") 
    $logMessage = "$Stamp $logString" 
    Add-content $logFile -value $logMessage 
    Write-Output $logMessage 
} 
#Open new RAS PowerShell session 
writeLog "Setting up RAS Farm connection...." 
New-RASSession -Username $userName -Password $securePassword -Server $RASServer 
#Log off all users 
Foreach ($session in Get-RASRDSession -Source RDS -GroupId $groupID | Select-Object -Property User, SessionHostId, SessionID) 
{ 
    writeLog "Logging off User: $session..." +$session.SessionID 
    Invoke-RASRDSSessionCmd -Command LogOff -Id $session.SessionID -RDSId $session.SessionHostId 
} 
#Wait for all sessions to be logged off 
While ((Get-RASRDSession -Source RDS -GroupId $groupID | Select-Object -Property User, SessionHostId, SessionID).count -ne 0) 
{ 
    writeLog "Waiting for all users to be logged off..." 
    Start-Sleep -s 10 
} 
#After group disable apply settings and wait for RDSH Hosts to be unregistered. 
writeLog "Disabling RDS Group......." 
Set-RASRDSGroup -Id $groupID -Enabled $False 
Invoke-RASApply -FullSync 
#Wait for all members to be removed from group 
While ((Get-RASRDSGroup -Id $groupID | select RDSIds).RDSIds.Count -ne 0) 
{ 
    writeLog "Waiting for all servers to be removed from the group..." 
    Start-Sleep -s 10 
} 
#Enter maintenance mode 
writeLog "Entering Maintenance Mode...." 
Invoke-RASVDITemplateCmd $templateName -Command EnterMaintenance 
Invoke-RASApply 
#Wait for the status update change 
While ((Get-RASVDITemplateStatus -Name $templateName | select Status).status -ne "Maintenance") 
{ 
    writeLog "Waiting for template status to update..." 
    Start-Sleep -s 10 
} 
#Exit maintenance mode and recreate desktops 
writeLog "Exit maintenance mode..." 
Invoke-RASVDITemplateCmd -Command ExitMaintenance -Name $templateName -ForceStopUpdateDesktops 
Invoke-RASApply 
Invoke-RASVDITemplateCmd -Command RecreateDesktops -Name $templateName -RecreateAllDesktops 
Invoke-RASApply 
#Re-enable group 
writeLog "Enabling group...." 
Set-RASRDSGroup -Id $groupID -Enabled $True 
Invoke-RASApply -FullSync 
#Clean up session and close 
Remove-RASSession 
writeLog  "Update complete of template " +$templateName  

VDI Template Script 

The sample script shown below is for use at your own risk.  Parallels assumes no responsibility for use of this script.

<# 
.SYNOPSIS 
    Parallels RAS script to schedule VDI template updates 
.DESCRIPTION 
    The script will look at a VDI template.  All running VDI guests will be shutdown which will also deal with any user sessions.  
    The template will then be put into maintenance mode and then maintenance mode will be exited with the recreate all instances switch. 
.PARAMETER   
    Parameter_Name: None 
.INPUTS 
    None 
.OUTPUTS 
    Log file stored in C:\PS\computername.log 
.NOTES 
    Version: 1.0 
    Author: Paul Fisher, Freek Berson 
    Creation Date: 09/11/22 
    Purpose/Change: Initial script development 
#> 
#Variables 
$userName = "ENTER_USERNAME " 
$plainPassword = "ENTER_PASSWORD " 
$securePassword = $plainPassword | ConvertTo-SecureString -AsPlainText -Force 
$RASServer = "ENTER_A_RAS_CONNECTION_BROKER_HOSTNAME " 
$templateName = "ENTER_TEMPLATE_NAME " 
$logDirectory = "C:\PS\" 
$logfile = "C:\PS\TemplateShedule_vdi_"+$templateName+"_"+$(get-date -f yyyy-MM-dd)+".log" 
#Import modules 
Import-Module 'C:\Program Files (x86)\Parallels\ApplicationServer\Modules\RASAdmin\RASAdmin.psd1' 
#Create log file if it does not exist 
If(!(test-path -PathType Container $logDirectory)){New-Item -ItemType Directory -Path $logDirectory} 
#Function to write to logfile 
function writeLog { 
    Param ([string]$logString) 
    $Stamp = (Get-Date).toString("yyyy/MM/dd HH:mm:ss") 
    $logMessage = "$Stamp $logString" 
    Add-content $logFile -value $logMessage 
    Write-Output $logMessage 
} 
#Open new RAS PowerShell session 
writeLog "Setting up RAS Farm connection...." 
New-RASSession -Username $userName -Password $securePassword -Server $RASServer 
$TempObj = Get-RASVDITemplate -Name $templateName 
#Shutdown all VMs (This section shutdowns the VMs and therefore Logs the users off too) 
Foreach ($RASVDIInstance in Get-RASVDIDesktop -VDITemplateObj $TempObj) 
{ 
Stop-RASVM -Id $RASVDIInstance.Id -ProviderId $RASVDIInstance.ProviderId 
writeLog "Shutting down VM:  $RASVDIInstance.ComputerName " 
Start-Sleep -s 10 
} 
#Enter maintenance mode 
writeLog "Entering Maintenance Mode...." 
Invoke-RASVDITemplateCmd $templateName -Command EnterMaintenance 
Invoke-RASApply 
#Wait for the status update change 
While ((Get-RASVDITemplateStatus -Name $templateName | select Status).status -ne "Maintenance")
{ 
 writeLog "Waiting for template status to update..."

Start-Sleep -s 10 
} 
#Exit maintenance mode and recreate desktops 
writeLog "Exit maintenance mode..." 
Invoke-RASVDITemplateCmd -Command ExitMaintenance -Name $templateName -ForceStopUpdateDesktops 
Invoke-RASApply 
Invoke-RASVDITemplateCmd -Command RecreateDesktops -Name $templateName -RecreateAllDesktops 
Invoke-RASApply 
#Clean up session and close 
Remove-RASSession 
writeLog "Update complete of template: $templateName complete."  

PRAS Powershell

Schedule the script(s) with Windows Task Scheduler 

 

  1. On one of your connection brokers, open the Windows Task Scheduler.
  2. Right-click the Task Scheduler Library and choose Create a Basic Task. 
  3. Type a name (for example, RAS – Update RDS Template), and click Next. 
  4. On the Trigger page, choose a trigger start type (for example, One time), and click Next. 
  5. Choose Start date and time, and click Next. 
  6. On the Action page, select Start a program, and click Next. 
  7. In the Program/script box, browse to or paste C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe. 
  8. In the Add arguments box, enter -File C:\PS\schedule-template-redeploy.ps1. (Change the path to match where you have saved and created your script.)
  9. Click Next. 
  10. Review the summary and click Finish.

Any questions or issues? Contact our support team!