Workplace and VDI test automation with PowerShell

Making test automation with PowerShell in Windows
Tags: vdi powershell windows automation |

Why to do test automation with PowerShell?

I was involved in a project to implement a new Virtual Desktop Infrastructure (VDI) within a large company

To ensure the environment is stable and well-functioning all the time on the same way, I made a script to test the basic functionality of the virtual desktop image. The script also measures the time it takes to complete an action, so this can be used to set a baseline for performance measurement.

The basic functionality which is scripted is:

  • Start Outlook and Send an email
  • Can the user browse the internet
  • Open a Word document, Print Preview, Print, and save the document
  • Open an Excel sheet, Save it under a different name
  • Browse the AppV content store
  • Start an AppV application

Other actions can be scripted as well and added to the script.

When the script has run completely with success it will ensure you that the basic functionality is still working.

See the script in action

This video gives a quick overview what kind of actions are scripted and how it works.

Workplace and VDI test automation with PowerShell from EasternNL on Vimeo.

What kind of results do the script make?

When using the script a PDF document is generated which shows the following for each step:

An example PDF document can be found here: 2015-09-23 163927 Workplace and VDI test-automation with PowerShell.pdf

Also an .su file is generated which has the following content:

12015-08-26    07:23:13.439    07:23:14.48    0.6092069    Excel - start    C:\Users\Erik\AppData\Local\Temp\2015-08-26 07.23.13.439 Excel - start.png

This file is tab-separated and can be imported in Excel or other tools for further investigation.

An example SU file can be found here: test.su

My baseline tools

The script is tested on:

  • Windows 7 with Office 2010
  • Windows 10 with Office 2013

Powershell version 3 or higher is enough to run this script. I am sure this will work on other platforms like Windows 8 e.g. as well.

The iTextSharp module is needed to generate the PDF’s and can be found here: http://sourceforge.net/projects/itextsharp/

Boxcutter.exe is used to make screenshots during the test. Boxcutter can be found here: http://keepnote.org/boxcutter/

Script code

Basically the following code is needed to start Excel:

1$excel = new-object -comobject Excel.Application
2$excel.visible = $True

Other example is the code to start Internet Explorer:

1$ie = new-object -com "InternetExplorer.Application"
2$ie.visible = $true

(In a second blog item I will explain how to do the automation of browsing on the internet.)

Basically it is simple, however in my coding some extra steps are involved to measure the start of Excel, and to make a screenshot to ensure everything went well. The Write-Transaction function is included in my module and will write the measured times to the .su file and take the screenshot as well.

1$transactionname = "Excel - start"
2Write-Transaction -transactionname $transactionname -sleepseconds $sleepseconds -outputfile $outputfile -screenshot $true -measured ( Measure-Command {
3            $excel = new-object -comobject Excel.Application
4            $excel.visible = $True
5            } )

In the end of the script the complete .su file is converted to PDF format together with the screenshots.

Conclusion

Windows endpoint testing, for VDI but also for physical desktop can be done with scripts. When launching every day, and eventually on different times of a day the performance and functionality of an Windows desktop can be measured.

The complete script

  1# load the modules
  2Import-Module "$(Split-Path -parent $PSCommandPath)\Test-Availability.psm1" -Force
  3Import-Module "$(Split-Path -parent $PSCommandPath)\iTextSharp.psm1" -Force
  4 
  5# -------------------------------------------
  6# configure variabeles
  7 
  8$testdocument = "$(Split-Path -parent $PSCommandPath)\testdocument.docx"
  9$testworkbook = "$(Split-Path -parent $PSCommandPath)\testworkbook.xlsx"
 10$printer = "Bullzip PDF Printer"
 11$appvcontentstore = "C:\AppV"
 12 
 13# -------------------------------------------
 14 
 15# Stop if an error has occured, will be handled by the try/catch
 16$ErrorActionPreference = "Stop"
 17 
 18# Verbose messages on
 19#$VerbosePreference = "Continue"
 20# wait time between the steps
 21$sleepseconds = 1
 22# temporary path to log the output to
 23$outputfile = "$($env:temp)\test.su"
 24if (Test-Path $outputfile) { rm $outputfile }
 25 
 26 
 27 
 28try {
 29 
 30    # Start Outlook 
 31        $transactionname = "Outlook - Start"
 32        Write-Transaction -transactionname $transactionname -sleepseconds $sleepseconds -outputfile $outputfile -screenshot $true -measured ( Measure-Command {
 33            $outlook = new-object -com "Outlook.Application"
 34            #$outlook.visible = $true
 35            $namespace = $outlook.GetNamespace("MAPI")
 36            $folder = $namespace.GetDefaultFolder(16)
 37            $folder.Display()
 38            } )
 39 
 40        # Write email
 41        # (not sending an email because that is blocked by default in Outlook)
 42        $transactionname = "Outlook - Write message in draft"
 43        Write-Transaction -transactionname $transactionname -sleepseconds $sleepseconds -outputfile $outputfile -screenshot $true -measured ( Measure-Command {
 44            $mail = $outlook.CreateItem(0)
 45            $mail.Subject = "$(Get-Date -format "yyyy-MM-dd HH:mm:ss") VDI Test Script"
 46            $mail.To = "user@domain.com"
 47            $mail.Body = "Testing the VDI functionality with a script"
 48            $mail.save()
 49            } )
 50 
 51        # Close Outlook 
 52        $transactionname = "Outlook - Exit"
 53        Write-Transaction -transactionname $transactionname -sleepseconds $sleepseconds -outputfile $outputfile -screenshot $true -measured ( Measure-Command {
 54            $outlook.Quit()
 55            } )
 56             
 57    # Internet Explorer - eastern.nl
 58        $transactionname = "Internet Explorer - Start"
 59        Write-Transaction -transactionname $transactionname -sleepseconds $sleepseconds -outputfile $outputfile -screenshot $true -measured ( Measure-Command {
 60            $ie = new-object -com "InternetExplorer.Application"
 61            $ie.visible = $true
 62     
 63            Set-ForegroundWindow "Internet Explorer"
 64            } )
 65     
 66        # navigate
 67        $transactionname = "Internet Explorer - www.eastern.nl"
 68        Write-Transaction -transactionname $transactionname -sleepseconds $sleepseconds -outputfile $outputfile -screenshot $true -measured ( Measure-Command {
 69            $ie.Navigate("http://www.eastern.nl/")
 70     
 71            # wait until the page is ready, all parameters okay and the text Erik van Oost is inside the document
 72            Wait-InternetExplorer -ie $ie -text "Erik van Oost"
 73            } )
 74         
 75        $transactionname = "Internet Explorer - Quit"
 76        Write-Transaction -transactionname $transactionname -sleepseconds $sleepseconds -outputfile $outputfile -screenshot $true -measured ( Measure-Command {
 77            # Internet Explorer Exit
 78            $ie.quit()
 79            } )
 80     
 81        # Word
 82        $transactionname = "Word - Start"
 83        Write-Transaction -transactionname $transactionname -sleepseconds $sleepseconds -outputfile $outputfile -screenshot $true -measured ( Measure-Command {
 84            $word=new-object -ComObject "Word.Application"
 85            $word.visible = $true
 86            } )
 87     
 88        # Document open 
 89        $transactionname = "Word - Open testfile"
 90        Write-Transaction -transactionname $transactionname -sleepseconds $sleepseconds -outputfile $outputfile -screenshot $true -measured ( Measure-Command {
 91            $doc = $word.Documents.Open($testdocument)
 92            } )
 93 
 94        # Document saven op temp
 95        $transactionname = "Word - Save testfile"
 96        Write-Transaction -transactionname $transactionname -sleepseconds $sleepseconds -outputfile $outputfile -screenshot $true -measured ( Measure-Command {
 97            $filename = "$($env:temp)\test.docx"
 98            $file_formatcode = 12
 99 
100            if (Test-Path filename) { rm $filename -Force -ErrorAction SilentlyContinue }
101            $doc.SaveAs([ref]$filename, [ref]$file_formatcode)
102        } )
103 
104        $transactionname = "Word - Print preview"
105        Write-Transaction -transactionname $transactionname -sleepseconds $sleepseconds -outputfile $outputfile -screenshot $true -measured ( Measure-Command {
106            $doc.PrintPreview()        
107            } )
108 
109        <#
110        $transactionname = "Word - Print"
111        Write-Transaction -transactionname $transactionname -sleepseconds $sleepseconds -outputfile $outputfile -screenshot $true -measured ( Measure-Command {
112            # set active printer             
113            $word.activeprinter = $printer
114             
115            # Document afdrukken
116            $doc.PrintOut([ref]$false)
117            } )
118        #>
119 
120        $transactionname = "Word - Quit"
121        Write-Transaction -transactionname $transactionname -sleepseconds $sleepseconds -outputfile $outputfile -screenshot $true -measured ( Measure-Command {
122            # Close document
123            $doc.Close()
124            # Exit Word
125            $word.Quit()
126                } )
127 
128    # Start Excel 
129        $transactionname = "Excel - start"
130        Write-Transaction -transactionname $transactionname -sleepseconds $sleepseconds -outputfile $outputfile -screenshot $true -measured ( Measure-Command {
131            $excel = new-object -comobject Excel.Application
132            $excel.visible = $True
133            } )
134     
135        # Open workbook
136        $transactionname = "Excel - Open testfile"
137        Write-Transaction -transactionname $transactionname -sleepseconds $sleepseconds -outputfile $outputfile -screenshot $true -measured ( Measure-Command {
138            $wb = $excel.Workbooks.Open($testworkbook)
139            } )
140     
141        # Save workbook
142        $transactionname = "Excel - Save testfile"
143        Write-Transaction -transactionname $transactionname -sleepseconds $sleepseconds -outputfile $outputfile -screenshot $true -measured ( Measure-Command {
144            $filename = "$($env:temp)\test.xlsx"       
145            $excel.displayalerts = $false
146            $wb.SaveAs($filename)
147            } )
148         
149    # Close Excel
150        $transactionname = "Excel - Quit"
151        Write-Transaction -transactionname $transactionname -sleepseconds $sleepseconds -outputfile $outputfile -screenshot $true -measured ( Measure-Command {
152            $excel.quit()
153        } )
154 
155    # Visit AppV Content Store
156        $transactionname = "AppV - ContentStore"
157        Write-Transaction -transactionname $transactionname -sleepseconds $sleepseconds -outputfile $outputfile -screenshot $true -measured ( Measure-Command {
158            $app = Start-Process cmd.exe -PassThru -ArgumentList " /k dir `"$($appvcontentstore)`" /ogneds" -WorkingDirectory "C:\"
159 
160            } )
161         
162            # Content store Sluiten
163            Stop-Process -Id $app.Id 
164 
165    # AppV Application
166    # %ALLUSERSPROFILE%\Microsoft\AppV\Client\Integration\4C39F850-61B3-4ED5-95E0-0F21C0B6D0BB\Root\DLS.exe
167        $transactionname = "AppV Application Dymo Label Writer"
168        Write-Transaction -transactionname $transactionname -sleepseconds 5 -outputfile $outputfile -screenshot $true -measured ( Measure-Command {
169            $app = Start-Process  C:\ProgramData\Microsoft\AppV\Client\Integration\4C39F850-61B3-4ED5-95E0-0F21C0B6D0BB\Root\DLS.exe -PassThru
170 
171            } )
172         
173            # Content store Sluiten
174            Stop-Process -Id $app.Id 
175 
176    
177 
178    # End of test
179        $result = Show-PopUp -Message "Test ended sucessfully" -Title "Test Automation" -ButtonSet OK -IconType Information
180}
181catch
182{
183    # log if an error occurs, including a screenshot with the error
184    $Error
185 
186    Write-Transaction -transactionname "ERROR $transactionname" -sleepseconds 0 -outputfile $outputfile -screenshot $true -measured ( Measure-Command { sleep -Milliseconds 100 } )
187 
188    $result = Show-PopUp -Message "Test ended with error" -Title "Test Automation" -ButtonSet OK -IconType Exclamation
189}
190 
191# Ask for conversion to PDF
192    $result = Show-PopUp -Message "Do you want to write the results to a PDF file?" -Title "PDF file" -ButtonSet YNC -IconType Question
193 
194    if ($result -eq 6)
195    {
196        # when in an Citrix Session log some information about Citrix
197        $sessioninfo = (Get-ItemProperty -Path HKLM:SOFTWARE\Citrix\ICA\Session -ErrorAction SilentlyContinue )
198        $outputpdf = (Get-FileName -defaultFileName "$(get-date ((ls $outputfile).CreationTime) -Format "yyyy-MM-dd HHmmss") Workplace and VDI test-automation with PowerShell.pdf" )        
199        $message = "VDI Desktop Image testscript run on $(get-date -Format "yyyy-MM-dd HH:mm"). `n`nOutput PDF: $(split-path $outputpdf -leaf)`nComputername: $($env:computername)`n"
200        # when in an Citrix Session log some information about Citrix
201        if ($sessioninfo -ne $null)
202        {
203            $message += "Clientaddress: $($sessioninfo.clientaddress) `nClientname: $($sessioninfo.clientname) `nClientversion: $($sessioninfo.clientversion)"
204        }
205        $message += "`n`n"
206        convert-su-to-pdf -inputsu $outputfile -outputpdf $outputpdf -title "Desktop Image functional Script" -message $message
207    }
208 
209# ask for logoff
210    $result = Show-PopUp -Message "Do you want to logoff?" -Title "Logoff" -ButtonSet YNC -IconType Question
211 
212    if ($result -eq 6)
213    {
214        start-process logoff
215    }

Download

Download the script, module and test-files here: sources.zip