Wens
Gebruikers met slecht zicht hadden de wens om de schermresolutie te kunnen wijzigen. Het lettertype en de pictogrammen vergroten was niet voldoende voor deze gebruikers. Daar mocht ik een oplossing voor bedenken (Bij het gebrek aan Citrix HDX en RES VDX licenties).
Architectuur
- Res Workspace Manager (Geen VDX licentie)
- Windows ThinPC
- Citrix XenDesktop (Geen HDX licentie)
- Microsoft Active Directory
- Imprivata OneSign
Probleemanalyse
Als een werkstation binnen ons bedrijf met Windows ThinPC opstart dan verschijnt het Imprivata aanmeldscherm (vervanger standaard Windows gina). Dit scherm bied geen mogelijkheden om de resolutie te wijzigen.
Na het aanmelden wordt de gebruiker door Imprivata via een SSO policy direct naar de Citrix XenDesktop VDI doorgestuurd. Imprivata vraagt via een API direct een .ICA file op bij de Citrix StoreFront server (Het bestand waar de user credentials en connection informatie in staat). Hoe dit exact werkt is echter onduidelijk. In de logs die Imprivata genereert is er wel wat over terug te vinden maar niet genoeg om de exacte werking te kunnen achterhalen. Het is ook niet mogelijk om zelf een “standaard” ICA file te bouwen aangezien deze telkens anders is (bevat onder andere het IP-adres van de VDI).
Het is mogelijk om na het aanmelden scripts uit te laten voeren door het Imprivata Procedure Code Extension Object. Zo had ik een resolutiekeuze scherm geprogrammeerd welke dan getoond werd na het inloggen. Het was echter niet mogelijk om na het tonen van dit scherm via SSO direct door te loggen naar Citrix. Het was wel mogelijk om de Citrix Storefront site aan te roepen maar dan zou de gebruiker twee maal in moeten loggen en dat was niet wenselijk.
Volgens onze leverancier lag er wel een RFC bij Imprivata om een resolution change via het login scherm mogelijk te maken. Het was echter niet duidelijk of hier überhaupt iets mee gedaan zou worden en wanneer het dan uitgegeven zou worden. Dan maar iets anders bedenken…
Vervolgens eens gaan knutselen om het vanuit de VDI aan te kunnen passen. Daarbij dacht ik aan de tool psexec (tool van Microsoft om remote applicaties te starten op een computer) in combinatie met een command line tool om de resolutie te wijzigen.
Uitdagingen:
- Hoe weet ik vanuit de VDI wat de hostname/IP is van het lokale werkstation?
- Heb beperkte rechten als standaard gebruiker. Hoe kan ik dan toch via psexec commando’s uitvoeren op andere werkstations?
- Hoe gaat Citrix om met een plotselinge resolutie wijziging (resizen sessie)
- Credentials van een account met local admin rechten plain in een script verwerken welke is uit te lezen door de gebruiker was niet wenselijk i.v.m. security.
Oplossing
Uiteindelijk na veel geknutsel heb ik met de onderstaande tools een stabiele oplossing kunnen realiseren:
- PsExec
- PsKill
- cpau
- nircmd
- PowerShell
PsExec werkt alleen in een dos-prompt of powershell window met administrative privileges (Anders wordt de connectie niet geaccepteerd door de computer waar verbinding mee gemaakt word, zelfs niet als je de juiste credentials meegeeft. Het was mogelijk om via RES Workspace Manager een programma aan te maken met admin rechten. De rechten die dan gezet werden door RES waren echter niet genoeg voor PsExec. Om de shell met Runas uit te voeren was helaas ook geen optie (geen mogelijheid om een wachtwoord mee te geven). Uiteindelijk de tool “cpau” gevonden waarmee het mogelijk is om een encrypted file te maken met daarin de logon credentials en het programma wat uitgevoerd dient te worden. Daarmee kon ik PowerShell opstarten met de juiste privileges voor psexec.
Vervolgens moest ik vanuit VDI op een of andere manier achterhalen wat de hostnaam van het eindstation was. Dit wordt door Citrix zowel in het register als in de Windows variabelen weggeschreven:
%clientname%
%clientipaddress%
HKLM:\SOFTWARE\Citrix\Ica\Session\ClientName
Na vastgesteld te hebben waar het eindstation zich bevond moest ik daar een script af kunnen trappen om de resolutiewijziging te doen. Eerst had ik de tool qres gevonden. Dat werkt goed voor één enkele monitor maar als er twee schermen zijn aangesloten op een eindstation dan kon ik enkel de resolutie aanpassen van de primaire monitor. Na wat zoeken kwam ik uit bij nircmd. Deze command line tool was wel in staat om voor beide monitoren de resolutie te wijzigen.
Na het wijzigen van de resolutie kwam het echter voor dat de Citrix sessie windows niet goed resized. Door 2x op SHIFT+F2 te drukken was dit weer hersteld maar dat kon ik de gebruiker niet aandoen. Via VBS, PowerShell en AutoIt verschillende oplossingen geprobeerd om met “SendKeys” commando’s deze SHIFT+F2 aan te roepen echter zonder success. Het aanroepen van deze toetsencombinatie ging op zowel de VDI als op het eindstation niet goed. Dit uiteindelijk opgelost door de Citrix sessie te disconnecten door het Citrix receiver process (wfica32.exe) te killen op het eindstation. Daardoor moet de gebruiker echter wel weer opnieuw aanmelden (helaas). Als er iemand is die hier een betere oplossing voor heeft gevonden hoor ik het graag.
Uiteindelijk alle benodigde bestanden in een MSI verwerkt welke de bestanden in C:\Windows\ResChange zet. Deze MSI gedistribueerd naar zowel de VDI als de eindstations.
Bestanden
Cpau.exe
nircmd.exe
psexec.exe
pskill.exe
res-800-600.login
res-800-600.ps1
res-1024-768.login
res-1024-768.ps1
res-1280-1024.login
res-1280-1024.ps1
res-1920-1080.login
res-1920-1080.ps1
Windows Firewall
Als PsExec niet of traag verbind naar het Windows eindstation dan zijn er enkele rules die toegevoegd moeten worden:
Remote Service Management (RPC) (RPC Dynamic Ports)
Poort 139
Code
RES Workspace Manager shortcut:
C:\Windows\ResChange\cpau.exe C:\Windows\ResChange\res-1024-768.login
Genereren van een encrypted login file die powershell opstart met het juiste script (1 file per resolutie):
CPAU.exe -u [username] -p [password] -enc -file res-1920-1080.login -ex "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe C:\Windows\ResChange\res-1920-1080.ps1"
Powershell Script (Het is mogelijk om de output van de commando’s te onderdrukken zodat deze niet getoont wordt aan de gebruiker. Dit heb ik niet opgenomen in dit voorbeeld).
# Resolution change script
# Written by Bas van Hemmen | e-mail: bas@van-hemmen.nl
#
# Read Citrix session information (Windows register)
$key_citrix = 'HKLM:\SOFTWARE\Citrix\Ica\Session'
$client = (Get-ItemProperty -Path $key_citrix -Name ClientName).ClientName
#Write message to screen
Write-Host ''
Write-Host 'Bezig met het aanpassen van de schermresolutie...'
Write-Host ''
# Set working dir
Set-Location "C:\Windows\ResChange\"
#Execute psexec and pskill commands
.\psexec.exe -accepteula \\$client -i "C:\Windows\ResChange\nircmd.exe" setdisplay monitor:0 800 600 32
.\psexec.exe -accepteula \\$client -i "C:\Windows\ResChange\nircmd.exe" setdisplay monitor:1 800 600 32
.\pskill.exe -accepteula \\$client -t wfica32.exe
Vragen, opmerkingen, tips zijn altijd welkom
Gebruikers met slecht zicht hadden de wens om de schermresolutie te kunnen wijzigen. Het lettertype en de pictogrammen vergroten was niet voldoende voor deze gebruikers. Daar mocht ik een oplossing voor bedenken (Bij het gebrek aan Citrix HDX en RES VDX licenties).

Architectuur
- Res Workspace Manager (Geen VDX licentie)
- Windows ThinPC
- Citrix XenDesktop (Geen HDX licentie)
- Microsoft Active Directory
- Imprivata OneSign
Probleemanalyse
Als een werkstation binnen ons bedrijf met Windows ThinPC opstart dan verschijnt het Imprivata aanmeldscherm (vervanger standaard Windows gina). Dit scherm bied geen mogelijkheden om de resolutie te wijzigen.
Na het aanmelden wordt de gebruiker door Imprivata via een SSO policy direct naar de Citrix XenDesktop VDI doorgestuurd. Imprivata vraagt via een API direct een .ICA file op bij de Citrix StoreFront server (Het bestand waar de user credentials en connection informatie in staat). Hoe dit exact werkt is echter onduidelijk. In de logs die Imprivata genereert is er wel wat over terug te vinden maar niet genoeg om de exacte werking te kunnen achterhalen. Het is ook niet mogelijk om zelf een “standaard” ICA file te bouwen aangezien deze telkens anders is (bevat onder andere het IP-adres van de VDI).
Het is mogelijk om na het aanmelden scripts uit te laten voeren door het Imprivata Procedure Code Extension Object. Zo had ik een resolutiekeuze scherm geprogrammeerd welke dan getoond werd na het inloggen. Het was echter niet mogelijk om na het tonen van dit scherm via SSO direct door te loggen naar Citrix. Het was wel mogelijk om de Citrix Storefront site aan te roepen maar dan zou de gebruiker twee maal in moeten loggen en dat was niet wenselijk.
Volgens onze leverancier lag er wel een RFC bij Imprivata om een resolution change via het login scherm mogelijk te maken. Het was echter niet duidelijk of hier überhaupt iets mee gedaan zou worden en wanneer het dan uitgegeven zou worden. Dan maar iets anders bedenken…
Vervolgens eens gaan knutselen om het vanuit de VDI aan te kunnen passen. Daarbij dacht ik aan de tool psexec (tool van Microsoft om remote applicaties te starten op een computer) in combinatie met een command line tool om de resolutie te wijzigen.
Uitdagingen:
- Hoe weet ik vanuit de VDI wat de hostname/IP is van het lokale werkstation?
- Heb beperkte rechten als standaard gebruiker. Hoe kan ik dan toch via psexec commando’s uitvoeren op andere werkstations?
- Hoe gaat Citrix om met een plotselinge resolutie wijziging (resizen sessie)
- Credentials van een account met local admin rechten plain in een script verwerken welke is uit te lezen door de gebruiker was niet wenselijk i.v.m. security.
Oplossing
Uiteindelijk na veel geknutsel heb ik met de onderstaande tools een stabiele oplossing kunnen realiseren:
- PsExec
- PsKill
- cpau
- nircmd
- PowerShell
PsExec werkt alleen in een dos-prompt of powershell window met administrative privileges (Anders wordt de connectie niet geaccepteerd door de computer waar verbinding mee gemaakt word, zelfs niet als je de juiste credentials meegeeft. Het was mogelijk om via RES Workspace Manager een programma aan te maken met admin rechten. De rechten die dan gezet werden door RES waren echter niet genoeg voor PsExec. Om de shell met Runas uit te voeren was helaas ook geen optie (geen mogelijheid om een wachtwoord mee te geven). Uiteindelijk de tool “cpau” gevonden waarmee het mogelijk is om een encrypted file te maken met daarin de logon credentials en het programma wat uitgevoerd dient te worden. Daarmee kon ik PowerShell opstarten met de juiste privileges voor psexec.
Vervolgens moest ik vanuit VDI op een of andere manier achterhalen wat de hostnaam van het eindstation was. Dit wordt door Citrix zowel in het register als in de Windows variabelen weggeschreven:
%clientname%
%clientipaddress%
HKLM:\SOFTWARE\Citrix\Ica\Session\ClientName
Na vastgesteld te hebben waar het eindstation zich bevond moest ik daar een script af kunnen trappen om de resolutiewijziging te doen. Eerst had ik de tool qres gevonden. Dat werkt goed voor één enkele monitor maar als er twee schermen zijn aangesloten op een eindstation dan kon ik enkel de resolutie aanpassen van de primaire monitor. Na wat zoeken kwam ik uit bij nircmd. Deze command line tool was wel in staat om voor beide monitoren de resolutie te wijzigen.
Na het wijzigen van de resolutie kwam het echter voor dat de Citrix sessie windows niet goed resized. Door 2x op SHIFT+F2 te drukken was dit weer hersteld maar dat kon ik de gebruiker niet aandoen. Via VBS, PowerShell en AutoIt verschillende oplossingen geprobeerd om met “SendKeys” commando’s deze SHIFT+F2 aan te roepen echter zonder success. Het aanroepen van deze toetsencombinatie ging op zowel de VDI als op het eindstation niet goed. Dit uiteindelijk opgelost door de Citrix sessie te disconnecten door het Citrix receiver process (wfica32.exe) te killen op het eindstation. Daardoor moet de gebruiker echter wel weer opnieuw aanmelden (helaas). Als er iemand is die hier een betere oplossing voor heeft gevonden hoor ik het graag.
Uiteindelijk alle benodigde bestanden in een MSI verwerkt welke de bestanden in C:\Windows\ResChange zet. Deze MSI gedistribueerd naar zowel de VDI als de eindstations.
Bestanden
Cpau.exe
nircmd.exe
psexec.exe
pskill.exe
res-800-600.login
res-800-600.ps1
res-1024-768.login
res-1024-768.ps1
res-1280-1024.login
res-1280-1024.ps1
res-1920-1080.login
res-1920-1080.ps1
Windows Firewall
Als PsExec niet of traag verbind naar het Windows eindstation dan zijn er enkele rules die toegevoegd moeten worden:
Remote Service Management (RPC) (RPC Dynamic Ports)
Poort 139
Code
RES Workspace Manager shortcut:
C:\Windows\ResChange\cpau.exe C:\Windows\ResChange\res-1024-768.login
Genereren van een encrypted login file die powershell opstart met het juiste script (1 file per resolutie):
CPAU.exe -u [username] -p [password] -enc -file res-1920-1080.login -ex "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe C:\Windows\ResChange\res-1920-1080.ps1"
Powershell Script (Het is mogelijk om de output van de commando’s te onderdrukken zodat deze niet getoont wordt aan de gebruiker. Dit heb ik niet opgenomen in dit voorbeeld).
# Resolution change script
# Written by Bas van Hemmen | e-mail: bas@van-hemmen.nl
#
# Read Citrix session information (Windows register)
$key_citrix = 'HKLM:\SOFTWARE\Citrix\Ica\Session'
$client = (Get-ItemProperty -Path $key_citrix -Name ClientName).ClientName
#Write message to screen
Write-Host ''
Write-Host 'Bezig met het aanpassen van de schermresolutie...'
Write-Host ''
# Set working dir
Set-Location "C:\Windows\ResChange\"
#Execute psexec and pskill commands
.\psexec.exe -accepteula \\$client -i "C:\Windows\ResChange\nircmd.exe" setdisplay monitor:0 800 600 32
.\psexec.exe -accepteula \\$client -i "C:\Windows\ResChange\nircmd.exe" setdisplay monitor:1 800 600 32
.\pskill.exe -accepteula \\$client -t wfica32.exe
Vragen, opmerkingen, tips zijn altijd welkom