Automation–Service Management Automation–Utility Runbook Spotlight–Get-SC-Product-Versions

Automation–Service Management Automation–Utility Runbook Spotlight–Get-SC-Product-Versions

  • Comments 8
  • Likes

Hello Readers/Viewers!

I know I keep posting stuff, but I have so much to  get out I hardly have time to get my PowerShell formatted!

Don’t worry – this post will be short and sweet. I simply wanted to get a quick script in front of you, something that you can execute either from PowerShell ISE as straight PSv3 Workflow, or from as a SMA Runbook.


Many of us work with Beta, Preview, Pre-Release software. Here at MSFT, it seems that I “live in Beta” – always “dogfooding” the next big thing. We do this to be on the bleeding edge, but also to get the best possible product in front of you, before it arrives. That said, if you are reading this post, you likely have some to all components of System Center 2012 R2 Release Preview installed on Windows Server 2012 R2 Release Preview. This means you have a specific version of each component installed.

Do you know which version of each R2 component you have installed?

Sure, at this point you may know AND they likely all line up – But what happens after updates, patches, etc. to the various components? Then it gets a bit more complicated.

For this reason (and for my own, living in a pre-build world), I put together the PowerShell script that you will find below.

Scope of Example

This script does not gather every version of every component of System Center. Instead, it focuses on the bits that were most important to me for troubleshooting purposes. I hope that it can be used as an example of how to quickly and easily gather this type of information – while at the same time illustrating some pretty nifty PowerShell for retrieving data from registries on remote machines.

Product/Components Included:

  • Windows Azure Pack
  • Service Management Automation
  • Service Provider Foundation
  • Virtual Machine Manager

The Example

About Get-SC-Product-Versions

Before we get to the example, here are a few notes about its functionality and script example setup:

  • The script walks the Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ path for each of the stored values related to each product/component above (on each of their respective machines).
  • The script leverages an array of “:” delimited data which is parsed (split), assigned to variables by specific array placement, and passed to the remote InlineScript call. You can certainly generate and pass data any way that you would like, this was just my way to encapsulate all the data necessary for the examples provided.
  • $Products is used to store the component/product data. It is stored as “:” delimited array data, and uses the following format:

    “Component Name from Registry:Field Name for Version:Component Server Name”

    Note     There is an array entry (like above) for each of the component/products.
  • $Creds is leveraging a built in SMA Credential Variable call. Other methods of getting credentials to this PowerShell v3 Workflow / SMA Runbook are certainly acceptable, I just wanted to be consistent with other example SMA Runbook posts.



workflow Get-SC-Product-Versions 
    $Products = @("MgmtSvc:ProductVersion:WAPSever","ServiceManagementAutomation:Version:SMAServer","Service Provider Foundation:Version:SPFServer","Microsoft System Center Virtual Machine Manager Server:ProductVersion:VMMServer") 
    $Creds = Get-AutomationPSCredential -Name 'Contoso Creds'
    foreach ($Product in $Products) {
        InlineScript { 
            $ErrorActionPreference = "SilentlyContinue" 

            $ProductName, $ProductRegVersionPropName, $null = $Using:Product -split ':'
            $ProdRegPath = "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\" + $ProductName 
            $ProductComponents = Get-ChildItem -Path $ProdRegPath 
            foreach ($Component in $ProductComponents) { 
                "{0} : {1} Version: {2}" -f $ProductName, $Component.PSChildName, (Get-ItemProperty -Path $Component.PSPath -Name $ProductRegVersionPropName | Select-Object -ExpandProperty $ProductRegVersionPropName).ToString()
        } -PSComputerName $Product.Split(':')[2] -PSCredential $Creds

Note     This script has been modified based on “Comment” feedback below by @alexandair. Thank you for helping improve our content!

Example Output from PowerShell


Example Output from SMA


Note     The versions you see here will differ from what you have installed.

That’s it! I hope this Get-SC-Product-Versions post provided you with another useful gadget in your SMA Runbook / PowerShell v3 Workflow utility belt!

Oh, and if you want more examples for SMA and PowerShell v3 Workflow, be sure to check out this list (to be updated as more examples are provided):

And for more information, tips/tricks, and example solutions for SMA, be sure to watch for future blog posts in the Automation Track!


Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • Instead of:

    $ProductData = $Product.Split(':')

    $ProductName = $ProductData[0]

    $ProductRegVersionPropName = $ProductData[1]

    $ProductServer = $ProductData[2]

    You can use multiple variable assignment and accomplish the same in just one line:

    $ProductName, $ProductRegVersionPropName, $ProductServer = $Product -split ':'

  • Using a plus sign for string concatenation is fine, but -f format operator produce cleaner code:

    "{0} : {1} Version: {2}" -f $Using:ProductName, $Component.PSChildName, (Get-ItemProperty -Path $Component.PSPath -Name $Using:ProductRegVersionPropName | Select-Object -ExpandProperty $Using:ProductRegVersionPropName).ToString()

  • @alexandair - Thank you so much for your suggested improvements.

    As you can see I have incorporated each in the modifications I made to the example script above.

    Note     I had to tweak the suggestions a little to work with PS Workflow.

    *I had to place the "- split" portion within the InlineScript as when I placed it in the same area where the variable assignments originally were, I received the following notification:

    "This type of assignment is not supported. Only variable names (i.e.: $variable) may be used as the target of an assignment statement."

    *Adding them in the InlineScript actually saved a bunch of instances of "$Using:VariableName" calls.

    *As $ProductServer is needed outside the InlineScript, I just used $Product.Split(':')[2] to get that part of the delimited string

    *I used replaced $ProductName with $null to ensure that the "-split" assignments lined up properly given the data being split. Of course, if you wanted to leverage $ProductName data in the output string, that is perfectly fine. I just didn't want it being assigned with no use in the InlineScript.

    Again, thanks so much for the feedback. I hope I incorporated it as you expected.