Home > Lync Server/Skype for Business Server > Script: Get-CsUpdateVersion.ps1 – See the Cumulative Update Level Of All Lync/Skype for Business Servers

Script: Get-CsUpdateVersion.ps1 – See the Cumulative Update Level Of All Lync/Skype for Business Servers


My work at Modality Systems often has me doing health checks for customer Lync environments. These can be due to customer requests, or as part of our onboarding for new managed support customers. If you’ve ever had an Active Directory Risk Assessment Program (ADRAP) or Exchange Risk Assessment Program (ExRAP), it’s quite similar. Lots of tasks to run, lots of data to sift through. So it’s always beneficial to standardize and automate the steps to get the data. The same is the case when you’re responsible for your own environment and want to ensure good health.

Just like Get-CsDatabaseUpdateStatus.ps1, Dave Howe from the Lync product group and I teamed up to automate something. In this case, it’s looking at what Cumulative Updates are installed on each server throughout a Lync environment. This script queries each pool, then finds what servers are part of that pool, and queries each server to find the CU that’s installed. It then provides an easy to read output of the entire environment (with exceptions) for easy review. As shown below, we see three multi-server pools, the version number and “friendly” Cumulative Update info.


The script works fine with Standard Edition servers as well:


In the first example, you see that the first two servers show “PSRemoting failure”. This is because the script uses PowerShell Remoting to connect to each remote server to query information (see installation notes below). PSRemoting doesn’t really work the same when dealing with non-domain joined machines, such as the first two, which are edge servers. So the script isn’t able to communicate with them via PSRemoting, and flags them. If the script can’t ping a server, it will show as “offline”. The friendly name of the CU shown is coded in the script. So I’ll update it each time a new CU is released.

By default, the script checks all pools. But you can specify a single pool by using the -PoolFqdn parameter.

A new option added is the -online option. When you use this option, the script will query an online source of version info, instead of using the data listed within the script.


Get-CsUpdateVersion.ps1 [[-PoolFqdn] ] [-WhatIf] [-Confirm] [-Online]


This script uses PowerShell Remoting to query remote servers. PSRemoting is enabled by default on Windows Server 2012 and later, but disabled by default on 2008 R2. To enable PSRemoting on 2008 R2 servers, see Enable-PSRemoting.

Execution Policy: Third-party PowerShell scripts may require that the PowerShell Execution Policy be set to either AllSigned, RemoteSigned, or Unrestricted. The default is Restricted, which prevents scripts – even code signed scripts – from running. For more information about setting your Execution Policy, see Using the Set-ExecutionPolicy Cmdlet.


I’ve never been one to really solicit donations for my work. My offerings are created because *I* need to solve a problem, and once I do, it makes sense to offer the results of my work to the public. I mean, let’s face it: I can’t be the only one with that particular issue, right? Quite often, to my surprise, I’m asked why I don’t have a “donate” button so people can donate a few bucks. I’ve never really put much thought into it. But those inquiries are coming more often now, so I’m yielding to them. If you’d like to donate, you can send a few bucks via PayPal at https://www.paypal.me/PatRichard. Money collected from that will go to the costs of my website (hosting and domain names), as well as to my home lab.




v3.8 – 02-14-2017 – Get-CsUpdateVersion.v3.8.zip

v3.7 – 02-05-2017 – Get-CsUpdateVersion.v3.7.zip

v3.6 – 01-06-2017 – Get-CsUpdateVersion.v3.6.zip

v3.5 – 11-28-2016 – Get-CsUpdateVersion.v3.5.zip

v3.4 – 11-12-2016 – Get-CsUpdateVersion.v3.4.zip

v3.3 – 08-31-2016 – Get-CsUpdateVersion.v3.3.zip

v3.2 – 07-15-2016 – Get-CsUpdateVersion.v3.2.zip

v3.1 – 07-05-2016 – Get-CsUpdateVersion.v3.1.zip

v3.0 – 04-21-2016 – Get-CsUpdateVersion.v3.0.zip

v2.9 – 04-07-2016 – Get-CsUpdateVersion.v2.9.zip

v2.8 – 01-26-2016 – Get-CsUpdateVersion.v2.8.zip

v2.7 – 12-14-2015 – Get-CsUpdateVersion.v2.7.zip

v2.6 – 11-17-2015 – Get-CsUpdateVersion.v2.6.zip

v2.5 – 11-11-2015 – Get-CsUpdateVersion.v2.5.zip

v2.4 – 10-03-2015 – Get-CsUpdateVersion.v2.4.zip

v2.3 – 09-09-2015 – Get-CsUpdateVersion.v2.3.zip

v2.2 – 07-14-2015 – Get-CsUpdateVersion.v2.2.zip

v2.1 – 06-21-2015 – Get-CsUpdateVersion.v2.1.zip

v2.0 – 05-12-2015 – Get-CsUpdateVersion.v2.0.zip

v1.9 – 02-19-2015 – Get-CsUpdateVersion.v1.9.zip

v1.8 – 02-09-2015 – Get-CsUpdateVersion.v1.8.zip

v1.7 – 01-01-2015 – Get-CsUpdateVersion.v1.7.zip

v1.6 – 12-12-2014 – Get-CsUpdateVersion.v1.6.zip

v1.5 – 11-21-2014 – Get-CsUpdateVersion.v1.5.zip

v1.4 – 09-24-2014 – Get-CsUpdateVersion.v1.4.zip

v1.3 – 09-02-2014 – Get-CsUpdateVersion.v1.3.zip

v1.2 – 08-07-2014 – Get-CsUpdateVersion.v1.2,zip

v1.1 – 06-02-2014 – Get-CsUpdateVersion.v1.1.zip

v1.0 – 05-02-2014 – Get-CsUpdateVersion.v1.0.zip


See the changelog for information on what’s changed/included in each version.

  1. May 6th, 2014 at 09:12 | #1

    Thx Pat for your effort, it was a good solution

  2. May 7th, 2014 at 03:42 | #2

    Fantastic as always Pat. Thanks a ton.

  3. davidchr
    May 16th, 2014 at 11:17 | #4

    Another great tool for Lync admins! Im seeing an issue though…all of my servers in the edge pool are showing the following: fqdn of server (offline)
    I checked execution policy and its remotesigned. The Edge server’s OS is 2012 and they are in the DMZ. We used the following http://technet.microsoft.com/en-us/library/gg398739.aspx to open the necessary ports to/from the edge servers and between edge and fe boxes. Any ideas?

    • Pat Richard
      May 16th, 2014 at 22:58 | #5

      It’s not likely going to work with Edge servers, as their is no AD authentication to those machines.

  4. Andy G
    May 20th, 2014 at 23:52 | #6

    If you have newer Debugging Tools or Resource Kit it detects those as the current version. Perhaps you should only look at the Core Components program as that should always reflect the latest installed version?

    • Pat Richard
      May 30th, 2014 at 11:20 | #7

      That’s being addressed in the new version, as is a quirk around Lync Server 2010.

  5. Mickael B
    August 13th, 2014 at 09:43 | #8

    Great script !
    For the 2013 Edge server, you could use the output of “Get-CsManagementStoreReplicationStatus” to get the “ProductVersion”, which is not very elegant, but should do the trick (at least for 2013)

    • Pat Richard
      August 16th, 2014 at 01:39 | #9

      The problem with that is it’s also not accurate. If you have post CU patches installed, Get-CsManagementStoreReplicationStatus just shows the version to the CU – not to any post CU patches.

      • Brian Longoria
        August 28th, 2014 at 17:13 | #10

        Yep – that’s what led me here. Had all CU 5 updates, and repstatus was still returning .556- I got concerned why there was a difference. Still haven’t found why, but at least this script, plus server control panel\product version and the CU.exe. three confirmations makes me feel a lot more secure. Thanks for the script.

  6. Andrew Burt
    February 24th, 2015 at 20:17 | #11

    Cheers Pat! Script much appreciated!

  7. Dhivya
    March 12th, 2015 at 04:15 | #12

    Great script and working well, is there any option to export the result in CSV file?

    • Pat Richard
      March 12th, 2015 at 06:44 | #13

      Not at this time.

  8. David Paulino
    April 12th, 2015 at 06:57 | #14

    Pat, thanks for this great script.
    I notice that in your script you have “5.0.8308.871”= “Lync Server 2013 CU11 – Feb. 19, 2015”, but if you download and install the latest CU it will go to “5.0.8308.872”.

    • Pat Richard
      April 17th, 2015 at 00:49 | #15

      I’ve requested clarification on this. The original file was .871, and the KB and updates pages still refer to .871. But the file that’s downloaded is .872. As soon as I get some more info, I’ll pass it along.

  9. Martin Boam
    May 12th, 2015 at 05:45 | #16

    Hi Pat, Thanks for the great Script as always! I used against Lync Server 2010 yesterday and I noticed that for 4.0.7577.710 it stated Lync Server 2010 CU15 – Dec. 2015. Wondered if this should be Dec 2014.

    • Pat Richard
      May 12th, 2015 at 08:03 | #17

      Yeah, that’s fixed in the next version.

  10. May 13th, 2015 at 11:43 | #18

    Fantastic script Pat! Worked like a charm and saved me time. Thanks. (it didn’t pick up my 2 Mediation Pools but they were co-located on my 2 Enterprise Front-End pools so it didn’t really matter)

  11. Bernard Dejonckheere
    August 12th, 2015 at 05:52 | #19


    great script.
    I would suggest you added folowing code:
    new-> $FriendlyResult=”Unknown Version”
    switch ([string] $version) {

    • Pat Richard
      August 14th, 2015 at 10:19 | #20

      Thanks for the idea. I’ve got it queued for v2.3.

  12. shane negaard
    February 21st, 2016 at 04:47 | #21

    if you have a copy of the HP 4120 December 2012 cumulative update. 4.0.7577.4366 I would like to get a link to download it.
    I need to roll back to that version in order to fix a nagging issue that was uncovered when I updated to the latest release.
    I have a open case with Microsoft, but they do not offer previous versions of those cumulative updates.
    only the most current one online.
    I had 1 phone with the older version that does not have the issue, but I do not have the CU to import and roll back my phones.
    if anyone has a copy, please reply with a link.

  13. Ryan Patridge
    February 25th, 2016 at 13:06 | #22

    Thanks, great script, Pat!

    Minor problem with version 2.8 – 01-26-2016: the script #Requires -Version 2.0, but Powershell 2.0 doesn’t support CmdletBinding directives or Parameter decorators with null arguments (ie. lacking the “=” operator with an assigned value). Running it in Powershell 2.0 yields the following error message:

    The “=” operator is missing after a named argument.
    At D:\Scripts\PS\Get-CsUpdateVersion.ps1:48 char:38
    + [CmdletBinding(SupportsShouldProcess) <<<< ]
    + CategoryInfo : ParserError: (:) [], ParseException
    + FullyQualifiedErrorId : MissingEqualsInNamedArgument

    I quickly "fixed" this by adding "= $false" to all of the unassigned arguments specified in various CmdletBinding directives and Parameter decorators in the script. Some of them might be better set to "$true", but I'm not sure, and lack the cycles to do testing. All the same, after making this "fix", it worked great for me in Powershell 2.0. Thanks again.

  14. Matthew
    April 22nd, 2016 at 13:54 | #23

    Love the script! Just curious why my FE servers show [Lync Server 2013 Post CU5] and not a definite CU version like your screenshots. Any thoughts?

    • Pat Richard
      April 22nd, 2016 at 15:30 | #24

      Because you have a post CU5 update installed. Your version number likely is 5.0.8308.803

  15. Tony Hart
    August 29th, 2016 at 15:28 | #25

    Has it been updated for the August 2016 CU?

  16. Pat Richard
    August 29th, 2016 at 15:31 | #26

    I’m assuming you mean the Lync Server CU for August. Not yet. Should be online in the next day.

  17. Pat Richard
    August 31st, 2016 at 13:42 | #27

    @Tony Hart
    New version is now available

  18. soder
    October 25th, 2016 at 09:15 | #28

    Hello Pat,
    does your script analyze all the components that are available as part of a Cumulative Update package, or is limited only to the FrontEnd patch / Core components patch? I am trying to validate the job done by operations people in order to see all update packages have been installed by them correctly, or they missed some of them.

  19. Robert
    January 12th, 2017 at 07:58 | #29

    Great script, but it does not work on edge servers that are not in a domain.
    “Get-CsService : Cannot find information about the local domain”.

    Is there a way to get the version on Edge servers?


  20. Phil Meyer
    January 13th, 2017 at 14:31 | #31

    Hello Pat,

    I stumbled upon your script while searching for a way to determine Lync version information. Thank you so much for your time and expertise on this and many other subjects!

    I think you should know that the current version of the script, 3.6, is still labeled 3.5 and also asks if you want to download a new version. I changed the following value and it no longer asks, but you might want to make sure the correct version is in your ZIP file. 🙂

    Thanks again!

  21. soder
    February 15th, 2017 at 10:45 | #33

    Hello Pat,

    // trying to clarify 1 more time //
    does your script analyze all the components that are available as part of a Cumulative Update package, or is limited only to the FrontEnd patch / Core components patch? I am trying to validate the job done by operations people in order to see all update packages have been installed by them correctly, or they missed some of them.

    • February 20th, 2017 at 16:21 | #34

      So, it takes a look at the related items shown in Add/Remove programs that have “Microsoft Lync Server”, “Microsoft Office Web Apps Server 2013”, or “Skype for Business Server”, and filters out “Debugging Tools”,”Resource Kit Tools”,”Best Practices Analyzer”, and “Meeting Room Portal”. It then takes the highest version number of what’s left, which should be just the related components. It’s not perfect, but I generally don’t see issues.

      If your operations people are are using the ServerInstaller.exe file to do the upgrade, then you should be fine.

  1. May 3rd, 2014 at 23:55 | #1
  2. May 5th, 2014 at 07:28 | #2
  3. May 7th, 2014 at 03:41 | #3
  4. July 3rd, 2014 at 13:13 | #4
  5. November 22nd, 2014 at 15:46 | #5
  6. January 1st, 2015 at 15:51 | #6