Application virtualization, IoT and Cloud Computing, Blog of Sacha Thomet

XenDesktop & XenApp FMA (7.x) HealthCheck – Oops!… I Did It Again

Some months ago I’ve created the Citrix PVS Health-Check Script which is a based on the idea and some parts of code from the Health-Check Script for XenApp 6.x of Jason Poyer ( .
Because now XenApp 7 with the Release 7.6 is finally in a state where considering an upgrade of the 6.x farms make sense, I belief that the demand for a XenApp 7.x Health Check Script grows.

So I did it again and took the “HealthCheck framework” to build a new version which combines the Power of the Citrix PS-Snappins for XenDesktop/XenApp and  the HTML-Output-Script of the existing HealthCheck Scripts.

The result is a new HealthCheck Script which is usable for XenApp and XenDesktop 7.x and what makes me also happy, with only a few line of more code the Script is downwardly compatible for XenDesktop 5.6 environments.

  XenDesktop XenApp Health Check HTML Output

This is just the first version and I’m sure that more check’s need to be added. Feedback and “Feature requests” are welcome … And to be honest I have not yet a big environment to test my Script, so please be insightfully if you find some bugs and report them to me.

In the first part of the Script you are able to configure some parameters. You can decide if you only want to see the “bad” Desktops on which something it’s going wrong or if you want see everything. In huge XenDesktop environments you want definitely only see the bad machines …  ( $ShowOnlyErrorVDI = 1 ) Also you can decide if you want only report XenApp or only XenDesktop or both. The Desktops and XenApps are in two different Tables. It’s also possible to exclude Collections ($ExcludeCatalogs) from the Check, so virtual Desktops which are for testing purposes are not checked.



If you have a feature request or a bug report please post it direct on GitHub.

Update 12.05.2016 (Version 0.95):
– Check CPU, Memory and C: of Controllers
– XenApp: Add values: CPU & Memory and Disk Usage
– XenApp: Option to toggle on/off to show Connected Users
– XenApp: DesktopFree set to N/A because not relevant
If you need a Health Check Script for XenApp Version which are older than XenApp 7.x see where it’s an excellent work and the inspiration for my HealthCheck-Scripts!

The code is on GitHub:

For Bug Reports or feature Request please use GitHub, of course you can also contribute on this code!

298 Responses to XenDesktop & XenApp FMA (7.x) HealthCheck – Oops!… I Did It Again

  • What’s your path were the Script is? It has maybe a blank inside?

    • I am running into an issue running this on a XenApp 7.12 environment. It will not gather the XenApp Server information or add it into the report even though the flag in the config file is set to 1.
      I am a full Xenapp and local administrator on all machines. Running powershell Ver4 Same failure if performed command line or via ISE

      Error 1

      At C:pscriptsFarmHealthReportXA-and-XD-HealthCheck.ps1:80 char:26
      + If ($CreateVariable) { New-Variable -Name $_.Name -Value $VarValue -Scope $_.S …
      + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      + CategoryInfo : WriteError: (ShowXenAppTable:String) [New-Variable], SessionStateUnauthorizedAccessExcep

      Error 2

      The variable ‘$ShowXenAppTable’ cannot be retrieved because it has not been set.
      At C:pscriptsFarmHealthReportXA-and-XD-HealthCheck.ps1:987 char:4
      + if($ShowXenAppTable -eq 1 ) {
      + ~~~~~~~~~~~~~~~~
      + CategoryInfo : InvalidOperation: (ShowXenAppTable:String) [], RuntimeException
      + FullyQualifiedErrorId : VariableIsUndefined

      Error 3

      The variable ‘$ShowXenAppTable’ cannot be retrieved because it has not been set.
      At C:pscriptsFarmHealthReportXA-and-XD-HealthCheck.ps1:1264 char:5
      + if ($ShowXenAppTable -eq 1 ) {
      + ~~~~~~~~~~~~~~~~
      + CategoryInfo : InvalidOperation: (ShowXenAppTable:String) [], RuntimeException
      + FullyQualifiedErrorId : VariableIsUndefined

      • does the XML exists at the right place? Are variables filled in the XML?

        • Yes the xml file exists in the same directory as the script and the flags are set

        • I was able to identify the source of the issue. I had an errant Unicode character in the xml file from when I was editing.

          • Great – sorry that I wasn’t a help. But happy that it works now.

        • 1 enhancement that would be highly beneficial would be a column for calculation of % of disk space free. Color coded with the parameters for Alert and Critical in the configuration file.

      • Hi,
        I have both environment with two different sites (XA7.12 & XD7.12). I have provided both delivery controllers XA&XD and also set the value 1 for XA and XD table , but it is giving the information for one site only either XA or XD. I am looking for single consolidated report as shown above, Can you please help me to fix this. Enclosing the parameters below which I have provided in xml file. Thanks a lot.




        • This script is intended to create consolidated reports, it should work fine. Please send me your XML to my address [email protected] the name you know from the blog 🙂

        • please try the fixed version 1.28 (please see that it’s also a update in the XML)

          • Hi Sacha,

            Some of the VDA vdisk is on E: and some on F:, how do I make the script to capture vDisk info other than D: drive?

            Many thanks,

          • that’s currently not possible with the Script, you can change it to E or F. But the script currenktly is intended to have only one unique letter for the write cache.

        • please try the fixed version 1.28 (please see that it’s also a update in the XML)

  • Awesome Sebastiaan, Thank’s – I’ve just uploaded your improved version!

  • Great script Sacha!

  • Hey Sacha!

    I do have one pretty important addition to the Health Check script!
    You should add one more column to the VDA list (and to the Assignment table) that shows Maintenance Mode Enabled!!

    I just had a major outage at one of my customers where even though hundreds of desktops were Registered and unused, nobody could launch desktops because all desktops automatically went into Maintenance mode ….. without anyone noticing .. 🙁


    • Hey Christoph,

      Nice to read a comment from you in my Blog.
      I have already the column in the XenApp part added by Sebastiaan Brozius. Thanks for the hint, I will also add a column in the VDA section and the Assignment table.

      Cheers, Sacha

      • I’ll take it on my list for FeatureRequests and try to implement it in a future version.

  • Hi Raj, I am Sacha 🙂 you don’t need an SDK, its just PowerShell. I work with notepad++ to developp my scripts.

  • Hey Sacha,
    I got it. Thanks!!

  • That’s possible. I will have a look on the next version of the Script. Thanks for your Input Luis!

  • It should run on the DDC, no idea why you get this error. Do you run it as admin? Has the user who run the script write access in this folder?

    Btw: Check also my PVS HealthCheck Script.

  • Thank you for the quick reply!

    I am running it on a DDC- I am running PS as admin and my creds are Domain Admin. I have local admin on all enterpris servers, as well.

    I have seen your PVS script as well- nice work :). I’ll be looking at that next-

    This is what I pasted into my file (less specifics). Does the formatting look alright to you?

  • Thank you, Sacha! I’ll give that a shot and let you know- thanks a ton!

  • Great Script – thank you

  • Awesome post and script.

  • Sacha, any reason for not seeing the Spooler and the CitrixPrint column?

    • Hi Rajen, under XenApp both should be visible, under XenDesktop those columns doesent exist.
      If it doesent work there is maybe a issue with the connection between the script runs and the destination (firewall), it’s a Get-Service request:

      ———– snap ————————————–

      # Check services
      $services = Get-Service -Computer $machineDNS

      if (($services | ? {$_.Name -eq “Spooler”}).Status -Match “Running”) {
      “SPOOLER service running…” | LogMe
      $tests.Spooler = “SUCCESS”,”Success”
      else {
      “SPOOLER service stopped” | LogMe -display -error
      $tests.Spooler = “ERROR”,”Error”

      if (($services | ? {$_.Name -eq “cpsvc”}).Status -Match “Running”) {
      “Citrix Print Manager service running…” | LogMe
      $tests.CitrixPrint = “SUCCESS”,”Success”
      else {
      “Citrix Print Manager service stopped” | LogMe -display -error
      $tests.CitrixPrint = “ERROR”,”Error”

      ———– snap ————————————–


  • Hi Sacha,

    Realy awesome script and job, for our 15 customers “Farms” i integrated in scom with scheduled tasks.

    The exclusion for machine catalogs not working for me in xendesktop 5.6/7.5 and 7.6, any idea? the log says nothing, just check catalag### (all)

    # Example: $ExcludedCatalogs = @(“Windows 7″,”Windows 8 Test”)

    $ExcludedCatalogs = @(“LevXDMASTER”,”LevXAMaster”,”LevXAMaster”)

    • Just checked, for me in 7.6 it still works fine. Be carefull it’s in the current version only possible to exclude MaschineCatalogs, not DeliveryGroups!

  • Could you explain “desktops free column”?

    The script is great but I do not understand the value of this field?

    #5th column, DesktopFree
    $AssigmentDesktopsFree = $AssigmentDesktopsAvailable – $AssigmentDesktopsInUse

    • If you have e.g. 50 pooled VDIs and there are 14 in use, you can see that you have 36 Free desktops. Guess this feature is only relevant for pooled desktops – maybe I need to filter out dedicated desktops in the next version.

      • Yes, good point. My XD Sites (3 separate data centers) are using dedicated desktops. Our XD sites are mixing Pooled PVS and Dedicated.

        • In the same delivery group??

          • Sorry typo
            XD Sites in 3 Data Centers with dedicated desktops in unique Catalogs and Delivery Groups.

            XA has 3 Data Centers with Unique Catalogs for Pooled and Others

      • Thank you for this script Sacha, it’s really useful. In my environment the script seems to not detect the shared XenApp desktops correctly, so the ‘DesktopsFree’ column in DeliveryGroup check is showing a negative number instead of ‘N/A (XenApp)’ as shown in your example. Any ideas why this would happen?


  • Check the Version 0.9 – I’ve made some corrections.

  • Hi Sacha,

    can you please suggest or modify the script and add the below command in script so it will give the unique user session

    get-brokersession -maxrecordcount xxxx | select-object -property username

    Appreciated the script it is awesome.

    • Hi Majeed Attar, thank you for your comment. Where do you mean, guess in XenApp section. But I don’t have this Get-BrokerSession code.

      I’m just doing:

      # Column ActiveSessions
      $ActiveSessions = $XAmachine | %{ $_.SessionCount }
      “Active Sessions: $ActiveSessions” | LogMe -display -progress
      $tests.ActiveSessions = “NEUTRAL”, $ActiveSessions

      • Hi Sacha,

        I know you do not have this Get-BrokerSession in Script…I want to add this in script so it will provide the user sessions, Can this be possible to add in scirpt

    • I just checked again your “FeatureRequest” but what acutal you want to get from Get-BrokerSession | Select-Object -Property UserName – you wish a list of all current connected users in XenApp and the one conencted user on XenDesktop? This is a very dynamic data and I’m not sure if I need to add this in a HealthCheck-Script because the logged-on user name is not impacting the health of a server. Or do I missunderstand your request?

      • We use xenapp and has published Desktop as if i run this command on Delivery controller it give me the output with user id and also shows if user has 2 session or not..

        We need that we are planning to run this script twice or thrice in a day…

        • I will have a look what I can do.

        • Majeed Attar I really want to help you and to fulfill your requirements, but currently it’s still a bit fuzzy what you need. Can you specify more exact your request. Do you wish to know the users of the single server or of the farm? What’s the intention for this information, do you want to know if you have an issue with session sharing? So I need only to output the dublicate sessions in a unique delivery group?

          Just to create a table with all logged on users will not be helpful in a health-check script. Consider that this script need to fulfill requirements of small and very large farms – so I need to have a usefull information at a glance even on a farm with 20’000 logged on users.

          • Hello Sacha,

            Thanks for the reply..

            Actually i need to get the current connected user of farm. so i can see how many of the user have duplicate session so it will easy for us to troubleshoot further as we are facing the issue that some random users are not able to connect on first attempt.. some time user has disconnected session and they try to connect but failed to do same..

          • Hi Majeed,

            I believe you should setup an OData API feed from Director. I don’t believe Sacha’s script is the place for this.


        • So a new table with this single information will be enough for you? No relation to a Server or Desktop?

          • yes.. that will be enough for now..and will be most appreciated.. 🙂

  • Hey Sacha,

    Thanks for the updated version – this script is just awesome!

    Not sure if this is a typo or I am reading it wrong

    Line 68: # Set to 1 if you want to Check a Environment with XenApp (5.x)

    I think that should read something like “Check Virtual Desktop”


  • I would love to see
    DiskFree C
    DiskFree D
    if a WMI request will result in an answer.

  • Hi Sacha, your Script is great as I have used it. To get more details of Xendesktop infrastructure, did you update this script in latest version? If yes, may I have that script?

    Thanks, Ravi

    • Sorry no newer Version currently – I have always the newest version online. But no alway time to create new versions.

  • aaaaaAAAAwsome script….

  • Sacha,
    Awesome script, really appreciate the work. I have one question about the “serverload” section, all the columns are showing up red no matter what value is in it, (0,40,80,160,200,240,280, etc.) any ideas? Some machines have only 1 user on it and still shows red.

  • Sacha,
    With version 0.93 of the script the email does not send when using more than one email address. It works fine with just one address, but if you add more addresses the mail never sends. This worked fine in version 0.92.

  • What are the chances you could add a variable to sends an email only if an error/warning is detected some where in the process? I did something like this on the older one because the people I worked with didn’t really care for the spam since our uptime was about 90%.

    • Hi, this is something what it’s planed in a future release for both of my health check scripts (XA/XD and PVS), but need a bit time to implement and test. But it’s definitely on my todo list, but not with highest priority to be honest.

  • Sacha, how can I get the total session count and have it displayed on top somewhere?

  • Having an issue running this against a XA and XD environment. It runs successfully against either independently, but both are placed into $DeliveryControllers the test only completes for the first entry regardless of ordering.
    Is this by design? When I looked at the script it seemed to be written to evaluate more than one controller in series.

    Example: $DeliveryControllers = @(“XA-CTRL1″,”XD-CTRL1”) produce results only for XA-CTRL1 while $DeliveryControllers = @(“XD-CTRL1″,”XA-CTRL1”) yields results only for XD-CTRL1
    log just shows:
    Check virtual Desktops ####################################################################################
    Check XenApp Servers ####################################################################################
    Machine: ………………………………….

    for now ill just run it independently against each environment , but it be great to have just one report.
    Any ideas?

    Also in testing I found adding $FileName.Close to end of “Function writeHtmlFooter” prevents the result .htm file from being locked.
    , so when testing code changes you can modify the code and rerun without having to manually kill the file lock or restart PowerShell.

    Great Script, Thanks for posting !!!

    • Hi Jess, thanks for using my script and for the feedback. The script intends to run on one farm. Do you have 2 separated delivery controllers in 2 farms? So you need run the script for each farm. The possibility to use more than one delivery controller is just in case the first DeliveryController does not respond.

      Usually if only one instance of the script runs I have never a file lock. But I’ll doublecheck this again.

    • Try to enter localhost in delivery controller variable and run it on the DeliveryController.,

  • hi – superb script.

    I have a multisite Xendesktop 76 implementation and like to be able to use this script to check all the sites at 1 go. is that possible?

  • Sacha,

    Any chance you have a way to toggle the top 3 sections on/off? I want a version that just has the list of servers and not the top 3 sections…is there a way to comment them out?

    • In the current version not, you need to comment out the lines. I’m working on a future version of the script (first pvs, later XenDesktop/XenApp) in which I work with functions for the checks where it will be much easier to opt-in/opt-out the checks.

      • Hi SachaKen Donaberger

        Dont know if it is my place to reply but I have cut a few things out the script to monitor load which is send every hour
        Columns used as follows
        ServerName CatalogName ServerLoad Ping MaintenanceMode Uptime RegistrationState ActiveSessions DesktopGroupName WindowsConnectionSettings(LogonEnabledLogonDisabled


  • Hi.
    Great script as usual. I have used this and the older Version for my 6.5 farm for a long time now.

    Against XenDesktop Pool 7.6 everything Works fine, but when running against XenApp 7.7 i’ve got an error.

    Get-BrokerMachine : An error occurred while receiving the HTTP response to
    okerAdminService/v2. This could be due to the service endpoint binding not using the HTTP protocol. This could also be
    due to an HTTP request context being aborted by the server (possibly due to the service shutting down). See server log
    for more details.
    At C:TempxsXA-and-XD-HealthCheck.ps1:534 char:13
    + $machines = Get-BrokerMachine -MaxRecordCount $maxmachines -AdminAddress $AdminA …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [Get-BrokerMachine], SdkOperationException
    + FullyQualifiedErrorId : Citrix.XDPowerShell.Broker.UnexpectedException,Citrix.Broker.Admin.SDK.GetBrokerMachineC

    What am I missing? I’m running the script localy from a XA 7.7 Controller.

    • Hi Anders, I just tested on my XenDesktop 7.7 farm what is virtually the same like XenApp 7.7 … it works fine. Does your delivery controller has a problem, can you try on a second one?

  • Hi Sacha

    Your PVS Script gave me needed brownie points at work but can you help me with the following error I am getting

    At C:XA-and-XD-HealthCheck.ps1:77 char:185
    + …”, )
    + ~
    Missing expression after ‘,’.
    + CategoryInfo : ParserError: (:) [], ParseException
    + FullyQualifiedErrorId : MissingExpressionAfterToken

    Any ideas for me please

  • Hi Sacha

    I have added some columns to the Xenapp Checks like Multisession and LogonEnabled or LogonDisabled

    This has probably been done already but just putting it out there


  • Hi Sacha

    I have added some columns to the Xenapp Checks like SessionSupport and LogonEnabled or LogonDisabled

    This has probably been done already but just putting it out there


  • Hi Sacha, thank you for the wonderful script. Also, I’m looking for Citrix Presentation Server 4.0 Health Check script. If you have anyone.. plz share..

    • Hi GP, thanks for your feedback. That’s not so easy, you don’t have powershell, XenApp commands are availible from XA5.x, what do you exaclty need? Maybe I can help you but I’ll not invest time for legacy version scripts.

      • Sacha, I’m looking for the same health check script for legacy environment… I’ve powershell 2.0 but, .NET framework like that few plugins are missing and I’m not recommend to upgrade those… so, planning to do with the vb script in legacy envt to get the health check report. I’ve tried few examples which was shown in online.. but, couldn’t worked for me…

        Plz help me on this

  • Hi Sacha, thank you so much for the wonderful script. I love it.

    Quick question, can you kindly add the addition to the script to shown:

    1. Number of Active Users per XenApp Server
    2. WMI
    3. XML
    4. Available Disk Space
    5. AvgCPU Usage

    Thank you, and keep up the great work Sacha.


    • Hello Bernhard,

      Thank you for your Feedback.

      1. Number of Active Users per XenApp Server -> can I do, will I do in a later version.
      2. WMI -> if WMI doesen’t work you have errors e.g. with the uptime, you will notice that.
      3. XML -> What do you meant with XML?? In XA7 the workers are no more XML-Broker if you mean that back from old IMA-Archtitecuter XenApp
      4. Available Disk Space => possible, only C: should be enough otherwise you are unlimited in configuration …
      5. AvgCPU Usage => not so easy… in which timeframe, nearly unlimited in configuration …


    • Hello Bernard, I have implemented some of your wishes in the new Version 0.95

  • Sacha,
    I’m looking for a powershell script which generate a entire farm inventory list… if yes, please help me on this…

  • Hi Sacha,
    Thanks for the very useful script…… I’m trying to figure out how to remove the “ConnectedUserName” column from the summary. Also, as previously requested, add average CPU and MEM utilization per server just like in the script for XA 6.5. Could this be done?


    • I’ll do an update with the new requests, but currently I’m very busy … please be patient .. sorry for that.

    • Hi Raul, I have implemented a Switch for this in the new Version 0.95

  • Sacha (and other contributers to this script): many thanks for this amazing script!

    As stated by Bradley earlier, the DesktopFree column for XenApp shows a negative number. In my opinion the DesktopFree isn’t relevant for Shared Desktop environments. Can this being changed in a next release?

    • It’s fixed in the new Version 0.95

      • Sacha,
        Thank you so much for this script, been running 0.93 for the past year everyday and it’s a life saver.

        I tried using 0.95 today and I get the following error in red:

        At C:CustomPowerShellXA-and-XD-HealthCheck.ps1:608 char:178
        + … ntDesktopsFree “DesktopsFree > 0 ! ($AssigmentDesktopsFree)” | LogMe -display -p …
        + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        Unexpected token ‘”DesktopsFree > 0 ! ($AssigmentDesktopsFree)”‘ in expression or statement.
        + CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
        + FullyQualifiedErrorId : UnexpectedToken

      • ok, found the issue……

        the following script option only has 953 lines of code:
        You can click here to see the Script code …

        the script you can click to download the file has 976 lines of code, so something is missing from the “You can click here to see the Script code …” option.

  • Sacha,
    Great update on the script!!!! Can you add an option to enable or disable DFreespace on the ControllerServers and the XenApp-Server/XenDesktop-Server?

    • Of course, I’ll add it in a further version, you have a server with only a C? Will the D be red? you can comment out in the table definition as workaround.

      • I do not have a server with only a c drive, my server at least have a c: and d: drive. I guess an option to disable the DFreespace is really not applicable or needed from my stand point.

        • Ah sorry I didn’t understood, but just had a look in my code and I just realized that I have not yet a D: check.
          You like that I add the D:, right?

        • Ryan – if you don’t mind can you add this also as an Issue in GitHub – so we can be sure that’s tracked and you get notified as soon it’s implemented

  • Hi Sacha,
    Well done on the CTP and the site in general, very useful.

    Is there any scope for a Storefront Health Check feature. Either as a bolt on to the XDXA script or as a separate scrip.
    Thanks Tony

    • I like the idea, what is better a separate Script or integrated in the XenApp Health Check script? I just set up a Twitter poll:

      • Great Sacha,
        Can the script interrogate remote storefront servers, as well as the local server/server group.
        Maybe an array of variables that can hold a list of server names?

        • Curretntly I started with the idea that it runs on a SF server, but you can launch it with a Remote session. First start relally early beta is here: What checks are on your wishlist?

          • The basics really (to start!)
            -Disk space
            -Citrix Configuration Replication
            -Citrix Credential Wallet
            -Citrix Default Domain Services
            -Citrix Peer Resolution Services
            -Citrix Subscription service

            Nice to haves would be
            -Verify the Base URL is available
            -Verify managed Delivery Controllers are up
            -Version of Storefront installed
            -We have 14 Storefront servers, it would be nice to run a single script to capture all Storefront servers

  • Just to let you know I have added our Jdrive on the DDC’s and D Drive on the Xenapp servers as well

  • Sorry just the J Drive on the DDC’s

  • Hi,

    We’ve got a strange issue today : one of our XenApp host was unable to accept new user connection. The server itself was Registered, Ping and able to accept/launch session but the Receiver stuck at “Local Session Manager”. So, after looking more deeply in the XenApp and XenDesktop 7.6 Farm Report we found a server that Ping, was Registered and had a Load Index @ 5000 but no user logged in (no user in the column “Connected Users”). The DDC send all the new connection to that server because it has the less load on it. We need to put this server in maintenance to resolve the strange issue.

    So, can you add a something like a validation in your report script so if a XenApp host is Registered, Ping and had a Load Index > 1000, highlight the line in red or something like that? It can probably help other people to be proactive.


    • This is already in:

      # Set value for a load of a XenApp server that is be fine, but is needed to escalate
      $loadIndexWarning = 800
      # Set value for a load of a XenApp server that is be critical
      $loadIndexError = 1500

      Which value you set here – did the server remain in green even when he has breached the set load index.

      • I forgot to say the fourth critaria who is probably needed for our case : Connected User = 0 (no user in the list, Get-BrokerSession)

        So, put in red when a XenApp Host is Registered, Ping, Load Index > 100 and Connected User = 0

        I hope you understand my need.


        • The current construct don’t consider dependencies, sorry. I will maybe implement this in a future release, but there are still a bunch of other requested features in the FR-Queue on GitHub

  • Should I add the FR on GitHub? Thanks yor the quick reply.