PowerShell Basics for Citrix admins

945e5c3ef6a52d8d7394b10a99e26277?s=47 Guy Leech
August 12, 2020

PowerShell Basics for Citrix admins

The why, how and what of using PowerShell to help administer and support Citrix Virtual Apps and Desktops.


Guy Leech

August 12, 2020



  2. WHY YOU SHOULD USE/LEARN POWERSHELL? • Can be easier/quicker than

    using consoles from (multiple) vendors • Bulk/repeated operations • Scheduled tasks to report/fix • Easy to import/export to csv/xml/json and send emails • Can use interactively or via scripts • Tab completion of commands, arguments, parameters • Intuitive/consistent – it’s a shell *AND* a scripting language • Huge number of scripts and learning resources out there • But check untrusted scripts before running them as admin on production systems! • Cross Platform • Fame, fortune, ….
  3. COMMON PITFALLS/BARRIERS • PowerShell execution policies • Leave them as

    you found them • Set-ExecutionPolicy –Scope Process • Old version • #Requires -version • $PSVersionTable • Avoid 2.0 – upgrade/install Windows Management Framework • Spaces in script names • Relative paths • Not running elevated or under an account with sufficient permissions • Parameters – missing mandatory ones • Not reading error text • Script readability • Putting everything on a single line • But assigning everything first can slow scripts down & increase memory usage (pipe through ForEach-Object)
  4. WHAT’S AVAILABLE TO USE? • What’s installed? • Install consoles,

    RSAT, VMware PowerCLI, SDKs, etc. on a dedicated management machine • Get-PSSnapin –Registered (gsnp) • Add-PSSnapin (asnp) • Get-Module –ListAvailable (gmo) • Import-Module (ipmo) • Get-Command –Module (gcm) • -verb • -name ‘*blah*’ • Get-Help • -showwindow • -online • RTFM
  5. USING CVAD POWERSHELL CMDLETS • Do not run on user

    facing infrastructure servers like Delivery Controllers, PVS (unless need to manipulate local store) • -AdminAddress (on every call – consider splatting) • -MaxRecordCount • Cloud – create credential profile via downloaded secrets csv file

    oriented SDK around 7.8 • Prior to that was MCLI.exe and text results ☹ • Do not use PvsPsSnapIn snapin as only has 11 cmdlets • Import-Module "$env:ProgramFiles\Citrix\Provisioning Services Console\Citrix.PVS.SnapIn.dll" • 178 cmdlets • Do not run on PVS server unless need to manipulate local store
  7. SOME CITRIX CVAD CMDLETS • Get-Broker* (118 cmdlets (1912 LTSR))

    • Get-BrokerMachine • Get-BrokerSession • Stop-BrokerSession • Set-BrokerMachine -InMaintenanceMode • Get-PVS* (63 cmdlets (1912 LTSR)) • Get-PVSSite • Get-PVSDeviceInfo • Get-PVSDiskInfo
  8. SOME USAGE SCENARIOS • Email daily checks • Maintenance mode/registration

    state/power state per delivery group/tag • Overdue reboot • High PVS retries • High user load • Low disk space • Remediation • Etc, etc • Check spoolers and shared printers • Consume “Director” data (via OData/REST) • Ghost sessions • … and whatever else you do repetitively

    properties and methods are available by piping to Get-Member (gm) • Assign result to variable or pipe through “Select –First 1” • Filter on some properties • Where-Object { $_.something –eq ‘interesting’ –and $_.somethingelse –ne 42 } • Check if cmdlet itself can filter as filtering as far left as possible is best for speed & efficiency • Pipe to Export-CSV • Pipe to Out-GridView • Pipe to other cmdlets • Get-ChildItem \blah | Where LastWriteTime -lt (Get-Date).AddDays(-120) | Remove-Item • Email via Send-MailMessage • SMTP but can use Invoke-Command to proxy mail off another machine if relaying restricted
  10. GENERAL POWERSHELL USAGE TIPS • Don’t sit in system folders

    like system32 in case you create/delete files • cd $env:userprofile • Can put in profile $env:userprofile\Documents\WindowsPowerShell\profile.ps1 • [console]::Title = ‘Server XXX’ • [console]::ForegroundColor = ‘Cyan’ • Use different colours for different users, systems, etc. • Sit in PowerShell.exe all day, not cmd.exe, so you get used to it • Set-StrictMode –version Latest • $PSVersionTable • $pid • Get-Alias • But do not use aliases in scripts as makes difficult to understand
  11. HOW TO RUN SCRIPTS - #1 • Understand execution policies

    and leave them as you found them • Get-ExecutionPolicy / Set-ExecutionPolicy • Double click explorer action should be left as edit for safety • Explorer right click “Run with PowerShell” should be avoided • Invoked window will close when finished so you can’t see errors/results • Cannot pass non-mandatory parameters • Like Unix/Linux shells, script must be in $env:Path or specify full or relative path (.\) • Must put single or double quotes around any script/argument which has spaces in the name and prefix with & • Without out & it will just echo the script name back to you – “hello world” • Double quotes causes PowerShell to evaluate $ variables, etc.
  12. HOW TO RUN SCRIPTS - #2 • Scripts will prompt

    for missing mandatory arguments • Use tab completion after typing – after the script name to cycle through available parameters • And when typed first few characters of option, e.g. –verb, although can leave as shortened form if not ambiguous • Be aware of any version restrictions e.g. #Requires lines • Run with –WhatIf if the script can be destructive • Although developer can choose to ignore
  13. SCRIPT PARAMETERS • Found in a Param block in the

    PowerShell script • [CmdletBinding] also means can use common options like –Verbose, -WhatIf, -Confirm, etc. • But script writer still has to wire them up • Script can have named parameter sets to try & stop people using wrong combinations of options • Parameter validation can be coded so only certain things allowed, e.g. –ErrorAction • Parameters can be dynamically presented, e.g. Get-Process –Name • Parameters may take patterns or regular expressions (regex) • Passing some options in via cmd or Scheduled tasks can cause problems • $true/$false • Arrays
  14. GETTING HELP • In ISE hit F1 but may need

    to update help • Run Get-Help <scriptname> • Level of info will depend if author has put in correctly formatted help system comments • Run the script with -? • Look at the script! • Web search • Ask the audience
  15. DEBUGGING • May support –verbose / -debug so try them

    • Load into ISE and set breakpoints via F9 • Can examine variables when breakpoint hit • Add Write-Output/Write-Verbose/Write-Debug lines where you need them • Keep an unadulterated copy of the script in case you break it! • Be careful, particularly if running as an admin on a production system
  16. ERRORS AND EXCEPTIONS • Errors are in red by default

    • Read and digest the error message! • Does it need to run elevated or on a specific machine where cmdlets, etc. are available? • They may be terminating or script may carry on – depends on how script written & type of error • Look at the line number referenced, put a breakpoint in and examine variables • -ErrorAction / -EA but do not turn off error reporting • Try/Catch blocks catch thrown exceptions & may not output any messages (could be expected error) • Capture to file/screenshot • Web search
  17. SCHEDULED TASKS • Very easy to create a scheduled task

    that runs a PowerShell script • Create task folder to keep all custom tasks in one place • Write a log file • Start-Transcript / Stop-Transcript • Can get problems with embedded strings, $true/$false and arrays • Execution Policies • Powershell.exe –executionpolicy bypass • Test command line via cmd.exe • Does it need a dedicated service account? Practise LUA!
  18. USING CSV FILES • Export-CSV takes objects and writes to

    csv format file so can sort, filter, etc. in Excel • Run a cmdlet and pipe through Export-CSV and voila you have captured that information to file • Get-BrokerMachine | Export-CSV –Path xenapp7.machines.csv -NoTypeInformation • Specify –NoTypeInformation and –NoClobber • Can also show on screen in a grid view by piping to Out-GridView instead of Export-CSV • E.g. if Excel not available • Import-CSV existing.info.csv | Out-GridView • Can import from a CSV directly into a variable and then process it – each column will be a . value • $data = Import-CSV existing.info.csv
  19. WRITING POWERSHELL SCRIPTS • Start by understanding and then modifying

    other people’s scripts • Don’t be frightened but do be careful • Don’t logon, let alone run scripts as an admin, unless you really have to • Use [CmdletBinding(SupportsShouldProcess=$true,ConfirmImpact='High')] and $PSCmdLet.ShouldProcess() • Don’t run on live systems where possible • Single step/set breakpoints before destructive actions • Sanity check parameters passed – don’t assume everyone will understand your parameters • If at first you don’t succeed, try, try again • Bite size chunks – plan version features/contents • Don’t hardcode – use parameters or variables • ISE is your friend, make use of breakpoints (some say Visual Studio Code is better) • Don’t copy and paste chunks of code – put it in a reusable Function • Use Write-Verbose or Write-Debug for status/debug messages, not Write-Host as can't be redirected • Neglect error checking and handling at your peril!
  20. PARTING THOUGHTS …. • Even if you can’t write a

    script from scratch, know how to figure out roughly what it does & is safe to run • Someone has probably written some of what you want already – search, find and plagiarise/improve (even I do but credit the originator!) • Don’t brag about not being able to write scripts – it’s not big or clever and limits/slows you • Don't worry about style, performance, etc to start with – the main thing is to solve the problem • Scripting can be an art form and can be therapeutic, yes really • What tools still need writing to help you become more efficient? • Writing stuff is, relatively speaking, easy but having the ideas is the difficult bit (and what to call it!) • If you find/write something useful, share it
  21. THAT’S ALL FOLKS • Exit 0