Advertisement
henrydenhengst

Test StoreFront or NetScaler Gateway v.1

Aug 17th, 2015
553
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. <#
  2.     .SYNOPSIS
  3.         Launch HDX session to a published resource through StoreFront or NetScaler Gateway (integrated with StoreFront).
  4.     .DESCRIPTION
  5.         This script launches an HDX session to a published resource through StoreFront or NetScaler Gateway (integrated with StoreFront).
  6.  
  7.         It attempts to closely resemble what an actual user would do by:
  8.         -Opening Internet Explorer.
  9.         -Navigating directly to the Receiver for Web site or NetScaler Gateway portal.
  10.         -Completing the fields.
  11.         -Logging in.
  12.         -Clicking on the resource.
  13.         -Logging off the StoreFront site.      
  14.  
  15.         Requirements:
  16.         -Use an Administrator console of PowerShell.
  17.         -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.
  18.         -StoreFront 2.0 or higher.
  19.         -If using NetScaler Gateway, version 9.3 or higher.
  20.         -Changes in web.config under C:\inetpub\wwwroot\Citrix\<storename>Web\: autoLaunchDesktop to false, pluginAssistant to false and logoffAction to none.
  21.         -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.
  22.  
  23.         By default, the script creates a log file with the username like SFLauncher_username.log.
  24.     .PARAMETER SiteURL
  25.         The complete URL of the StoreFront Receiver for Web site or NetScaler Gateway portal.
  26.     .PARAMETER UserName
  27.         The name of the user which is used to log on. Acceptable forms are down-level logon name or user principal name.
  28.     .PARAMETER Password
  29.         The password of the user which is used to log on.
  30.     .PARAMETER ResourceName
  31.         The display name of the resource to be launched.
  32.     .PARAMETER SleepBeforeLogoff
  33.         The time in seconds to sleep after clicking the resource and before logging off. Default is 5.
  34.     .PARAMETER NumberOfRetries
  35.         The number of retries when retrieving an element. Default is 30.
  36.     .PARAMETER LogFilePath
  37.         Directory path to where the log file will be saved. Default is SystemDrive\Temp.
  38.     .PARAMETER LogFileName
  39.         File name for the log file. Default is SFLauncher_<UserName>.log.
  40.     .PARAMETER NoLogFile
  41.         Specify to disable logging to a file.
  42.     .PARAMETER NoConsoleOutput
  43.         Specify to disable logging to the console.
  44.     .PARAMETER TwoFactorAuth
  45.         The token or password used for two-factor authentication. This is used in the NetScaler Gateway portal.
  46.     .EXAMPLE
  47.         SFLauncher.ps1 -SiteURL "http://storefront.domain.com" -UserName "domain1\User1" -Password "P4ssw0rd" -ResourceName "My Desktop"
  48.  
  49.         Description
  50.         -----------
  51.         Launches a session to a resource using the parameters provided.
  52.     .LINK
  53.         UserName format used in StoreFront.
  54.         http://msdn.microsoft.com/en-us/library/windows/desktop/aa380525(v=vs.85).aspx#down_level_logon_name
  55.     .LINK
  56.         Change to autoLaunchDesktop.
  57.         http://support.citrix.com/proddocs/topic/dws-storefront-20/dws-configure-wr-view.html
  58.     .LINK
  59.         Change to logoffAction.
  60.         http://support.citrix.com/proddocs/topic/dws-storefront-20/dws-configure-wr-workspace.html
  61.     .NOTES
  62.         Copyright (c) Citrix Systems, Inc. All rights reserved.
  63.         Version 1.1
  64. #>
  65.  
  66. Param (
  67.     [Parameter(Mandatory=$true,Position=0)] [string]$SiteURL,
  68.     [Parameter(Mandatory=$true,Position=1)] [string]$UserName,
  69.     [Parameter(Mandatory=$true,Position=2)] [string]$Password,
  70.     [Parameter(Mandatory=$true,Position=3)] [string]$ResourceName,
  71.     [Parameter(Mandatory=$false)] [int]$SleepBeforeLogoff = 5,
  72.     [Parameter(Mandatory=$false)] [int]$NumberOfRetries = 30,
  73.     [Parameter(Mandatory=$false)] [string]$LogFilePath = "$($env:SystemDrive)\Temp\",
  74.     [Parameter(Mandatory=$false)] [string]$LogFileName = "SFLauncher_$($UserName.Replace('\','_')).log",
  75.     [Parameter(Mandatory=$false)] [switch]$NoLogFile,
  76.     [Parameter(Mandatory=$false)] [switch]$NoConsoleOutput,
  77.     [Parameter(Mandatory=$false)] [string]$TwoFactorAuth
  78. )
  79.  
  80. Set-StrictMode -Version 2
  81.  
  82. Set-Variable -Name NGLoginButtonId -Value "Log_On" -Option Constant -Scope Script
  83. Set-Variable -Name NGUserNameTextBoxName -Value "login" -Option Constant -Scope Script
  84. Set-Variable -Name NGPasswordTextBoxName -Value "passwd" -Option Constant -Scope Script
  85. Set-Variable -Name NGTwoFactorTextBoxName -Value "passwd1" -Option Constant -Scope Script
  86.  
  87. Set-Variable -Name SFLoginButtonId -Value "loginBtn" -Option Constant -Scope Script
  88. Set-Variable -Name SFUsernameTextBoxId -Value "username" -Option Constant -Scope Script
  89. Set-Variable -Name SFPasswordTextBoxId -Value "password" -Option Constant -Scope Script
  90. Set-Variable -Name SFLogOffLinkId -Value "userdetails-logoff" -Option Constant -Scope Script
  91.  
  92. function Write-SFLauncherHeader {
  93.     $infoMessage = @"
  94.  
  95.                           *****************************************************
  96.                           *****  Citrix Solutions Lab SF Launcher Script  *****
  97.                           *****        -Console output:     {0,-6}        *****
  98.                           *****        -Log output:         {1,-6}        *****
  99.                           *****************************************************
  100.  
  101. "@  -f $(-not $NoConsoleOutput),$(-not $NoLogFile)
  102.     Write-Host $infoMessage
  103. }
  104.  
  105. function Write-ToSFLauncherLog {
  106.     Param (
  107.         [Parameter(Mandatory=$true,ValueFromPipeline=$true)] [string]$Message,
  108.         [Parameter(Mandatory=$false)] [string]$LogFile=$($LogFilePath.TrimEnd('\') + "\$LogFileName"),
  109.         [Parameter(Mandatory=$false)] [bool]$NoConsoleOutput=$NoConsoleOutput,
  110.         [Parameter(Mandatory=$false)] [bool]$NoLogFile=$NoLogFile
  111.     )
  112.     Begin {
  113.         if(Test-Path $LogFile -IsValid) {
  114.             if(!(Test-Path "$LogFile" -PathType Leaf)) {
  115.                 New-Item -Path $LogFile -ItemType "file" -Force -ErrorAction Stop | Out-Null           
  116.             }
  117.         } else {
  118.             throw "Log file path is invalid"
  119.         }
  120.     }
  121.     Process {
  122.         $Message = [DateTime]::Now.ToString("[MM/dd/yyy HH:mm:ss.fff]: ") + $Message
  123.  
  124.         if (-not $NoConsoleOutput) {
  125.             Write-Host $Message
  126.         }
  127.              
  128.         if (-not $NoLogFile) {
  129.             $Message | Out-File -FilePath $LogFile -Append
  130.         }
  131.     }
  132. }
  133.  
  134. function Wait-ForPageReady {
  135.     while ($internetExplorer.ReadyState -ne 4) {
  136.         Write-ToSFLauncherLog "Internet Explorer: BUSY"
  137.         Start-Sleep 1
  138.     }  
  139. }
  140.  
  141. function Open-InternetExplorer {
  142.     Param (
  143.         [Parameter(Mandatory=$true)] [string]$SiteURL    
  144.     )
  145.     Write-ToSFLauncherLog "Creating Internet Explorer COM object"
  146.     New-Variable -Name internetExplorer -Value (New-Object -ComObject "InternetExplorer.Application") -Scope Script
  147.     Write-ToSFLauncherLog "Setting Internet Explorer visible"
  148.     $internetExplorer.visible = $true
  149.     Write-ToSFLauncherLog "Navigating to '$SiteURL'"
  150.     $internetExplorer.Navigate2($SiteURL)
  151.     Wait-ForPageReady
  152.     Write-ToSFLauncherLog "Accessing DOM"
  153.     New-Variable -Name document -Value $internetExplorer.Document -Scope Script
  154. }
  155.  
  156. function Test-LoginForm {
  157.     Write-ToSFLauncherLog "Detecting NetScaler Gateway or StoreFront login form..."
  158.     $loginButton = $null
  159.     $try = 1
  160.     do {
  161.         $NGloginButton = [System.__ComObject].InvokeMember(“getElementById”,[System.Reflection.BindingFlags]::InvokeMethod, $null, $document, $NGLoginButtonId)
  162.         $SFloginButton = [System.__ComObject].InvokeMember(“getElementById”,[System.Reflection.BindingFlags]::InvokeMethod, $null, $document, $SFLoginButtonId)
  163.         if ($NGloginButton -ne $null -and $NGloginButton.GetType() -ne [DBNull]) {
  164.             "Try #$try`: SUCCESS","NETSCALER GATEWAY DETECTED" | Write-ToSFLauncherLog
  165.             New-Variable -Name isNG -Value $true -Scope Script
  166.             $loginButton = $NGloginButton
  167.             break
  168.         } elseif ($SFloginButton -ne $null -and $SFloginButton.GetType() -ne [DBNull]) {
  169.             "Try #$try`: SUCCESS","STOREFRONT DETECTED" | Write-ToSFLauncherLog
  170.             New-Variable -Name isNG -Value $false -Scope Script
  171.             $loginButton = $SFloginButton
  172.             break
  173.         } else {
  174.             Write-ToSFLauncherLog "Try #$try`: FAIL"
  175.             Start-Sleep -Seconds 1
  176.             $try++
  177.         }
  178.     } until ($try -gt $NumberOfRetries)
  179.     if ($loginButton -eq $null -or $loginButton.GetType() -eq [DBNull]) {
  180.         throw "Login button not found"
  181.     }    
  182. }
  183.  
  184. function Submit-UserCredentials {
  185.     if ($isNG) {
  186.         Write-ToSFLauncherLog "Getting Login button"
  187.         $loginButton = [System.__ComObject].InvokeMember(“getElementById”,[System.Reflection.BindingFlags]::InvokeMethod, $null, $document, $NGLoginButtonId)
  188.         Write-ToSFLauncherLog "Getting UserName textbox"
  189.         $userNameTextBox = @([System.__ComObject].InvokeMember(“getElementsByName”,[System.Reflection.BindingFlags]::InvokeMethod, $null, $document, $NGUserNameTextBoxName)) | where { $_.name -eq $NGUserNameTextBoxName }
  190.         Write-ToSFLauncherLog "Getting Password textbox"
  191.         $passwordTextBox = @([System.__ComObject].InvokeMember(“getElementsByName”,[System.Reflection.BindingFlags]::InvokeMethod, $null, $document, $NGPasswordTextBoxName)) | where { $_.name -eq $NGPasswordTextBoxName }
  192.         if ($TwoFactorAuth) {
  193.             Write-ToSFLauncherLog "Getting Two Factor Authentication textbox"
  194.             $twoFactorTextBox = @([System.__ComObject].InvokeMember(“getElementsByName”,[System.Reflection.BindingFlags]::InvokeMethod, $null, $document, $NGTwoFactorTextBoxName)) | where { $_.name -eq $NGTwoFactorTextBoxName }
  195.                 if ($twoFactorTextBox -ne $null) {
  196.                     Write-ToSFLauncherLog "Setting Two Factor Authentication"
  197.                     $twoFactorTextBox.value = $TwoFactorAuth
  198.                 } else {
  199.                     throw "Two-factor authentication textbox not found"
  200.                 }
  201.         }
  202.     } else {
  203.         Write-ToSFLauncherLog "Getting Login button"
  204.         $loginButton = [System.__ComObject].InvokeMember(“getElementById”,[System.Reflection.BindingFlags]::InvokeMethod, $null, $document, $SFLoginButtonId)
  205.         Write-ToSFLauncherLog "Getting UserName textbox"
  206.         $userNameTextBox = [System.__ComObject].InvokeMember(“getElementById”,[System.Reflection.BindingFlags]::InvokeMethod, $null, $document, $SFUsernameTextBoxId)
  207.         Write-ToSFLauncherLog "Getting Password textbox"
  208.         $passwordTextBox = [System.__ComObject].InvokeMember(“getElementById”,[System.Reflection.BindingFlags]::InvokeMethod, $null, $document, $SFPasswordTextBoxId)
  209.     }            
  210.    
  211.     if ($userNameTextBox -ne $null -and $userNameTextBox.GetType() -ne [DBNull]) {
  212.         Write-ToSFLauncherLog "Setting UserName '$UserName'"
  213.         $userNameTextBox.Value = $UserName
  214.     } else {
  215.         throw "UserName textbox not found"
  216.     }
  217.    
  218.     if ($passwordTextBox -ne $null -and $passwordTextBox.GetType() -ne [DBNull]) {
  219.         Write-ToSFLauncherLog "Setting Password"
  220.         $passwordTextBox.Value = $Password
  221.     } else {
  222.         throw "Password textbox not found"
  223.     }
  224.  
  225.     if ($loginButton -ne $null -and $loginButton.GetType() -ne [DBNull]) {
  226.         Write-ToSFLauncherLog "Clicking login button"
  227.         $loginButton.Click()
  228.     } else {
  229.         throw "Login button not found"
  230.     }
  231. }
  232.  
  233. function Start-Resource {
  234.     Write-ToSFLauncherLog "Getting SF resources page..."
  235.     $try = 1
  236.     do {
  237.         $logoffLink = [System.__ComObject].InvokeMember(“getElementById”,[System.Reflection.BindingFlags]::InvokeMethod, $null, $document, $SFLogOffLinkId)
  238.         if ($logoffLink -ne $null -and $logoffLink.GetType() -ne [DBNull]) {
  239.             Write-ToSFLauncherLog "Try #$try`: SUCCESS"
  240.             break
  241.         } else {
  242.             Write-ToSFLauncherLog "Try #$try`: FAIL"
  243.             Start-Sleep -Seconds 1
  244.             $try++
  245.         }
  246.     } until ($try -gt $NumberOfRetries)
  247.     if ($logoffLink -eq $null -or $logoffLink.GetType() -eq [DBNull]) {
  248.         throw "SF recources page not found"
  249.     }
  250.  
  251.     Write-ToSFLauncherLog "Getting resource '$ResourceName'..."
  252.     $try = 1
  253.     do {
  254.         $resource = @([System.__ComObject].InvokeMember(“getElementsByTagName”,[System.Reflection.BindingFlags]::InvokeMethod, $null, $document, "img")) | where { $_.alt -eq $ResourceName }
  255.         if ($resource -ne $null) {
  256.             Write-ToSFLauncherLog "Try #$try`: SUCCESS"
  257.             break
  258.         } else {
  259.             Write-ToSFLauncherLog "Try #$try`: FAIL"
  260.             Start-Sleep -Seconds 1
  261.             $try++
  262.         }
  263.     } until ($try -gt $NumberOfRetries)
  264.     if ($resource -eq $null) {
  265.         throw "Resource '$ResourceName' not found"
  266.     }
  267.  
  268.     $wficaBefore = @()
  269.     Get-Process wfica32 -ErrorAction SilentlyContinue | select id | % { $wficaBefore += $_.id }
  270.     Write-ToSFLauncherLog "Found $($wficaBefore.Count) session(s) before clicking '$ResourceName'"
  271.  
  272.     Write-ToSFLauncherLog "Clicking resource '$ResourceName'"
  273.     $resource.Click()
  274.  
  275.     Write-ToSFLauncherLog "Verifying that session launched..."
  276.     $wficaFound = $false
  277.     $try =1
  278.     do {    
  279.         $wficaAfter = @()
  280.         Get-Process wfica32 -ErrorAction SilentlyContinue | select id | % { $wficaAfter += $_.id }
  281.         $wficaComparison = Compare-Object $wficaBefore $wficaAfter -PassThru
  282.        
  283.         if ($wficaComparison -ne $null) {
  284.             foreach ($wfica in $wficaComparison) {
  285.                 if ($wfica.SideIndicator -eq '=>') {
  286.                     $wficaFound = $true
  287.                     "Try #$try`: SUCCESS","Found $($wficaAfter.Count) sessions after clicking '$ResourceName'","Found wfica32.exe with PID $wfica for session launched" | Write-ToSFLauncherLog
  288.                     break
  289.                 }
  290.             }
  291.         }
  292.         if ($wficaFound) {
  293.             break
  294.         } else {
  295.             Write-ToSFLauncherLog "Try #$try`: FAIL"
  296.             Start-Sleep -Seconds 1
  297.             $try++
  298.         }
  299.     } until ($try -gt $NumberOfRetries)
  300.     if (-not $wficaFound) {
  301.         Write-ToSFLauncherLog "WARNING: Unable to confirm that session launched"
  302.     }
  303. }
  304.  
  305. function Disconnect-User {
  306.     Write-ToSFLauncherLog "Sleeping $SleepBeforeLogoff seconds before logging off..."
  307.     Start-Sleep -Seconds $SleepBeforeLogoff
  308.    
  309.     Write-ToSFLauncherLog "Getting log off link..."
  310.     $try = 1
  311.     do {    
  312.         $logoffLink = [System.__ComObject].InvokeMember(“getElementById”,[System.Reflection.BindingFlags]::InvokeMethod, $null, $document, $SFLogOffLinkId)
  313.         if ($logoffLink -ne $null -and $logoffLink.GetType() -ne [DBNull]) {
  314.             Write-ToSFLauncherLog "Try #$try`: SUCCESS"
  315.             break
  316.         } else {
  317.             Write-ToSFLauncherLog "Try #$try`: FAIL"
  318.             Start-Sleep -Seconds 1
  319.             $try++
  320.         }
  321.     } until ($try -gt $NumberOfRetries)
  322.     if ($logoffLink -eq $null -or $logoffLink.GetType() -eq [DBNull]) {
  323.         Write-ToSFLauncherLog "Log off link not found"
  324.     } else {
  325.         Write-ToSFLauncherLog "Clicking log off link"
  326.         $logoffLink.Click()
  327.     }
  328. }
  329.  
  330. try {
  331.     Write-ToSFLauncherLog "*************** LAUNCHER SCRIPT BEGIN ***************"
  332.    
  333.     Write-SFLauncherHeader
  334.    
  335.     Open-InternetExplorer -SiteURL $SiteURL
  336.    
  337.     Test-LoginForm
  338.    
  339.     Submit-UserCredentials
  340.  
  341.     Wait-ForPageReady
  342.    
  343.     Start-Resource
  344.  
  345.     Disconnect-User  
  346. }
  347. catch {
  348.     Write-ToSFLauncherLog "Exception caught by script"
  349.     $_.ToString() | Write-ToSFLauncherLog
  350.     $_.InvocationInfo.PositionMessage | Write-ToSFLauncherLog
  351.     throw $_
  352. }
  353. finally {  
  354.     if ($internetExplorer -is [System.__ComObject]) {
  355.         if ($internetExplorer | Get-Member 'Quit') {
  356.             Write-ToSFLauncherLog "Quitting Internet Explorer"
  357.             $internetExplorer.Quit()
  358.         }
  359.         Write-ToSFLauncherLog "Releasing Internet Explorer COM object"
  360.         [System.Runtime.Interopservices.Marshal]::ReleaseComObject($internetExplorer) | Out-Null
  361.         Remove-Variable -Name internetExplorer
  362.     }
  363.     Write-ToSFLauncherLog "***************  LAUNCHER SCRIPT END  ***************"
  364. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement