Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <#
- .SYNOPSIS
- Test StoreFront or NetScaler Gateway (integrated with StoreFront) and XenApp by launching one or more Published Applications.
- .DESCRIPTION
- This script launches an a Published Applications through StoreFront or NetScaler Gateway (integrated with StoreFront).
- For MONITORING purposes!
- It attempts to closely resemble what an actual user would do by:
- -Opening Internet Explorer.
- -Navigating directly to the Receiver for Web site or NetScaler Gateway portal.
- -Entering Username and Password.
- -Logging in.
- -Clicking on the Application(s).
- -Logging off the StoreFront site.
- You can use thie Script to verify your most important Applications load.
- You can also use this Script to verify that each of your servers is repsonding correctly.
- To do this you would need to Publish an Application from each server.
- For example, you could publish Task Manager (taskmgr.exe), from each server, and name it something like "Server 1 Task Manager", "Server 2 Task Manager", etc, etc.
- Requirements:
- -Citrix Receiver installed in the default location.
- -Must be launched from an Elevated Administrator console of PowerShell x86. The 64 Bit Powershell will not work since the script is using Citrix Reciever, which is 32 bit, to verify a lunch and logoff the session.
- -No other sessions should be connected/running before running the script.
- -SiteURL should be part of the Intranet Zone (or Internet Zone at Medium-Low security) in order to be able to download AND launch the ICA file. This can be done through a GPO.
- -StoreFront 2.0 or higher or NetScaler Gateway, version 9.3 or higher.
- -Changes in web.config under C:\inetpub\wwwroot\Citrix\<storename>Web\: autoLaunchDesktop to false, pluginAssistant to false.
- -Currently works for desktops or already subscribed apps only.
- -You can auto subscribe users to apps by setting "KEYWORDS:Auto" in the published app's description or make sure the apps have been subscribed to manually.
- -This script does not support AppController at this time.
- -In order for the script to interact with the ICO, it requires the following to be set in the registry:
- -x64: HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Citrix\ICA Client\CCM
- -x86: HKEY_LOCAL_MACHINE\SOFTWARE\Citrix\ICA Client\CCM
- -AllowLiveMonitoring REG_DWORD 1
- -AllowSimulationAPI REG_DWORD 1
- .PARAMETER SiteURL
- The complete URL of the StoreFront Receiver for Web site or NetScaler Gateway portal.
- .PARAMETER UserName
- The name of the user which is used to log on. Acceptable forms are down-level logon name or user principal name.
- .PARAMETER Password
- The password of the user which is used to log on.
- .PARAMETER smtpServer
- The SMTP Server to send email alerts to
- .PARAMETER emailFrom
- Email Address that the alerts will come from
- .PARAMETER emailTo
- Email Address to send the alerts to
- .PARAMETER SleepBeforeLogoff
- The time in seconds to sleep after clicking the resource and before logging off. Default is 5.
- .PARAMETER NumberOfRetries
- The number of retries when retrieving an element. Default is 30.
- .PARAMETER LogFilePath
- Directory path to where the log file will be saved. Default is SystemDrive\Temp.
- .PARAMETER LogFileName
- File name for the log file. By default, the script creates a log file named "SFLauncher.log".
- .PARAMETER EmailAlertsLagTime
- This sets the amount of time, in seconds, an alert email will be sent if the same error is encountered. For example, if Application 1 fails, and the script is set to run every 30 minutes, you can set this to something higher than 1800 so not to be notified every 30 minutes.
- .PARAMETER TwoFactorAuth
- The token or password used for two-factor authentication. This is used in the NetScaler Gateway portal.
- .PARAMETER ResourceName
- The display name(s) of the Published Application(s) to be launched. Just add the applications at the end of the command line. See the example for more info.
- .PARAMETER TimeToWaitForApp
- The amount of time, in seconds, to wait for the Application to launch
- .PARAMETER TimeToWaitForLogoff
- The amount of time, in seconds, to wait before issuing the Logoff Command
- .EXAMPLE
- SFLauncher.ps1 -SiteURL "http://storefront.domain.com" -UserName "domain1\User1" -Password "P4ssw0rd" -smtpServer "smtp.domain.com -emailFrom "XenAppMon@domain.com" -emailTo "email@domain.com" -LogFilePath C:\Logifles -LogFileName SFLauncher.log "Application 1" "Application 2"
- Description
- -----------
- Launches a sPublished Application using the parameters provided.
- .LINK
- UserName format used in StoreFront.
- http://msdn.microsoft.com/en-us/library/windows/desktop/aa380525(v=vs.85).aspx#down_level_logon_name
- .LINK
- Change to autoLaunchDesktop.
- http://support.citrix.com/proddocs/topic/dws-storefront-20/dws-configure-wr-view.html
- .LINK
- Change to logoffAction.
- http://support.citrix.com/proddocs/topic/dws-storefront-20/dws-configure-wr-workspace.html
- .LINK
- Automating the launch of HDX sessions through StoreFront (and NetScaler Gateway integrated with StoreFront)
- http://blogs.citrix.com/2014/06/12/scripting-update-automating-the-launch-of-hdx-sessions-through-storefront-and-netscaler-gateway-integrated-with-storefront/
- .NOTES
- Created using SFLauncher.ps1 originally written by Citrix Systems, Inc.
- #>
- Param (
- [Parameter(Mandatory=$true,Position=0)] [string]$SiteURL,
- [Parameter(Mandatory=$true,Position=1)] [string]$UserName,
- [Parameter(Mandatory=$true,Position=2)] [string]$Password,
- [Parameter(Mandatory=$true,Position=3)] [string]$smtpServer,
- [Parameter(Mandatory=$true,Position=4)] [string]$emailFrom,
- [Parameter(Mandatory=$true,Position=5)] [string]$emailTo,
- [Parameter(ValueFromRemainingArguments=$true)] $ResourceName,
- [Parameter(Mandatory=$false)] [int]$SleepBeforeLogoff = 5,
- [Parameter(Mandatory=$false)] [int]$NumberOfRetries = 10,
- [Parameter(Mandatory=$false)] [string]$LogFilePath = "$($env:SystemDrive)\Temp\",
- [Parameter(Mandatory=$false)] [string]$LogFileName = "SFLauncher.log",
- [Parameter(Mandatory=$false)] [string]$TwoFactorAuth,
- [Parameter(Mandatory=$false)] $EmailAlertsLagTime = "900",
- [Parameter(Mandatory=$false)] $TimeToWaitForApp = "120",
- [Parameter(Mandatory=$false)] $TimeToWaitForLogoff = "15"
- )
- #Set-StrictMode -Version 2
- Set-Variable -Name NGLoginButtonId -Value "Log_On" -Option Constant -Scope Script
- Set-Variable -Name NGUserNameTextBoxName -Value "login" -Option Constant -Scope Script
- Set-Variable -Name NGPasswordTextBoxName -Value "passwd" -Option Constant -Scope Script
- Set-Variable -Name NGTwoFactorTextBoxName -Value "passwd1" -Option Constant -Scope Script
- Set-Variable -Name SFLoginButtonId -Value "loginBtn" -Option Constant -Scope Script
- Set-Variable -Name SFUsernameTextBoxId -Value "username" -Option Constant -Scope Script
- Set-Variable -Name SFPasswordTextBoxId -Value "password" -Option Constant -Scope Script
- Set-Variable -Name SFLogOffLinkId -Value "userdetails-logoff" -Option Constant -Scope Script
- Set-Variable -Name x64DLLPath -Value "C:\Program Files (x86)\Citrix\ICA Client" -Option Constant -Scope Script
- Set-Variable -Name x86DLLPath -Value "C:\Program Files\Citrix\ICA Client" -Option Constant -Scope Script
- # Setting up log files
- [string]$PreviuosLogFile = $($LogFilePath.TrimEnd('\') + "\" + $LogFileName + "_PreviuosRun.log")
- [string]$AlertsEmailed = $($LogFilePath.TrimEnd('\') + "\" + $LogFileName + "_AlertsEmailed.log")
- [string]$CurrentAlerts = $($LogFilePath.TrimEnd('\') + "\" + $LogFileName + "_AlertsCurrent.log")
- [string]$AlertEmail = $($LogFilePath.TrimEnd('\') + "\" + $LogFileName + "_AlertsEmailTimeStamp.log")
- [string]$ErrorStyle = "style=""background-color: #000000; color: #FF3300;"""
- [string]$Script:LogFile=$($LogFilePath.TrimEnd('\') + "\$LogFileName")
- function ScriptInfo {
- "=============Script Parameters=================" | LogMe -displaynormal
- "StoreFront / Netscaler Gateway URL: $SiteURL" | LogMe -displaynormal
- "User Name: $UserName" | LogMe -displaynormal
- "SMTP Server: $smtpServer" | LogMe -displaynormal
- "Email From Address: $emailFrom" | LogMe -displaynormal
- "Email To Address: $emailTo" | LogMe -displaynormal
- "Log File: $Script:LogFile" | LogMe -displaynormal
- "Number of Resources found in command line: " + $ResourceName.count | LogMe -displaynormal
- foreach($Resource in $ResourceName) {"Resource: '$Resource'" | LogMe -displaynormal}
- "Number of Seconds before sending repeat Email: $EmailAlertsLagTime" | LogMe -displaynormal
- "Number of Seconds to wait for the App to Launch: $TimeToWaitForApp" | LogMe -displaynormal
- "Number of Seconds to wait to send Logoff Command: $TimeToWaitForLogoff" | LogMe -displaynormal
- "Number of Seconds to wait before StoreFront Logoff: $SleepBeforeLogoff" | LogMe -displaynormal
- "===============================================" | LogMe -displaynormal
- }
- function CheckforDLL {
- if ((test-path -Path $x64DLLPath) -eq "TRUE") {Set-Variable -Name DLLPath -Value "$x64DLLPath\WfIcaLib.dll" -Option Constant -Scope Script }
- elseif ((test-path -Path $x86DLLPath) -eq "TRUE") {Set-Variable -Name DLLPath -Value "$x86DLLPath\WfIcaLib.dll" -Option Constant -Scope Script }
- else {throw "WfIcaLib.dll cannot be found, is the Citrix Client installed in it's default location?"}
- }
- function Create-ProgressBar($Activity,$Status){
- Write-Progress -Activity $Activity -status $Status
- }
- function Complete-ProgressBar($Activity,$Status){
- Write-Progress -Activity $Activity -status $Status -Completed
- }
- function Get-ICAClientVersion{
- # ============================ #
- # Get Client Version Function #
- # ============================ #
- $ErrorActionPreference = "SilentlyContinue"
- $ica = New-Object -ComObject 'Citrix.ICAClient'
- if($ica) { return $ica.ClientVersion }
- else { return 0 }
- }
- function GetElapsedTime([datetime]$starttime) {
- # ====================== #
- # Time Elapsed Function #
- # ====================== #
- $runtime = $(get-date) - $starttime
- $retStr = [string]::format("{0} sec(s)", $runtime.TotalSeconds)
- $retStr
- }
- function CreateRegEntry ($RegPath,$RegName,$PropType,$Val){
- # ===================== #
- # Create Registry Item #
- # ===================== #
- try {New-ItemProperty -Path $RegPath -Name $RegName -PropertyType $PropType -Value $Val -ErrorAction Stop}
- catch {
- $Script:RegError += $_.Exception.Message
- $_.Exception.Message | LogMe -error
- }
- }
- function ModifyRegEntry ($RegPath,$RegName,$Val){
- # ===================== #
- # Modify Registry Item #
- # ===================== #
- try {Set-ItemProperty -Path $RegPath -Name $RegName -Value $Val -ErrorAction Stop}
- catch {
- $Script:RegError += $_.Exception.Message
- $_.Exception.Message | LogMe -error
- }
- }
- function CreateRegKey ($RegPath){
- # ===================== #
- # Create Registry Item #
- # ===================== #
- try {New-Item -Path $RegPath -ErrorAction Stop}
- catch {
- $Script:RegError += $_.Exception.Message
- $_.Exception.Message | LogMe -error
- }
- }
- function CheckRegistry {
- # Making sure Registry Entries exist
- # If not, try to create or modify
- # If they cannot be created or modified, logging an error
- # and skipping ICA test
- $Script:Activity="Checking Registry for Settings Required"
- $Path = "HKLM:SOFTWARE\Citrix\ICA Client\CCM"
- $TestRegPath = Get-ItemProperty -Path $Path -ErrorAction SilentlyContinue
- if (!$TestRegPath) {CreateRegKey $Path}
- $AllowLiveMonitoringName = "AllowLiveMonitoring"
- $AllowSimulationAPIName = "AllowSimulationAPI"
- $PropertyType = "DWORD"
- $Value = "1"
- $AllowLiveMonitoring = Get-ItemProperty -Path $Path -Name $AllowLiveMonitoringName -ErrorAction SilentlyContinue
- $AllowSimulationAPI = Get-ItemProperty -Path $Path -Name $AllowSimulationAPIName -ErrorAction SilentlyContinue
- if (!$AllowLiveMonitoring) {
- "AllowLiveMonitoring does not exist, creating it" | LogMe -warning
- CreateRegEntry $Path $AllowLiveMonitoringName $PropertyType $Value
- } elseif ($AllowLiveMonitoring.AllowLiveMonitoring -ne "1") {
- "AllowLiveMonitoring Value does not equal 1, setting to 1" | LogMe -warning
- ModifyRegEntry $Path $AllowLiveMonitoringName $Value
- }
- if (!$AllowSimulationAPI) {
- "AllowSimulationAPI does not exist, creating it" | LogMe -warning
- CreateRegEntry $Path $AllowSimulationAPIName $PropertyType $Value
- } elseif ($AllowSimulationAPI.AllowSimulationAPI -ne "1") {
- "AllowSimulationAPI value exists but does not equal 1, setting to 1" | LogMe -warning
- ModifyRegEntry $Path $AllowSimulationAPIName $Value
- }
- if ($Script:RegError -ne $Null) {
- "Errors were encountered when trying to add or modify registry entries required for this script to work" | LogMe -error
- "You will either need to run this script once as an Adminitrator or create the following registry entries manually:" | LogMe -error
- "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Citrix\ICA Client\CCM, AllowLiveMonitoring, DWORD, 1" | LogMe -error
- "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Citrix\ICA Client\CCM, AllowLiveMonitoring, DWORD, 1" | LogMe -error
- }
- }
- function Send-Email {
- #=============================================================================================
- # Email Section
- #=============================================================================================
- $CurrTime = Get-Date -format g
- $Script:Activity="Sending Email, if needed"
- If (($Script:NewAlerts -eq $True) -or ($Script:SendEmail -eq $True)) {
- if (Test-Path $AlertsEmailed) { clear-content $AlertsEmailed }
- foreach ($line in $script:ErrorMessage) { $Line | Add-Content $AlertsEmailed }
- # Setting MailFlag for the validation and error handling
- $MailFlag = $True
- If(!$emailFrom) { $MailFlag = $False; Write-Warning "From Email is NULL" }
- If(!$emailTo) { $MailFlag = $False; Write-Warning "To Email is NULL" }
- If(!$smtpServer) { $MailFlag = $False; Write-Warning "SMTP Server is NULL" }
- # $MailFlag = $True
- # Send email only if From, To and SMTP adress are not null
- if($MailFlag -match $False) {
- "Email could not send as the email parameters (FROM/TO/SMTP) failed" | LogMe -error
- } else {
- # Send email only if there is either an Error or Warning Detected
- $msg = new-object System.Net.Mail.MailMessage
- $msg.From=$emailFrom
- $msg.to.Add($emailTo)
- if($emailCC) { $msg.cc.add($emailCC) }
- $msg.Subject="StoreFront Error Detected"
- $msg.IsBodyHtml=$true
- $msg.Body=$Script:ErrorMessage
- #$msg.Attachments.Add($logfile)
- $smtp = new-object System.Net.Mail.SmtpClient
- $smtp.host=$smtpServer
- Try {
- $smtp.Send($msg)
- "Email Sent" | LogMe -displaygreen
- } Catch {
- "Error Sending Email. See Error Messages Below:" | LogMe -error
- "Error Message: " + $_.Exception.Message | LogMe -error
- "Error Item: " + $_.Exception.ItemName | LogMe -error
- }
- Start-Sleep 3
- $msg.Dispose()
- if (Test-Path $AlertEmail) { clear-content $AlertEmail }
- $CurrTime | Add-Content $AlertEmail
- }
- } else {
- "Not sending an email since there were no new Errors detected" |LogMe -displaynormal
- }
- }
- function CheckForErrors {
- # Checking to see if there were any Errors Detected
- # If there were, update the CurrentAlerts Log File for later comparison
- $Script:Activity="Checking for Errors"
- if ($script:ErrorMessage -ne $Null) {
- if (Test-Path $CurrentAlerts) { clear-content $CurrentAlerts }
- foreach ($line in $script:ErrorMessage) {$Line | Add-Content $CurrentAlerts}
- # Get Content from Alert Log File, we want the first line, which should be the previuos time stamp.
- if (Test-Path $AlertEmail) {
- $AlertFileTime = gc $AlertEmail -TotalCount 1 }
- # Check to see if the Time Span for sending alerts has passed
- if ($AlertFileTime){
- $AlertTimeSpan = New-TimeSpan $AlertFileTime $(Get-Date -format g)
- $AlertTimeDifference = $AlertTimeSpan.TotalSeconds
- if (!$AlertTimeDifference) { $Script:SendEmail = $True }
- if ($AlertTimeDifference -ge $EmailAlertsLagTime) {
- $Script:SendEmail = $True
- "Email Alerts lag Time is $EmailAlertsLagTime seconds"
- "Alerts last sent on $AlertFileTime or $AlertTimeDifference seconds ago"
- } else { $Script:SendEmail = $False }
- }
- if (!$AlertFileTime) { $Script:SendEmail = $True }
- # Checking Alert Log Contents from last run for comparison
- if (Test-Path $AlertsEmailed) { $AlertLogContents = gc $AlertsEmailed }
- # Checking Current Errors and Warnings found this duration for comparison
- if (Test-Path $CurrentAlerts) { $CurrentAlertsContents = gc $CurrentAlerts }
- # If the Alerts Email Log is empty but the Current Log is not, there are new alerts.
- If (!$AlertLogContents -and $CurrentAlertsContents) {
- $Script:NewAlerts = $True
- $Script:SendEmail = $True
- "New Alerts Detected" | LogMe -warning
- } ElseIf ($AlertLogContents -and $CurrentAlertsContents -and $Script:SendEmail -ne $True ) {
- # If the Alert Email Log and the Current Alert Log matches then there are most likely no new errors
- $AlertsDiff = compare-object $CurrentAlertsContents $AlertLogContents | Measure
- If ($AlertsDiff.count -gt "0") {
- $Script:SendEmail = $True
- $Script:NewAlerts = $True
- "New Alerts Detected" | LogMe -warning
- } else {
- $Script:NewAlerts = $False
- "Existing Alerts Detected" | LogMe -warning
- "Previous Alerts are the same as Existing Alerts and lag time not reached" | LogMe -displaynormal
- "No NEW Alerts Detected" | LogMe -displaynormal
- }
- }
- } else {
- if (Test-Path $CurrentAlerts) {
- clear-content $CurrentAlerts}
- }
- }
- function KillProcess {
- # Killing left over processes from Receiver so the script will work the next time it is executed
- # This is really only needed when running as a scheduled task
- # If these processes are allowed to remain the Connection fails after the second try
- $Script:Activity="Killing Receiver Processes"
- "Killing processes from Receiver so the script will work, existing processes will prevent the ICO from working" | LogMe -displaynormal
- $KillApps = $True
- if ($KillApps -eq $True){
- try {kill -name wfcrun32 -Force -ErrorAction SilentlyContinue}
- catch {$_.Exception.Message}
- try {kill -name concentr -Force -ErrorAction SilentlyContinue}
- catch {$_.Exception.Message}
- try {kill -name redirector -Force -ErrorAction SilentlyContinue}
- catch {$_.Exception.Message}
- try {kill -name wfica32 -Force -ErrorAction SilentlyContinue}
- catch {$_.Exception.Message}
- try {kill -name receiver -Force -ErrorAction SilentlyContinue}
- catch {$_.Exception.Message}
- }
- Start-Sleep -Seconds 3
- }
- function Create-PreviuosRunLog {
- # Creating Log file for previuos ran jobs
- # File is cleared when it reaches 1MB
- if (test-path $PreviuosLogFile) {
- $size = Get-ChildItem $PreviuosLogFile
- if ($size.length -ge 1048576) {clear-content $PreviuosLogFile}
- }
- $LogPattern = @("[SUCCESS]","[ERROR]","[WARNING]","[SCRIPT_START]","[SCRIPT_END]")
- if (Test-Path $Script:LogFile) {Get-Content $Script:LogFile | add-Content $PreviuosLogFile}
- }
- Function LogMe() {
- #===================================================================== #
- # Sends the results into a logfile as well as in the powershell window #
- #===================================================================== #
- Param( [parameter(Mandatory = $true, ValueFromPipeline = $true)] $logEntry,
- [switch]$displaygreen,
- [switch]$error,
- [switch]$warning,
- [switch]$displaynormal,
- [switch]$displayscriptstartend,
- [switch]$justprogressbar
- )
- $Status = $logEntry
- if($error) {
- $script:ErrorMessage += "<p $ErrorStyle>$logEntry<p>"
- Write-Host "$logEntry" -Foregroundcolor Red; $logEntry = [DateTime]::Now.ToString("[MM/dd/yyy HH:mm:ss.fff]: ") + "[ERROR] $logEntry"
- }
- elseif($warning) { Write-Host "$logEntry" -Foregroundcolor Yellow; $logEntry = [DateTime]::Now.ToString("[MM/dd/yyy HH:mm:ss.fff]: ") + "[WARNING] $logEntry"}
- elseif ($displaynormal) { Write-Host "$logEntry" -Foregroundcolor White; $logEntry = [DateTime]::Now.ToString("[MM/dd/yyy HH:mm:ss.fff]: ") + "[INFO] $logEntry" }
- elseif($displaygreen) { Write-Host "$logEntry" -Foregroundcolor Green; $logEntry = [DateTime]::Now.ToString("[MM/dd/yyy HH:mm:ss.fff]: ") + "[SUCCESS] $logEntry" }
- elseif($displayscriptstartend) { Write-Host "$logEntry" -Foregroundcolor Magenta; $logEntry = "[SCRIPT_STARTEND] $logEntry" }
- elseif($justprogressbar) { $logEntry=$Null }
- else { Write-Host "$logEntry"; $logEntry = "$logEntry" }
- if ($logEntry -ne $null) {$logEntry | Out-File -FilePath $Script:LogFile -Append}
- Create-ProgressBar $Script:Activity $Status
- }
- function Wait-ForPageReady {
- "Waiting for Internet Explorer to return Page Ready" | LogMe -displaynormal
- $try = 1
- do {
- $Script:Activity="Waiting for Page Ready"
- "Try #$try`: Waiting for Internet Explorer to return Page Ready" | LogMe -justprogressbar
- Start-Sleep 5
- $try++
- }
- until ($internetExplorer.ReadyState -eq 4 -or $try -gt 12)
- if ($internetExplorer.ReadyState -ne 4) {
- "Internet Explorer did not repsond Page Ready within time allotted" | LogMe -error
- break
- }
- }
- function Open-InternetExplorer {
- Param ([Parameter(Mandatory=$true)] [string]$SiteURL)
- $Script:Activity="Opening Internet Explorer"
- "Creating Internet Explorer Component Object Model (COM)" | LogMe -displaynormal
- Start-Sleep -seconds 1
- New-Variable -Name internetExplorer -Value (New-Object -ComObject "InternetExplorer.Application") -Scope Script
- "Setting Internet Explorer visible" | LogMe -displaynormal
- Start-Sleep -seconds 1
- $internetExplorer.visible = $true
- "Navigating to '$SiteURL'" | Logme -displaynormal
- Start-Sleep -seconds 1
- $internetExplorer.Navigate2($SiteURL)
- "Waiting until the page is ready" | Logme -displaynormal
- Wait-ForPageReady
- "Accessing Document Object Model (DOM)" | Logme -displaynormal
- Start-Sleep -seconds 1
- New-Variable -Name document -Value $internetExplorer.Document -Scope Script
- }
- function Test-LoginForm {
- "Detecting NetScaler Gateway or StoreFront login form" | Logme -displaynormal
- $Script:Activity="Detecting NetScaler Gateway or StoreFront login form"
- start-sleep 1
- $loginButton = $null
- $try = 1
- do {
- $NGloginButton = [System.__ComObject].InvokeMember(“getElementByIdâ€,[System.Reflection.BindingFlags]::InvokeMethod, $null, $document, $NGLoginButtonId)
- $SFloginButton = [System.__ComObject].InvokeMember(“getElementByIdâ€,[System.Reflection.BindingFlags]::InvokeMethod, $null, $document, $SFLoginButtonId)
- if ($NGloginButton -ne $null -and $NGloginButton.GetType() -ne [DBNull]) {
- "NETSCALER GATEWAY DETECTED" | Logme -displaygreen
- Start-Sleep -Seconds 1
- New-Variable -Name isNG -Value $true -Scope Script
- $loginButton = $NGloginButton
- break
- } elseif ($SFloginButton -ne $null -and $SFloginButton.GetType() -ne [DBNull]) {
- "STOREFRONT DETECTED" | Logme -displaygreen
- Start-Sleep -Seconds 1
- New-Variable -Name isNG -Value $false -Scope Script
- $loginButton = $SFloginButton
- break
- } else {
- "Try #$try`: Still detecting..." | LogMe -justprogressbar
- Start-Sleep -Seconds 3
- $try++
- }
- } until ($try -gt $NumberOfRetries)
- if ($loginButton -eq $null -or $loginButton.GetType() -eq [DBNull]) {
- "Log on button not found" | Logme -error
- Start-Sleep -Seconds 1
- }
- }
- function Submit-UserCredentials {
- $Script:Activity="Submitting User Credentials"
- if ($isNG) {
- "Getting Log On button" | Logme -displaynormal
- $loginButton = [System.__ComObject].InvokeMember(“getElementByIdâ€,[System.Reflection.BindingFlags]::InvokeMethod, $null, $document, $NGLoginButtonId)
- Start-Sleep -Seconds 1
- "Getting UserName textbox" | Logme -displaynormal
- $userNameTextBox = @([System.__ComObject].InvokeMember(“getElementsByNameâ€,[System.Reflection.BindingFlags]::InvokeMethod, $null, $document, $NGUserNameTextBoxName)) | where { $_.name -eq $NGUserNameTextBoxName }
- Start-Sleep -Seconds 1
- "Getting Password textbox" | Logme -displaynormal
- $passwordTextBox = @([System.__ComObject].InvokeMember(“getElementsByNameâ€,[System.Reflection.BindingFlags]::InvokeMethod, $null, $document, $NGPasswordTextBoxName)) | where { $_.name -eq $NGPasswordTextBoxName }
- Start-Sleep -Seconds 1
- if ($TwoFactorAuth) {
- "Getting Two Factor Authentication textbox" | Logme -displaynormal
- $twoFactorTextBox = @([System.__ComObject].InvokeMember(“getElementsByNameâ€,[System.Reflection.BindingFlags]::InvokeMethod, $null, $document, $NGTwoFactorTextBoxName)) | where { $_.name -eq $NGTwoFactorTextBoxName }
- if ($twoFactorTextBox -ne $null) {
- "Setting Two Factor Authentication" | Logme -displaynormal
- $twoFactorTextBox.value = $TwoFactorAuth
- Start-Sleep -Seconds 1
- } else {"Two-factor authentication textbox not found" | Logme -error
- Start-Sleep -Seconds 1
- }
- }
- } else {
- "Getting Login button" | Logme -displaynormal
- $loginButton = [System.__ComObject].InvokeMember(“getElementByIdâ€,[System.Reflection.BindingFlags]::InvokeMethod, $null, $document, $SFLoginButtonId)
- Start-Sleep -Seconds 1
- "Getting UserName textbox" | Logme -displaynormal
- $userNameTextBox = [System.__ComObject].InvokeMember(“getElementByIdâ€,[System.Reflection.BindingFlags]::InvokeMethod, $null, $document, $SFUsernameTextBoxId)
- Start-Sleep -Seconds 1
- "Getting Password textbox" | Logme -displaynormal
- $passwordTextBox = [System.__ComObject].InvokeMember(“getElementByIdâ€,[System.Reflection.BindingFlags]::InvokeMethod, $null, $document, $SFPasswordTextBoxId)
- Start-Sleep -Seconds 1
- }
- if ($userNameTextBox -ne $null -and $userNameTextBox.GetType() -ne [DBNull]) {
- "Setting UserName '$UserName'" | Logme -displaynormal
- $userNameTextBox.Value = $UserName
- Start-Sleep -Seconds 1
- } else {"UserName textbox not found" | Logme -error}
- if ($passwordTextBox -ne $null -and $passwordTextBox.GetType() -ne [DBNull]) {
- "Setting Password" | Logme -displaynormal
- $passwordTextBox.Value = $Password
- Start-Sleep -Seconds 1
- } else {"Password textbox not found" | Logme -error}
- if ($loginButton -ne $null -and $loginButton.GetType() -ne [DBNull]) {
- "Clicking Log On button" | Logme -displaynormal
- $loginButton.Click()
- Start-Sleep -Seconds 1
- } else {"Login button not found" | Logme -error
- Start-Sleep -Seconds 1
- }
- }
- function Start-Resource {
- $Script:Activity="Getting Storefront resources page"
- "Getting Storefront resources page" | Logme -displaynormal
- Start-Sleep -Seconds 3
- $try = 1
- do {
- $logoffLink = [System.__ComObject].InvokeMember(“getElementByIdâ€,[System.Reflection.BindingFlags]::InvokeMethod, $null, $document, $SFLogOffLinkId)
- if ($logoffLink -ne $null -and $logoffLink.GetType() -ne [DBNull]) {
- "Successfully found Storefront resources page" | LogMe -displaygreen
- Start-Sleep -Seconds 1
- break
- } else {
- "Try #$try`: Still looking..." | LogMe -justprogressbar
- Start-Sleep -Seconds 3
- $try++
- }
- } until ($try -gt $NumberOfRetries)
- if ($logoffLink -eq $null -or $logoffLink.GetType() -eq [DBNull]) {
- "StoreFront recources page not found, possible page loading issue or logon issue" | Logme -error
- Start-Sleep -Seconds 3
- $Script:StoreFrontRP = $False
- }
- if ($Script:StoreFrontRP -ne $False){
- foreach ($App in $ResourceName){
- $ScriptActivity="Locating resource '$App'"
- "Locating resource '$App'" | Logme -displaynormal
- Start-Sleep -Seconds 1
- $try = 1
- do {
- $resource = @([System.__ComObject].InvokeMember(“getElementsByTagNameâ€,[System.Reflection.BindingFlags]::InvokeMethod, $null, $document, "img")) | where { $_.alt -eq $App }
- if ($resource -ne $null) {
- "Successfully Located resource '$App'" | LogMe -displaygreen
- Start-Sleep -Seconds 1
- break
- } else {
- "Try #$try`: Still Looking..." | LogMe -justprogressbar
- Start-Sleep -Seconds 3
- $try++
- }
- } until ($try -gt $NumberOfRetries)
- if ($resource -eq $null) {
- "The ResourceName specified, '$App', was not found" | LogMe -error
- Start-Sleep -Seconds 1
- "Either the App was mistyped on the command line or it is not visible on the Storefront main page" | LogMe -error
- Start-Sleep -Seconds 1
- $ResourceFound = $false
- }
- if ($ResourceFound -ne $false) {
- $Script:Activity="Looking for existing ICA Connections"
- $wficaBefore = @()
- Get-Process wfica32 -ErrorAction SilentlyContinue | select id | % { $wficaBefore += $_.id }
- if ($($wficaBefore.Count) -ge 1) {
- $SkipApp = $true
- "Found $($wficaBefore.Count) session(s) before clicking '$App'" | Logme -error
- "The script will only work correctly when there are no existing connections" | Logme -error
- "Sessions will be disconnected when Receiver is killed at the end of the script and should work next time" | Logme -error
- Start-Sleep -Seconds 1
- throw("Found $($wficaBefore.Count) session(s) before clicking '$App'")
- }
- else {
- $SkipApp = $false
- "Found $($wficaBefore.Count) session(s) before clicking '$App'" | Logme -displaynormal
- Start-Sleep -Seconds 1
- "Clicking resource '$App'" | Logme -displaynormal
- Start-Sleep -Seconds 1
- $LaunchTime = Get-Date
- "Connect Started at $LaunchTime" | Logme -displaygreen
- $resource.Click()
- }
- $Script:Activity="Verifying that the session launched"
- "Looking for connection info" | Logme -displaynormal
- $wficaFound = $false
- $try =1
- do {
- $wficaAfter = @()
- Get-Process wfica32 -ErrorAction SilentlyContinue | select id | % { $wficaAfter += $_.id }
- $wficaComparison = Compare-Object $wficaBefore $wficaAfter -PassThru
- if ($wficaComparison -ne $null) {
- foreach ($wfica in $wficaComparison) {
- if ($wfica.SideIndicator -eq '=>') {
- $wficaFound = $true
- "Found $($wficaAfter.Count) sessions after clicking '$App'","Found wfica32.exe with PID $wfica for session launched" | Logme -displaygreen
- break
- }
- }
- }
- if ($wficaFound -and $SkipApp -ne $True) {
- $index = $null
- "Waiting for '" + $App + "' to launch." | Logme -displaynormal
- Do {
- try {Add-Type -Path $DLLPath}
- catch {throw "Error loading $DLLPath"}
- $ICO = New-Object WFICALib.ICAClientClass
- $ICO.OutputMode = [WFICALib.OutputMode]::OutputModeNormal
- $EnumHandle = $ICO.EnumerateCCMSessions()
- $NumSessions = $ICO.GetEnumNameCount($EnumHandle );
- $sessionid = $ICO.GetEnumNameByIndex($EnumHandle, $index)
- $ICO.StartMonitoringCCMSession($sessionid,$true)
- $APPSERVER = $ICO.GetSessionString(0)
- $null = $ICO.CloseEnumHandle($EnumHandle)
- $ICO.StopMonitoringCCMSession($sessionid)
- "Waiting to find an active XenApp Server for '$App'" | LogMe -justprogressbar
- Start-Sleep -Seconds 1
- $try++
- }
- until ($APPSERVER -or $try -gt $TimeToWaitForApp)
- if([string]::IsNullOrEmpty($APPSERVER) -and $SkipApp -ne $true) {
- "Unable to confirm that session launched for '$App'" | LogMe -error
- "The time to launch '$App' could have taken longer than $TimeToWaitForApp seconds" | LogMe -error
- }
- else {
- "Found an active XenApp Server for '$App'" | LogMe -displaygreen
- $logonelapsed = GetElapsedTime $LaunchTime
- Start-Sleep -Seconds 1
- "Time taken to launch App is: $logonelapsed" | Logme -displaygreen
- Start-Sleep -Seconds 1
- $App + " appears to be connected to Server: " + $APPSERVER | Logme -displaynormal
- Start-Sleep -Seconds 1
- try {Add-Type -Path $DLLPath}
- catch {throw "Error loading WfIcaLib.dll"}
- $ICO = New-Object WFICALib.ICAClientClass
- $ICO.OutputMode = [WFICALib.OutputMode]::OutputModeNormal
- $EnumHandle = $ICO.EnumerateCCMSessions()
- $NumSessions = $ICO.GetEnumNameCount($EnumHandle );
- "Number of ICA Sessions is: $NumSessions" | Logme -displaygreen
- $sessionid = $ICO.GetEnumNameByIndex($EnumHandle, $index)
- "Session ID: " + $sessionid | Logme -displaygreen
- "Active XenApp Server is: " + $APPSERVER | Logme -displaygreen
- $ICO.StartMonitoringCCMSession($sessionid,$true)
- "Sleeping for $TimeToWaitForLogoff seconds before sending ICA Logoff Command" | Logme -displaynormal
- Start-Sleep -Seconds $TimeToWaitForLogoff
- "Sending Logoff Command" | Logme -displaynormal
- $ICO.Logoff()
- Start-Sleep -Seconds 15
- $null = $ICO.CloseEnumHandle($EnumHandle)
- $ICO.StopMonitoringCCMSession($sessionid)
- }
- break
- }
- else {
- "Try #$try`: Still looking..." | LogMe -justprogressbar
- Start-Sleep -Seconds 3
- $try++
- }
- } until ($try -gt $NumberOfRetries)
- if (-not $wficaFound) {
- "Unable to confirm that session launched for '$App'" | LogMe -error
- Start-Sleep -Seconds 1
- }
- }
- }
- }
- }
- function Logoff-Storefront {
- $Script:Activity="Logoff StoreFront"
- if ($Script:StoreFrontRP -ne $False){
- "Sleeping $SleepBeforeLogoff seconds before logging off Storefront" | Logme -displaynormal
- Start-Sleep -Seconds $SleepBeforeLogoff
- "Getting log off link" | LogMe -displaynormal
- Start-Sleep -Seconds 3
- $try = 1
- do {
- $logoffLink = [System.__ComObject].InvokeMember(“getElementByIdâ€,[System.Reflection.BindingFlags]::InvokeMethod, $null, $document, $SFLogOffLinkId)
- if ($logoffLink -ne $null -and $logoffLink.GetType() -ne [DBNull]) {
- "Found log off link" | LogMe -displaygreen
- Start-Sleep -Seconds 1
- break
- }
- else {
- "Try #$try`: Still looking..." | LogMe -justprogressbar
- Start-Sleep -Seconds 3
- $try++
- }
- }
- until ($try -gt $NumberOfRetries)
- if ($logoffLink -eq $null -or $logoffLink.GetType() -eq [DBNull]) {
- "Log off link not found" | Logme -error
- Start-Sleep -Seconds 1
- } else {
- "Clicking log off link" | Logme -displaynormal
- Start-Sleep -Seconds 1
- $logoffLink.Click()
- }
- }
- }
- try {
- cls
- $startTime = Get-Date
- rm -path $($LogFilePath.TrimEnd('\') + "\$LogFileName") -force -EA SilentlyContinue
- $Script:Activity = "Starting Script"
- ""
- ""
- ""
- ""
- ""
- ""
- ""
- ""
- "********** LAUNCHER SCRIPT START **********" | Logme -displayscriptstartend
- ""
- ScriptInfo
- "Checking for Citrix Cient DLL" | logMe -displaynormal
- CheckforDLL
- "Checking Citrix Client Verion" | Logme -displaynormal
- $ClientVersion = Get-ICAClientVersion
- "Citrix Client Version: " + $ClientVersion | Logme -displaynormal
- KillProcess
- CheckRegistry
- if ($RegError -eq $Null) {
- Open-InternetExplorer -SiteURL $SiteURL
- Test-LoginForm
- Submit-UserCredentials
- Wait-ForPageReady
- Start-Resource
- Logoff-Storefront
- }
- }
- catch {
- "Exception caught by script" | Logme -error
- $Error1 = $_.ToString()
- $Error1 | Logme -error
- $Error2 = $_.InvocationInfo.PositionMessage
- $Error2 | Logme -error
- throw $_
- }
- finally {
- if ($internetExplorer -is [System.__ComObject]) {
- if ($internetExplorer | Get-Member 'Quit') {
- "Quitting Internet Explorer" | Logme -displaynormal
- Start-Sleep -Seconds 3
- $internetExplorer.Quit()
- }
- "Releasing Internet Explorer Component Object Model (COM)" | Logme -displaynormal
- Start-Sleep -Seconds 3
- [System.Runtime.Interopservices.Marshal]::ReleaseComObject($internetExplorer) | Out-Null
- Remove-Variable -Name internetExplorer
- }
- #Kill Receiver Processes, only needed when ran as a scheduled task
- KillProcess
- CheckForErrors
- Send-Email
- Complete-ProgressBar $Activity="Script End" $Status="Exiting"
- Create-PreviuosRunLog
- ""
- "********** LAUNCHER SCRIPT END **********" | Logme -displayscriptstartend
- ""
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement