Sunday, May 9, 2010

Keeping Citrix sessions alive with sendkeys

I use the following script as a way of keeping my Citrix session alive to thwart security guys and their over-aggressive timeouts.

Normally I don't like to use sendkeys, but this seemed like the perfect way to trick ica into thinking keys were being pressed...

PowerShell and VBScript versions below.



#
# Find the wfica.exe process and poke keystrokes at it, preventing a Citrix session from timing out
# Be careful what you have open and what keystrokes you poke

[System.Object[]]$processes = get-process | where {$_.ProcessName -eq "wfica32.exe"}
if ($processes.count -ge 1) { $process = $processes[0] }

if ($process -is [System.Diagnostics.Process])
{
  $processes | format-list -property *

  for (;;)
  {
    [void] [System.Reflection.Assembly]::LoadWithPartialName("'Microsoft.VisualBasic")

    [Microsoft.VisualBasic.Interaction]::AppActivate($process.Id)
    start-sleep -seconds 1

    [void] [System.Reflection.Assembly]::LoadWithPartialName("'System.Windows.Forms")
    [System.Windows.Forms.SendKeys]::SendWait("1")
    start-sleep -seconds 240
  }

}





Set objWshShell = CreateObject("Wscript.Shell")

strProcessName = "wfica32.exe"

intProcessID = 0
Call FindProcessID(strProcessName, intProcessID)

if (intProcessID > 0) Then
 wscript.echo "Found process ID: " & intProcessID

 Do 
  objWshShell.AppActivate(intProcessID)
  WScript.Sleep 1000
  objWshShell.SendKeys "1"
  WScript.Sleep 240000
 Loop

End If


Function FindProcessID(ByRef strProcessName, ByRef intProcessID)

 strQuery = "Select * from Win32_Process Where Name = '" & strProcessName & "'" ' WQL query string looking for the specified process

 Set objNameSpace = GetObject("winmgmts://./root/cimv2")    ' The cimv2 namespace of the local machine

 FindProcessID = vbFalse
 Set objProcessSet = objNameSpace.ExecQuery(strQuery)     ' Execute the query
 For Each objProcess in objProcessSet      ' For each process in the set, ordered by oldest to newest
  intProcessID = objProcess.ProcessID
  WScript.Echo "Found process, ID: " & intProcessID
  WScript.Echo objProcess.Name & ", " & intProcessID & ", " & objProcess.CreationDate & ", " & objProcess.CommandLine & ", " & objProcess.Priority & ", " & objProcess.WorkingSetSize & ", " & objProcess.PageFileUsage
  FindProcessID = vbTrue
 Next

 Set objNameSpace = Nothing : Set objProcessSet = Nothing : Set objProcess = Nothing
End Function


Wayne's World of IT (WWoIT), Copyright 2010 Wayne Martin.