ICA connections using Powershell – Part 1

Since version 10.x of the ICA Client, Citrix has shipped the ICA Client Object (ICO) SDK with the installation. This allows developers to control the ICA Client. Writing managed code using ICO is a breeze (my ICAConnect tool is using it), but you can easily write Powershell scripts which leverage the SDK.

The ICOSDK is accessible by using a DLL called “WfIcaLib.dll”, which is located in your ICA Client (or Citrix Receiver) installation directory (default is “%ProgramFiles%\Citrix\ICA Client” on 32bit platforms and “%ProgramFiles(x86)%\Citrix\ICA Client” on 64bit platforms). Now let’s have some fun with the ICO SDK using Powershell.

First of all, we need to start up Powershell to start working. Since the ICO SDK is a 32bit DLL, we need to start Powershell in x86 mode (this is only valid if you’re using a 64bit Operating System). Press Start > Accessories  > Windows PowerShell > Windows PowerShell (x86). Note that it should display “Windows PowerShell (x86)” in the PowerShell window.

Ok, now it’s time to load the ICO SDK library  into Powershell. This can be done by executing the following command:

[System.Reflection.Assembly]::LoadFile("C:\Program Files (x86)\Citrix\ICA Client\WfIcaLib.dll")

Note that I’m using a 64bit Operating System, so I’m pointing to “Program Files (x86)”, if you’re using a 32bit Operating System, you should point to “Program Files”. Now Powershell should display something like this:

GAC    Version        Location
---    -------        --------
False  v2.0.50727     C:\Program Files (x86)\Citrix\ICA Client\WfIcaLib.dll

Now we can start using the library. First of all, we need to create the ICAClienClass Object.

$ICA = New-Object WFICALib.ICAClientClass

All methods and properties are now available through the $ICA object. Next, we need to define some properties:

  • Address
    This is the address of the Citrix server you’re connecting to
  • Application
    The published application to connect to (if this is left empty, the ICA client will connect to the server’s desktop)
  • Username
    The user under which you want to connect
  • Domain
    The domain for the user
  • Launch
    This property tells the ICO SDK to launch a new session, this is a boolean (true or false) property
  • OutputMode
    The way that the actual ICA Client is displayed on screen

Note that I left out the Password property. This is because there is no “real” password property to be set which defines the password to be used. I will discuss this later on.

The following commands will set these properties:

$ICA.Address = "XASRV001"
$ICA.Application = "" # Connect to the server desktop
$ICA.Username = "TestUser01"
$ICA.Domain = "LAB"
$ICA.Launch = $true
$ICA.OutputMode = [WFICALib.OutputMode]::OutputModeNormal
# Valid OutputModes: OutputModeNonHeadless, OutputModeNormal, OutputModeRenderless, OutputModeRenderless

Setting the password for the ICA connection can’t be done through a property, instead you will have to use the SetProp() method:

$ICA.SetProp("Password","MyUsersPassword")

Ok, now that all properties have been set, we can make the connection to the defined server. This can be done by using the Connect() method:

$ICA.Connect()

This should start the ICA client on your machine and connect to the server. Note that after you enter the command, it could take a few seconds before the ICA connection pops up. If no ICA connection is shown, verify that the OutputMode is set to OutputModeNormal and that the Launch property is set to true.

In a default XenApp installation, the server desktop is not enabled by default, so you could receive the following error:

This can easily be solved by setting a Citrix User Policy. Define a policy in your AppCenter and set a user policy: ICA > Desktop Launches > Set to Allowed.

To sum up the complete script:

[System.Reflection.Assembly]::LoadFile("C:\Program Files (x86)\Citrix\ICA Client\WfIcaLib.dll")
$ICA = New-Object WFICALib.ICAClientClass
$ICA.Address = "XASRV001"
$ICA.Application = ""
$ICA.Username = "TestUser01"
$ICA.SetProp("Password","MyUsersPassword")
$ICA.Domain = "LAB"
$ICA.Launch = $true
$ICA.OutputMode = [WFICALib.OutputMode]::OutputModeNormal
$ICA.Connect()

Easy as that. Hope you found this post usefull and this helps you writing scripts using the ICO SDK. In my next post, I’ll talk about ways to change the session behaviour and appearance.

29 thoughts to “ICA connections using Powershell – Part 1”

  1. Hi
    I do this as your write. But when I connect, it always tell me that your application is unavailable . I don’t know if you do something on the XenDesktop Server. Please tell me what your configuration on the XenDesktop Server to solve my problem .
    thanks

    1. Hi James,

      for XenDesktop connections, you can’t use direct ICO. It will only work with XenApp servers. This is because the published desktop name in XenDesktop environments is based on the VM name (this requires some communication between the Citrix Web Interface and the XenDesktop DDC).

      For this you could use Citrix StoreFront; it has an API which allows you to get an ICA file from the StoreFront server (but I don’t know the general availability of the API documentation). If the documentation is public, I can do another series on the StoreFront API.

      regards,
      Floris

  2. Newbie question – is there anyway in powershell to check ica connections of remote computers? we have some apps that need to always be on, I would like to do spot check using powershell to see if the ica connections have been disconnected?

    Thanks for any tips.

    1. Hi Fred,

      that’s not possible using the method I’m describing in this article; the ICA Client Object is only available for the LOCAL ICA Client (/Receiver). Maybe it could be possible using PowerShell remoting, but my advice would be to use something like WMI queries to the Citrix Farm (if you’re using XenApp) and check the status of the specific session. If it’s disconnected or not available, you know there’s a problem. If you want I can help you out with such a script.

      kind regards,
      Floris

      1. Thank you so much for the quick reply. Unfortunately I don’t have access to the Citrix farm. Was hoping to be able to query the local PC, but just don’t know enough about Citrix and what’s available via Powershell.

  3. Hi, thanks for the great article, i am testing this in our Citrix enviroment but now when i run the script nothing happens, no citrix pops up and no msgbox pops up…

    The only message i get is from the DLL

    GAC Version Location
    — ——- ——–
    False v2.0.50727 C:\Program Files (x86)\Citrix\ICA Client\WfIcaLib.dll

    And then it stops and nothing more happens :S

    1. Hi Bjorn,

      Thanks for the feedback.

      Can you give me some more information about your issue?
      – Does the script return to the PowerShell prompt?
      – Did you try to run the script line-by-line?
      – Did you start PowerShell in x86 mode? (important!)

      kind regards,
      Floris

      1. Hi
        I have same problem. I use powershell ICO SDK to monitor my citrix servers and from time to time. The script fails to launch anything. There is no error message other than the timeout of 180 seconds we setup. There is no issue with script or server a I am able to connect with script on a different PC.

  4. Hi Floris,
    I know this post is 2 years old. I hope you are still around.
    I ran your script line by line, entered my Citrix gateway IP address instead of the Xenapp server and entered the published application name but I got this error;
    Citrix Receiver
    Unable to launch your application. Contact your help desk with the following information. Cannot connect to the Citrix XenApp server.Protocol Driver error.

    Do you think this script can communicate with the Citrix gateway?

    Thanks.
    Sosu

    1. Hi Sosu,

      when you’re talking about Citrix Gateway, dus you mean like Access Gateway/Netscaler? The script will not work with Netscaler (it will try to connect directly to either the XML port or the ICA port).

      What does your Citrix environment look like?

      kind regards,
      Floris

    2. I was able to fix this problem by setting $ICA.SSLEnable = $false;

      But I still have another problem. When I try to connect I get an OnConnecting and then an OnConnect event, but just after that OnDisconnect is called. (No errors, also nothing in the log)

      The only way I got this to work is by downloading an ica file from the Citrix website and then load this file directly with: $ICA.ICAFile = “myfile”;

      Is this maybe a security setting of this Citrix server and if so, is there any way (webservice etc) to get an ica file from .Net?

    3. With this script add the below mentioned line, it will help solve the issue

      $ICA.HttpBrowserAddress = “xxxx” # mention ur xml broker name in it

  5. Hi Floris,

    I have a requirement where we need to launch internet explorer application from the citrix URL and open a new website in the explorer and login to it.

    Could you please let me know whether using this ICA client approach can we handle the internet explorer application launched from citrix.

    Could you please share a sample code to enter a username and password into the launched internet explorer from citrix pprogramatically

  6. Hi All,

    I tried to create ICA client object and below is the error is seeing.

    “Retrieving the COM class factory for component with CLSID {238F6F83-B8B4-11CF-8771-00A024541EE3} failed due to the following error: 80040154” error is coming

    Can someone please help me sort out this issue.

    1. You are probably using a 64 bit Windows version. In that case you’ll have to use a x86 powershell prompt. The wficalib.dll is a 32 bit dll, and can’t be loaded from a 64 bit program.

  7. Hi Floris,

    Help of your script I have created the below mentioned script . And this script is working fine if you run the script directly on the server.
    But when I scheduled it through scheduled task . it is not working.

    Can you please help me to solve it.

    ===========================
    # E-mail reporting details. Based on the below details, the report will be emailed.
    $emailFrom = “xxxx”
    $emailTo = “xxxx”
    $emailCC = “xxxx” # If no address to send CC leave the value as null
    $smtpServer = “xxxx”
    $emailSubject = “FMOxx Application Availablity Check- Testing”
    $emailbody=”Hi Team,Unable to launch FMO xx application -testing. Please verify the ICE Citrix Servers”

    if ((Get-PSSnapin “Citrix.*” -EA silentlycontinue) -eq $null) {
    try { Add-PSSnapin Citrix.* -ErrorAction Stop

    set-XADefaultComputerName SM06226

    }
    catch { write-error “Error loading XenApp Powershell snapin”; Return } }

    $workgrp_ser_list= get-xaworkergroup -WorkerGroupName ICE_EN_Nottingham

    foreach( $w_servers in $workgrp_ser_list.servernames)

    {

    write-host $w_servers

    }

    set-content “D:\BEstShore\HEalthCheck\Silo_Monitoring\ICE_application_report.txt” $null

    [Reflection.Assembly]::LoadFile(“C:\Program Files (x86)\Citrix\ICA Client\WfIcaLib.dll”)
    $ICA = New-Object WFICALib.ICAClientClass
    $ICA.HttpBrowserAddress = “sm06226”
    $ICA.Application = “#FMO_ICE_silo_Monitoring”
    $ICA.Launch = $true
    $ICA.OutputMode = [WFICALib.OutputMode]::OutputModeNormal
    $ICA.DesiredHRes = 1024
    $ICA.DesiredVRes = 768
    $ICA.DesiredColor = [WFICALib.ICAColorDepth]::Color16bit
    $ICA.TWIMode = $true
    $ica.Encrypt=$true

    #$ICA.Username = “xxx”
    #$ICA.SetProp(“Password”,”xx”)
    #$ICA.Domain = “u-xxx”
    $ica.EncryptionLevelSession= “EncRC5-128″
    #Register-ObjectEvent -InputObject $ICA -EventName OnLogon -SourceIdentifier ICA_OnLogon
    $ICA.Connect()

    Start-Sleep -s 30

    $ICA_result=””
    $Failed_servers=$null
    $w_servers=$null
    $workgrp_ser_list=$null
    if($ica.connected -eq $true)
    {

    #write-host “true”
    $ICA_result=”True”

    $ICA.disConnect()

    }
    else
    {

    #write-host “false”
    $ICA_result=”False”

    #get-xaworkergroup -WorkerGroupName ICE_EN_Nottingham

    $workgrp_ser_list= get-xaworkergroup -WorkerGroupName ICE_EN_Nottingham

    foreach( $w_servers in $workgrp_ser_list.servernames)

    {

    $ICA.Address = $w_servers
    $ICA.Connect()

    Start-Sleep -s 20

    if($ica.connected -eq $true)
    {

    #write-host “true”
    $ICA.disConnect()

    }
    else
    {

    # write-host “false”
    $ICA.disConnect()

    $Failed_servers= $w_servers + “;” + $Failed_servers
    }

    }

    $emailbody=”Hi Team,Unable to launch FMO ICE application -testing. Please verify the ICA connection failed Citrix Servers :” + $Failed_servers

    Add-content “D:\BEstShore\HEalthCheck\Silo_Monitoring\ICE_application_report.txt” $emailbody

    send-mailmessage -from $emailFrom -to $emailTo -subject $emailSubject -body $emailbody -priority High -dno onSuccess, onFailure -smtpServer $smtpServer

    }
    $ICA.disConnect()

    #set-content “D:\BEstShore\HEalthCheck\Silo_Monitoring\ICE_application_report.txt” $null
    #Add-content “D:\BEstShore\HEalthCheck\Silo_Monitoring\ICE_application_report.txt” $ICA_result

    ========================

    1. Hi Feroz,

      if the script works when you manually launch it, it could be that the ICA Client Object needs an interactive session (logged on user) to be able to work. I can imagine that it does, since it creates a new window, etc. If you use this script from a server, you could try to connect over RDP and just disconnect the session. You can then modify the scheduled task to run under the logged on user context (and enabled the “run only when logged on” checkbox).

  8. Hi Floris,

    When I try and use your initial powershell code to launch an Published Application from a XenDesktop 7.6 SeverOS Delivery group, I get, the error

    Cannot Connect to the Citrix XenApp Server: Protocol driver error

    I would like to Launch a publicshed app programmatically that I get then provide a link to on the Recever for Web Storefront logon page.

    This would ideally launch a specific application with certain credentials – (Published IE in KIOSK mode pointing at a SelfService Help Website – e.g reset password, unblock PIN etc)

    The client is a non-domain joined Thin Client thats why I want to give users the chance to launch a Published app (using a generic account) to access the self service webpage on a XenDesktop Apps server.

    Anonymous is not an option as I need to start the published app with domain creds.

    Any ideas as to why getting the protocol driver error when launching a published app in the way you recommend.

  9. Just wanted to say thank you. Beautifully done. My goal is to have a script located in a network location to be executed within Citrix I’ve opened my Citrix Windows Explorer session. Using your guide, I’ve got Receiver loaded up, logged in, and a Windows Explorer session started, but I’m now stuck at how to navigate to a network location. Any ideas? Does the SDK support this?

    1. Hi Gregory,

      What could work, is sending a enter key down on connection (but I never tried it). You could leverage the simulation API for that as described here:

  10. Hi Floris,

    Thank you for the script . I am getting the following error when I try to execute the same .

    ‘There is no Citrix XenAppServer configured at the specified address.[Socket error 100060])

    I am passing the XenApp server’s IP in the address field .

    What could be the issue

  11. I have modified the script to prompt for a username and mask the password.
    #Will.Huerto
    #Sources:
    #http://www.florisvanderploeg.com/ica-connections-using-powershell-part-1/#more-104
    #https://blogs.technet.microsoft.com/heyscriptingguy/2010/08/11/masking-passwords-in-windows-powershell/
    #http://sqlblog.com/blogs/jamie_thomson/archive/2014/04/24/prompt-for-a-password-with-a-mask-using-powershell.aspx

    [System.Reflection.Assembly]::LoadFile(“C:\Program Files (x86)\Citrix\ICA Client\WfIcaLib.dll”)

    $Adress = read-host “=======> Please Enter The Server Name”
    $username = read-host “=======> Please Enter Your UserName”

    $response = Read-host “What’s your password?” -AsSecureString
    $password = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($response))

    $ICA = New-Object WFICALib.ICAClientClass
    $ICA.Address = $Adress
    $ICA.Application = “”
    $ICA.Username = “$username”
    $ICA.Domain = “TJU-MST”
    $ICA.Launch = $true
    $ICA.OutputMode = [WFICALib.OutputMode]::OutputModeNormal
    $ICA.SetProp(“Password”,”$Password”)
    $ICA.Connect()

  12. I’m having the same issue and cannot get past the protocol driver error. My use case is to have this connect to the Citrix controller and launch a published application with the given credentials. The only way I can get this to work at all is if I use $ICA.Address=”” and blank out the application so it launches the desktop. I can’t get a published application to work. I know this is an old thread but hoping someone might have some ideas.

Leave a Reply

Your email address will not be published. Required fields are marked *

Complete the following sum: * Time limit is exhausted. Please reload CAPTCHA.

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