LoginVSI PowerShell – New-CitrixVSITest

Being able to automate a LoginVSI test saves a lot of time, but there is more to testing than just the LoginVSI portion. We must remember to get the environment prepared for a LoginVSI test. For a Citrix XenApp and XenDesktop test, I always need to do the following:

  • Prepare environment
    • Remove the first VM from maintenance mode and power on
    • Identify the XenServer host for the VM
    • If needed, start capturing metrics on the XenServer host
    • Wait for the VM to register with the XenApp and XenDesktop delivery controller
    • Remove all remining VMs from maintenance mode, start and wait for them to register
  • Invoke the LoginVSI test
  • When test completes, cleanup the environment
    • Stop metric gather on XenServer host
    • Stop all VMs
    • Place all VMs into maintenance mode
    • Logoff of the launcher machine
    • Reboot XenServer host

The first part is to define all of the parameters for the LoginVSI test, and there are a lot of them.

One of the parameters needs the path for an SSH Module. This is for capturing XenServer-level metrics as explained here:

function Start-NewCitrixVSITest {
        [string] $testdesc, #Short description of what the test is validating. Will be part of the test name
        [string] $Workload, #LoginVSI Workload
        $VMs, #VM Names to be part of the test
        [string] $DomainName, #name of the Windows domain
        [string] $vsishare, #Path to the LoginVSI share
        [string] $VSIProfileName, #Name of the LoginVSI profile to use
        [string] $Launchers, #Name of the machine to be used as a LoginVSI Launcher
        [string] $XSMaster, #hostname of the XenServer master server in the pool
        [int] $cycles, #Number of times the LoginVSI test should execute
        [int] $Duration, #Length of time to execute the LoginVSI test
        [switch] $XSMetrics, #Boolean if XenServer-level metrics should be captured
        [string] $MasterImage, #Name of the master image used for the LoginVSI test
        [switch] $ResetHost, #Boolean if the XenServer host should be rebooted after each test
        [string] $SSHModulePath, #Path to the PowerShell SSHModule
        [string] $XenServerUsername, #admin name for XenServer
        [string] $XenServerPW, #XenServer admin password
        [string] $VSILogFile #Path for a test results log file


    $username = "Launcher-v4" #Default LoginVSI username.

The remainder of the PowerShell script will be part of a loop based on the number of cycles defined.
Due to the interactions with XenServer, we also want to make a connection to the XenServer pool.

    foreach($i in 1..$cycles){
        # Connect to XenServer pool
        $session = Connect-XenServer -Server $XSMaster -UserName $XenServerUsername -Password $XenServerPW -NoWarnCertificates -SetDefaultSession -PassThru

Define Test Name
LoginVSI requires a unique test name. The script creates a test name my combining the following:

  • Workload Name – from parameters
  • Test Description – from parameters
  • LoginVSI Profile Name – from parameters
  • Test # of # – from parameters and loop iteration
  • Current Date/Time
        #Define testname
        $date = Get-Date -Format yyyy-MM-dd-HHmm
        Write-host (date -Format hh:mm:ss)   -   Running LoginVSI $testdesc test with $workload workload - Test Number $i of $cycles -ForegroundColor Green -Verbose
        $testname = $Workload + "-" + $testdesc + "-" + $VSIProfileName + "-Test" + $i + "of" + $cycles + "-" + $date
        Write-host (date -Format hh:mm:ss)   -   Current test name is $testname -ForegroundColor Yellow

Start First VM

Regardless of how many VMs the test will use, we need to start a single one VM and take it out of maintenance mode. If only 1 VM was defined as part of the test, we can simply start that VM. But if multiple VMs are part of the test, as part of an array, we need to start the first VM in the array.

This uses the following custom function

        #Start one VM
        if ($VMs.count -gt 1){
            Start-VM -VM $VMs[0] -DomainName $DomainName 
        else {
            Start-VM -VM $VMs -DomainName $DomainName

Identify Host

With one VM running, we can now identify the hypervisor host.

        # Identify XenServer host Server
        if ($VMs.count -gt 1){
            $Hostserver = Get-CurrentVMHost -VM $VMs[0]
        else {
            $Hostserver = Get-CurrentVMHost -VM $VMs

Gather XenServer Metrics

If the Boolean value is $True for capturing XenServer Metrics, the script will start a new powershell process that connects to the VM’s hypervisor host to start the metrics gathering process, which uses the following function

        # Capture XenServer Metrics on host if selected
        If($XSMetrics -eq $true) {
            Write-host (date -Format hh:mm:ss)   -   Start gathering metrics on VM host $HostServer -ForegroundColor Yellow
            start-process powershell.exe -Argument "Start-XSMetrics $testname $hostserver $sshModulePath $XenServerUsername $XenServerPW" -WindowStyle Minimized

Gather VM Metrics

If the Boolean value is $True for capturing VM Metrics, the script will update the V4-VSI-Logon.cmd file to enable/disable the perfmon script and call the Set-Perfmon function to set the Perfmon.ps1 script with test variables.

        If($VMMetrics -eq $true) {
            $LogonScript=Get-Content "\\dc1\Netlogon\V4-VSI_Logon.cmd"
            $LogonScript  | Foreach-Object {
            $_ -replace "REM Powershell -NoProfile.+", "PowerShell -NoProfile.+"
            } | Set-Content "\\dc1\Netlogon\V4-VSI_Logon.cmd"

            set-perfmon -workload $workload -TestDesc $testdesc -MasterImage $MasterImage -CurrentCycle $i -Cycles $cycles

        Elseif($VMMetrics -eq $false) {
            $LogonScript=Get-Content "\\dc1\Netlogon\V4-VSI_Logon.cmd"
            $LogonScript  | Foreach-Object {
            $_ -replace "Powershell -NoProfile.+", "REM PowerShell -NoProfile.+"
            } | Set-Content "\\dc1\Netlogon\V4-VSI_Logon.cmd"

Wait for VM to Register

The script needs to wait for the VM to registry with the XenApp and XenDesktop delivery controller, which uses the following function

        #Wait for VM to register to controller
        if ($VMs.count -gt 1){
            Wait-VMRegistration -VM $VMs[0]
        else {
            Wait-VMRegistration -VM $VMs

Start all VMs

We can now start all remining VMs, if needed, by doing the following:

        #Start remaining VMs
        If ($VMs.count -gt 1) {
            #Start remaining VMs
            foreach ($VM in $VMs) {
                Start-VM -VM $VM -DomainName $DomainName 
                start-sleep -s 15
            #Wait for remaining VMs to regsiter with controller
            foreach ($vm in $VMs) {
                Wait-VMRegistration -VM $VM
                start-sleep -s 10

Invoke LoginVSI Test

With the VMs running and registered, we are able to invoke the LoginVSI test by calling the following function

        #Start LogonVSI Test
        start-sleep -s 30
        Invoke-VSITest -vsishare $vsishare -DomainName $DomainName -VSIProfileName $VSIProfileName -launchers $Launchers -Testname $TestName -Duration $Duration -MasterImage $MasterImage -VSILogFile $VSILogFile


When the Invoke-VSITest completes, either because the test was successful or ended early due to a failure, we need to clean up the environment to prepare for the next test in the cycle

  • XenServer Metrics: If we are capturing the hypervisor-level metrics, those must be stopped
  • VM Power Off: We need to shutdown all VMs and wait for them to power off by using the following custom functions Stop-VM and Wait-PowerOff
  • Logoff Launcher: Use “quser” to log the user off of the launcher machine
  • Restart XenServer: If required, based on parameter, reboot the hypervisor host using the customer function Restart-XenServer
        # Test complete, cleanup environment

        # Stop gathering XenServer metrics if capturing
        If($XSMetrics -eq $true) {
            stop-XSMetrics $hostserver $XenServerUsername $XenServerPW

        #Stop VMs
        if ($VMs.count -gt 1){
            foreach ($VM in $VMs) {
                Stop-VM -VM $VM -DomainName $DomainName                   

            #Verify VMs are powered off
            foreach ($VM in $VMs) {
                Wait-PowerOff -VM $VM 
        Else {       
            Stop-VM -VM $VMs -DomainName $DomainName
            Wait-PowerOff -VM $VMs

        #Power off launcher 
        $LaucherVM = get-xenvm -name $Launchers
        Do {
            if ($LaucherVM.power_state -ne "Halted") {
                #shut down VM
                Invoke-XenVM -VM $LaucherVM -XenAction Shutdown -async
                Write-host (date -Format hh:mm:ss)   -   Waiting for $Launchers to shutdown -ForegroundColor Yellow
                sleep 10
                $LaucherVM = get-xenvm -name $Launchers
        } while ($LaucherVM.power_state -ne "Halted")

        # Kill remote launcher connection and LoginVSI Session Monitor processes        
        Get-Process | Where-Object {$_.Path -like "*mstsc*"} | Stop-Process
        Get-Process | Where-Object {$_.Path -like "*sessionmonitor*"} | Stop-Process

        # restart XenServer host if required
        If($ResetHost -eq $true) {
            Restart-XenServer -XenMaster $XSMaster -Hostserver $Hostserver -XenServerUsername $XenServerUsername -XenServerPW $XenServerPW
    # Disconnect from XenServer session
    disconnect-xenserver -session $session

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

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