Automation–Service Management Automation & Azure Automation–Complex Asset Creation and Usage

Hello Readers!

What if I told you that you could store and leverage Hashtables as Variable Assets in Service Management Automation (SMA) AND Azure Automation (AA)?

Well you can!

It takes a little more effort, but the ROI is well worth it…after all, who wants to store the same Hashtable of information over and over throughout a set of Runbooks?

Before I begin, let me preface this post with some existing (and fantastic) guidance about Assets for both SMA and AA, previously posted by the SC Automation Team:

Now, let’s go through the Whats, the Wheres, and the Hows, of my scenario!

Note     The guidance here applies to both SMA and AA. I will clearly notate any and all differences.


Complex Asset Creation

The What

What is the use case for this?

Use Case: You have a set of semi-static information (e.g. Hashtable) that you want to reference multiple times, but only store once.

Out-of-the-box and intuitively, as you have been working with SMA Assets for a while now, you could easily store:

image

And retrieve single values:

image

You could even store really large string values here…

image

Special thanks to the online Lorem Ipsum Generator.

But jamming a Hashtable in there – that is a bit more challenging…


The Where

So, where does one work with Assets (complex or otherwise)?

Up to this point, you likely have started the majority of your Variable Asset creation and modification in one of two places:

  • In the ASSETS tab of SMA/AA – Add Setting button
    image
  • Within a Runbook, from the Manage button – Add Setting option
    image

Note     If you didn’t know about that “Manage – Add Setting” option, it is a FANTASTIC way to generate new Settings, without having to change context of Runbook authoring.

For the most part, you will continue to use these two primary Variable Asset Creation methods. For Modifications (or setting the Variable Asset value) though, that is where we diverge a bit, for now. See the “Alternate Creation Method for SMA” section below for more information.


The How

Now we get to the good stuff – How do we create Complex Variable Assets?

The following process provides guidance for the creation and modification (setting) of Complex Variable Assets. It works and has been tested in both SMA and AA (as of the date of this post).

  1. Create a String Variable Asset (Choose “Add Setting” from either the SMA/AA Asset tab, or Manage button at the bottom of a Runbook Authoring tab)
    image
    image
    Note     Leave the “Value” field blank, as it will be overwritten later in this process, anyway.

    Alternatively     You could leverage the “Null” (SMA) or “Not Defined” (AA) Variable Types for this step. These options do not allow you to enter a Value, which is just fine for this scenario. In fact, the Variable Type field exists so that the engine knows how to interpret user input. The engine does not enforce that the variable ever stay the value type after creation – thus allowing us to change it to a “Complex” type via the Set commands (below).

  2. Verify the creation of the Asset Variable (from the Asset tab in SMA/AA)
    image
    image
    Note    See that the “Type” value is “String” (as specified during creation).
  3. Create a new Runbook (within SMA/AA New – … – Quick Create – … – Create)
    SMA
    image
    -or- AA
    image
  4. Type or Insert the Script necessary to perform Set-AutomationVariable on “My Complex Asset”
    SMA
    image
    image
    -or- AA
    image
    image
    Note     In either case, this will be used AFTER the Complex Variable Asset (Hashtable) has been declared.
  5. Above the Set-AutomationVariable call, Type or Paste in the definition of your desired Complex Variable Asset (Hashtable), Update the -Value parameter with the Variable name for that Hashtable, and Add a Get-AutomationVariable call so the update can be verified during test/execution

    First, here is an example of the Hashtable I will be using for this example, developed/tested in ISE first:
    image
    Note     Each item in the Hashtable contains a simple string for the “Key”; the corresponding “Value” is an array with members consisting of a string, an int, and a boolean value.

    And here is the Runbook after all the updates in this step:
    image
    Note     This is the same for both SMA and AA.

  6. Either Publish and Run, or Save and Test this Runbook
    image
    Note     The example here is a “Save and Test” execution from AA. I did the same in SMA, but the output is (as expected) the same.
  7. Verify the update of the Asset Variable (from the Asset tab in SMA/AA)
    SMA
    image

    -and- AA
    image
    Note    See that the “Type” value is now “Complex Type” or “Complex” (slight difference in output from SMA to AA).

 

You now have stored a Complex Variable Asset in SMA and/or AA!


Example Runbook (from above)

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
workflow Update-MyComplexAsset
{
    $myComplexAsset = @{
        HTKey1 = "String 1",5120,$false
        HTKey2 = "String 1",2560,$true
        HTKey3 = "String 2",10240,$true
        HTKey4 = "String 1",1024,$true
        HTKey5 = "String 3",256000,$true
    }
   
    Set-AutomationVariable -Name 'My Complex Asset' -Value $myComplexAsset
   
    $myComplexAssetData = Get-AutomationVariable -Name 'My Complex Asset'
    Write-Output $myComplexAssetData
}

Alternate Creation Method for SMA

Both SMA and AA ship with a set of PowerShell Cmdlets. For SMA, they ship with the product as SMA Cmdlets. For AA, they ship as part of the Azure Cmdlets.

Included in the SMA Cmdlets is the command: Set-SmaVariable. This cmdlet allows for both the creation of new SMA Variables, as well as the updating of existing SMA Variables.

Note     Set-AutomationVariable is different than Set-SmaVariable in this regard, as it requires the variable asset already exist within SMA/AA.

So, the following script will create and set a complex variable in SMA:

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
$myComplexAsset = @{
    HTKey1 = "String 1",5120,$false
    HTKey2 = "String 1",2560,$true
    HTKey3 = "String 2",10240,$true
    HTKey4 = "String 1",1024,$true
    HTKey5 = "String 3",256000,$true
}

Set-SmaVariable -Name "My Complex Asset 2" -Value $myComplexAsset `
    -WebServiceEndpoint "https://localhost"

Get-SmaVariable -Name "My Complex Asset 2" `
    -WebServiceEndpoint "https://localhost"

Results

image

Note     Performing the Get-SmaVariable is not necessary, as the Set-SmaVariable results output the same data.

image

Note     It was not required to create the String Variable Asset before running this Get-AutomationVariable call, because the Set-SmaVariable command both creates and sets.


Other Advantages of Using the available Cmdlets

In general, there are other advantages of using the available Cmdlets – Specifically, the fact that they can be used inside a Runbook, or in a PS Console / ISE (assuming that the module is installed local to that PS Console / ISE).


What About Azure Automation for this scenario?

Once the Azure Cmdlets are updated to include Set-AzureAutomationVariable, this same functionality should be possible.


Note     This completes the “Creation” portion of this scenario. The next section will describe the “Usage” portion.


Complex Asset Usage

The What

Now that you have stored a Complex Variable Asset in SMA and/or AA, what can you do with it?

Well, your first thought might be to get it, and use it like a normal Hashtable.

While that is a good thought, the storage of this Complex Variable Asset requires it to change “type” from a conventional Hashtable.

Note     In general, Variables are stored as JSON. So, complex objects (e.g. Hashtables) stored, come back as property bags (specifically, the PSCustomObject type).

So, when you call Get-AutomationVariable on a complex object, assign it to a variable, that variable becomes a PSCustomObject.

Here are the BEFORE GetType() Results:

image

No sweat, there are many published ways on Converting from PSCustomObject to a conventional Hashtable.

Note     In the next part of this section, I will show you what I use. You may want to explore other options.


The How

So, how did I overcome this minor obstacle in my scenario?

Well, looking through the various options (from the Bing search link above), I decided on the following process:

  1. Get the Variable (Get-AutomationVariable) and assign it to a $Variable
  2. Declare a new Variable Hashtable ($htVariable = @{})
  3. Iterate through the PSObject Properties of the PSCustomObject and add each Name/Value pair to the new Variable Hashtable

Note     The examples here work both in SMA and AA, the screen shots were taken from the tests performed in AA.

Here is an Example Script:

001
002
003
004
005
$myComplexAssetData = Get-AutomationVariable -Name 'My Complex Asset'

$newComplexAssetHT = @{}
$myComplexAssetData.PSObject.Properties `
    | ForEach { $newComplexAssetHT.Add($_.Name, $_.Value) }

And here are the AFTER GetType() Results:

image

Now that the Complex Variable Asset data has been converted back to a conventional Hashtable, we can perform the “usual Hashtable tasks” to get and manipulate the data…

And just to finish this off, here is a simple example script of Complex Asset Usage (based on the same Complex Variable Asset data set above):

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
$myComplexAssetData = Get-AutomationVariable -Name 'My Complex Asset'

$newComplexAssetHT = @{}
$myComplexAssetData.PSObject.Properties `
    | ForEach { $newComplexAssetHT.Add($_.Name, $_.Value) }

$htData = $newComplexAssetHT.Get_Item("HTKey1")

$strValue = $htData[0]
$intValue = $htData[1]
$boolValue = $htData[2]
   
$outputMsg = "String Value: {0}`nInteger Value: {1}`nBoolean Value: {2}" `
    -f $strValue,$intValue,$boolValue
Write-Output $outputMsg

And here are the Usage Results (again, based on the same Complex Variable Asset data set above):

image


Alternative / Filter Enhanced Method for Conversion

As I stated, there are various options for accomplishing this conversion. Here is another example, in the event that you need further filtering as part of the conversion:

001
002
003
004
005
006
007
$newComplexAssetHT =@{}

$myComplexAssetData = Get-AutomationVariable -Name 'My Complex Asset'

$myComplexAssetData.PSObject.Properties |
?{ $_.Name -inotmatch '^PS' } |
Foreach { $newComplexAssetHT.Add($_.Name, $_.Value) }

Note     This is especially helpful if the PSCustomObject being returned contains the extraneous “PS*” prefixed Name/Value pairs often associated with PowerShell Workflow calls. But you could leverage this level of filtering for anything you need with regards to data manipulation.


Updating the Complex Asset Data

In the beginning of this post, the use case I described for this scenario was intended for “semi-static information”. It really could be fully dynamic information as well. Updating the Variable is as simple as:

  1. Changing the values for the Hashtable as desired
  2. Assigning the Hashtable to a $Variable
  3. Calling Set-AutomationVariable with the new $Variable value

Essentially, just modify and execute the Update-MyComplexAsset Runbook discussed above (or whatever you have decided to call it in your set of Runbooks).


Note     The examples here are truly just examples.  You likely have more and better ways to leverage Hashtable data. I just wanted to show you a simple way to Create Complex Variable Assets in SMA and AA, then retrieve that data, convert it, and use it.


Thanks for checking out my blog post! For more information, tips/tricks, and example solutions for Automation within System Center, Windows Azure Pack, Microsoft Azure, etc., be sure to check out the other blog posts from Building Clouds in the Automation Track!

enJOY!