Hello readers!

This is Part 2 of the “Calling an Orchestrator Runbook from SMA” blog post. In the previous blog post I talked about how you can call - or actually invoke - an Orchestrator Runbook from within Service Management Automation (SMA). In this blog post (Part 2) we are going to look at how you can return Orchestrator data bus values back into SMA. Orchestrator data bus values are very useful if you want to temporary store data which can be re-used during the runtime of the runbooks and can for example serve as input for other runbooks.

The scenario as described in this blog post is based on automating several steps when a tenant creates a new VM through the Windows Azure Pack portal. To be able to capture the VMname which the user has chosen and which CloudName is linked to the user’s plan, we need to create a SMA Runbook which will be triggered when that happens . This process runbook will invoke different subroutine runbooks as well.

Click on the Download button to download the samples used in this blog post:

7266_BCDLButtonDark_22F105C6


Blog post objectives

We will accomplish the following in this blog post:

  1. Create a custom CostCenter class in Service Manager (or you can download the management pack here)
  2. Create an Orchestrator Runbook to insert the new VMname into the Service Manager’s CMDB
  3. Create an Orchestrator Runbook to retrieve a CostCenterCode from Service Manager
  4. Create a subroutine SMA Runbook which invokes the Orchestrator Runbook as created in step 2
  5. Create a subroutine SMA Runbook which invokes the Orchestrator Runbook as created in step 3  to retrieve a CostCenter stored in the Service Manager’s CMDB, based on a CloudName which is part of a tenant plan
  6. Create a subroutine SMA Runbook to insert the CostCenterCode into the VM properties within Virtual Machine Manager
  7. Create a process SMA Runbook to capture the VMname and CloudName when a tenant creates a new VM and to invoke the subroutine SMA Runbooks
  8. Associate the process SMA Runbook from step 7 to the object VMM VirtualMachine with the action Create
  9. Test drive our solution

Assumptions

As in the previous blog post there are a couple prerequisites. First of all I’m assuming that you have read Part 1 and that you have successfully ran the sample runbooks. This means that you have SMA configured and working. To summarize I am assuming that you have:

  • Windows Azure Pack (WAP) configured with VMM integration and that you can successfully deploy a new VM. Please check Anders Ravnholt’s blog posts on troubleshooting WAP, SPF and VMM if you run into problems
  • System Center Service Manager 2012 SP1 or higher installed and configured
  • System Center Orchestrator 2012 SP1 or higher installed and configured
  • Installed and configured System Center Service Manager’s integration pack for System Center 2012 Orchestrator (SP1 or higher)

SMA Credentials vs. Connections

In Part 1 I’ve used an SMA Credential. To show you a different option this time we will leverage an SMA Connection of the type Orchestrator Service. You can find documentation and a walkthrough on setting up Credentials and Connections here.

image


Step 1 – Create a custom CostCenter class in Service Manager

In this blog post I’ve talked about creating a custom class in Service Manager. You can follow those steps or you can download the custom management pack here

After you have created your custom class or have imported the downloaded management pack into Service Manager, create a CostCenter class instance, that will give you something like this:

image

 

And even a fancy form if you want where you can see the usage of a “projection type” also known as a “combination class” in the form of a Cost Center Owner:

image

 

The information stored in the CostCenter class will be returned to SMA by Orchestrator later on.


Step 2 – Create an Orchestrator Runbook to create a VM entry in the Service Manager CMDB

The following two sections talk about creating the necessary Orchestrator Runbooks. This will make more sense when we include them in the process SMA Runbook. Let’s create the first Orchestrator Runbook which will create a new entry in the Service Manager’s CMDB which represents the new VM created by the tenant.

Note: If you have configured a Virtual Machine Manager connector in Service Manager then you would obviously not need this step. It is just an example how you can pass SMA data to an Orchestrator Runbook.

The Create VMname in CMDB Runbook consists of 3 simple steps:

image

 

The SMA Runbook will pass a VMname into the Intialize Data activity:

image

 

An Create Object activity from the Service Manager integration pack will do the CMBD insert for us:

image

 

For data to be returned to SMA, we need to configure a Return Data variable in the properties of the runbook:

image

 

And return that with an Return Data activity:

image


Step 3 – Create an Orchestrator Runbooks to retrieve the CostCenterCode

In this section we will create the second Orchestrator Runbook which will retrieve the CostCenterCode from the Service Manager CMDB based on the CloudName which is linked to the tenant’s plan in Windows Azure Pack (in my example the Gold Plan and Production Cloud):

image

 

image

 

The Retrieve CostCenter runbook consists of the following steps:

image

 

The Initialize Data activity will get the CloudName passed from SMA

image

 

The GetCostCenter activity will retrieve our CostCenter class instance based on the CloudName

image

 

We could even return Service Manager relationships back to SMA:

image

 

And retrieve the actual related User Object:

image

 

And finally return the values back to SMA through a Return Data activity:

image


Step 4 – Create a subroutine SMA Runbook which will invoke the Orchestrator Runbook to create a VMname entry in the CMDB

This section shows how to invoke the Orchestrator Runbook - as created in step 2 - to create a new entry in the Service Manager CMDB which represents the new created VM. In Part 1 I explained how invoking of an Orchestrator Runbook works.

Create a new SMA Runbook and copy and paste the following PowerShell script in your new SMA Runbook, please make sure that you replace the $RBPath (Runbook Path) and $param1name (Initialize Data) values with your own. My SMA Runbook is called “Write-VMnameToCMDB”.

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100

workflow Write-VMnameToCMDB

<#
    Project Name: Invoke Orchestrator Runbook
    Runbook Name: Write-VMnameToCMDB
    Runbook Type: Subroutine
    Runbook Tags: Type:Sub, Proj:Invoke Orchestrator Runbook
    Runbook Description: Subroutine Runbook, creates a new VMname entry in Service Manager's CMDB
    Runbook Author: Tiander Turpijn
    Runbook Creation Date: 12/09/2013
#>


{
    param( 
    [string]$VMname
    ) 

    # Get the Orchestrator connection
    $con = Get-AutomationConnection -Name 'OrchestratorConnection'

    # Convert the password to a SecureString to be used in a NetworkCredential Object
    $securepassword = ConvertTo-SecureString -AsPlainText -String $con.UserPassword -Force

    # Combine username and domain to be used in NetworkCredential Object
    $domainuser = $con.UserDomain + "\" + $con.UserName

    # Create a Network Credential Object
    $creds = New-Object -TypeName System.Net.NetworkCredential -ArgumentList ($domainuser, $securepassword)

    # Get the url for the Orchestrator service
    $url = Get-OrchestratorServiceUrl -Server $con.ServerName
   
    # Define Runbook Path and parameter names, currently just using 1 initialize data parameter
    # comment out param2name and param2guid if you need it
    $RBPath = "\Building Clouds\Create VMname in CMDB"
    $param1name = "VMname"
    #$param2name = ""
    $param1guid = ""
    #$param2guid = ""
   
    # Retrieve the target SCO Runbook
    $runbook = Get-OrchestratorRunbook -ServiceUrl $url -Credentials $creds -RunbookPath $RBPath
       
    foreach ($param in $runbook.Parameters)
    {
        if ($param.Name -eq $param1name)
        {
            $param1guid = $param.Id  
        }
        elseif ($param.Name -eq $param2name)
        {
            $param2guid = $param.Id  
        }
    }
       
    if ($runbook -ne $null) 
       {
        # Start runbook with params
        [hashtable] $params = @{
            $param1guid = $VMname;
            #$param2guid = "<value here>"
        }
       }

    # Start the runbook and get the job id returned
    $job = Start-OrchestratorRunbook -Runbook $runbook -Credentials $creds -Parameters $params
       
    # If a job has been created then wait for it to complete and get any output
    if ($job -ne $null)
    {
        # Wait for the Job to complete
        while( ($job.Status -eq "Running") -or ($job.Status -eq "Pending") )
        {
            Start-Sleep -m 500
            $job = Get-OrchestratorJob -jobid $job.Id -serviceurl $job.Url_Service -credentials $creds
        }
   
        # The job is complete, so get any output
        $instance = Get-OrchestratorRunbookInstance -Job $job -Credentials $creds
        if ($instance -ne $null)
        {
            $instparams = Get-OrchestratorRunbookInstanceParameter -RunbookInstance $instance -Credentials $creds
            if ($instparams -ne $null)
            {
                foreach ($instparam in $instparams)
                {
                    if ($instparam.Direction -eq "Out" -and $instparam.name -eq "VMname")
                    {
                        $VMname = $instparam.value
                    }
                }
            }
        }
    }
    else
    {
        Write-Output "No job created"
    }
  Return $VMname  
}

Test your new SMA Runbook to make sure it works as expected. It should create a new entry in the Service Manager’s CMDB of the type Windows Computer.


Step 5 - Create a subroutine SMA Runbook which invokes an Orchestrator Runbook to retrieve the CostCenterCode

For invoking the Orchestrator Runbook which will retrieve the CostCenterCode for us, we are using something similar as in the previous step, but this time we will retrieve multiple Orchestrator Return Data values.

Retrieving Orchestrator Databus Values

The PowerShell script below demonstrates how you can retrieve Orchestrator Databus Values which are getting returned from Orchestrator through a Return Data activity. Please note line 78– 98, there’s where all the Return Data magic happens. The $CostCenterHashTable will contain all the Databus Values from Orchestrator.

Please make sure that you replace the $RBPath (Runbook Path) and $param1name (Initialize Data) values with your own. Copy and paste the following PowerShell script into your new SMA Runbook. Mine is called Get-CostCenterFromSM :

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106

workflow Get-CostCenterFromSM
<#
    Project Name: Invoke Orchestrator Runbook
    Runbook Name: Get-CostCenterFromSM
    Runbook Type: Subroutine
    Runbook Tags: Type:Sub, Proj:Invoke Orchestrator Runbook
    Runbook Description: Subroutine Runbook, Get's the CostCenter from Service Manager
    Runbook Author: Tiander Turpijn
    Runbook Creation Date: 12/09/2013
    #>

{
    param( 
    [string]$CloudName
    ) 

    # Get the Orchestrator connection
    $con = Get-AutomationConnection -Name 'OrchestratorConnection'

    # Convert the password to a SecureString to be used in a NetworkCredential Object
    $securepassword = ConvertTo-SecureString -AsPlainText -String $con.UserPassword -Force

    # Combine username and domain to be used in NetworkCredential Object
    $domainuser = $con.UserDomain + "\" + $con.UserName

    # Create a Network Credential Object
    $creds = New-Object -TypeName System.Net.NetworkCredential -ArgumentList ($domainuser, $securepassword)

    # Get the url for the Orchestrator service
    $url = Get-OrchestratorServiceUrl -Server $con.ServerName
   
    # Define Runbook Path and parameter names, currently just using 1 initialize data parameter
    # comment out param2name and param2guid if you need it
    $RBPath = "\Building Clouds\Retrieve CostCenter"
    $param1name = "CloudName"
    #$param2name = ""
    $param1guid = ""
    #$param2guid = ""
   
    # Retrieve the target SCO Runbook
    $runbook = Get-OrchestratorRunbook -ServiceUrl $url -Credentials $creds -RunbookPath $RBPath
   
   
    foreach ($param in $runbook.Parameters)
    {
        if ($param.Name -eq $param1name)
        {
            $param1guid = $param.Id  
        }
        elseif ($param.Name -eq $param2name)
        {
            $param2guid = $param.Id  
        }
    }
       
    if ($runbook -ne $null) 
       {
       
        # Start runbook with params
        [hashtable] $params = @{
            $param1guid = $CloudName;
            #$param2guid = "<value here>"
        }
       }

    # Start the runbook and get the job id returned
    $job = Start-OrchestratorRunbook -Runbook $runbook -Credentials $creds -Parameters $params
       
    # If a job has been created then wait for it to complete and get any output
    if ($job -ne $null)
    {
        # Wait for the Job to complete
        while( ($job.Status -eq "Running") -or ($job.Status -eq "Pending") )
        {
            Start-Sleep -m 500
            $job = Get-OrchestratorJob -jobid $job.Id -serviceurl $job.Url_Service -credentials $creds
        }
   
        # The job is complete, so get any output
        $instance = Get-OrchestratorRunbookInstance -Job $job -Credentials $creds
       
        if ($instance -ne $null)
        {
            $instparams = Get-OrchestratorRunbookInstanceParameter -RunbookInstance $instance -Credentials $creds
            if ($instparams -ne $null)
            {
                $CostCenter = InLinescript{
                    $CostCenterHashTable = @{}
                    foreach ($instparam in $Using:instparams) {
                      if ($instparam.Direction -eq "Out")
                      {
                        $CostCenterHashTable.Add($instparam.name,$instparam.Value)
                      }
               }

              Return $CostCenterHashTable
                }
            }
         }
     }
    else
    {
        Write-Output "No job created"
    }
    $CostCenter
}

Test your new SMA Runbook to make sure it works as expected.

 

If you test the Orchestrator web service as we’ve done in Part 1 and paste the Orchestrator web service URL including the RunbookParameterGuid in your web browser, you can see the return parameter (CostCenterCode) and its direction (Out), which corresponds with what we’re doing in the above PowerShell script (line 78– 98):

image

 


Step 6 - Create a subroutine SMA Runbook to insert the CostCenterCode into the VM properties

This last subroutine SMA Runbook will insert the CostCenterCode into the VM properties within Virtual Machine Manager.

Create -  as in the previous steps - a new SMA Runbook and copy and paste the following PowerShell script, mine is called Set-CostCenterInVM :

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043

Workflow Set-CostCenterInVM
<#
    Project Name: Invoke Orchestrator Runbook
    Runbook Name: Set-CostCenterInVM
    Runbook Type: Subroutine
    Runbook Tags: Type:Sub, Proj:Invoke Orchestrator Runbook
    Runbook Description: Subroutine Runbook, inserts the CostCenterCode in the VM properties within VMM
    Runbook Author: Tiander Turpijn, Microsoft Corporation
    Runbook Creation Date: 12/09/2013
    #>

{

param( 
    [Parameter(Mandatory)]
    [string]$VMname,
    [Parameter(Mandatory)]
    [string]$CostCenterCode
    )
   
$PSCredName = "XWING-Creds"
$PSUserCred = Get-AutomationPSCredential -Name 
$PSCredName
$VMMServer
 = "XW-VMM12R2" 
   
$output = InlineScript{
    Import-Module virtualmachinemanager 
    Get-SCVMMServer -ComputerName $Using:VMMServer 
  
    # Set CostCenter for a VM
    $vm = Get-SCVirtualMachine | where {$_.Name -eq $Using:VMname}
   
    while ([string]($vm.MostRecentTask | select "Status") -match "Running")
        {
            # VM object is locked by another process, retrying...
            Start-Sleep -m 5000
        }
    Set-SCVirtualMachine -VM $vm -CostCenter $Using:CostCenterCode
       
return $output
  }
$output
$CostCenterCode

}

Test your new SMA Runbook to make sure it works as expected. This has a dependency on an existing VM, so make sure you have one to test against. Be sure to replace the $PSCredName (Credentials) and the $VMMServer variable values with your own.


Step 7 – Create a process SMA Runbook to capture the VMname and CloudName and to invoke the subroutine SMA Runbooks

Finally the last SMA Runbook which we call our process runbook. This does two things: it captures the VMname (as chosen by the tenant) and it captures the CloudName (as linked to the tenant’s plan).

Before continuing make sure that you have saved and published all your subroutine SMA Runbooks

Copy and paste the PowerShell script below into a new SMA Runbook, mine is called Get-MyVMname:

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034

workflow Get-MyVMname
<#
    Project Name: Invoke Orchestrator Runbook
    Runbook Name: Get-MyVMname
    Runbook Type: Process
    Runbook Tags: Type:Process, Proj:Invoke Orchestrator Runbook
    Runbook Description: Process Runbook for the "Invoke Orchestrator Runbook" Project
    Runbook Author: Tiander Turpijn
    Runbook Creation Date: 12/09/2013
    #>


{
    param
    (
        [object]$resourceObject
    )
   
    $VMname = $resourceObject.name
    $CloudName = $resourceObject.Cloud.name
   
    #Call Subrouting Runbook to write VMname to the Service Manager CMDB
    Write-VMnameToCMDB -VMname $VMname
   
    # Call Subroutine Runbook to retrieve the Cloud CostCenter from Service Manager CMDB
    #Write-Output "Cloudname is $CloudName"
    $CostCenter = Get-CostCenterFromSM -CloudName $CloudName
    $CostCenter
    $CostCenterCode = $CostCenter.CostCenterCode
       
    # Call Subroutine Runbook for setting the CostCenter in VM properties in VMM
    Set-CostCenterInVM -VMname $VMname -CostCenterCode $CostCenterCode
    Write-Output "CostCenterCode is: $CostCenterCode"
}
 

Make sure that you add a “SPF” TAG to your runbook, otherwise your runbook will not show if we are going to associate it in step 8:

image

 


Step 8 – Associate the process SMA Runbook

In this section we are going to associate our new process runbook, which we’ve created in step 7,  so that it will be invoked if a tenant creates a new VM through the WAP portal.

Within the Windows Azure Pack portal, click on VM CLOUDS and then on AUTOMATION:

image

 

Click on  image  on the bottom of the portal and link our process SMA Runbook (as created in step 7)  as shown below:

image

Note: A very good reference for associating objects with SMA Runbooks can be found here


Step 9 – Test-drive our solution

Now that we have all the pieces in place it is time to test-drive our solution! Login as a tenant into the Windows Azure Pack portal and create a new VM:

image

 

image

 

You should see that our process runbook get’s triggered by this event. Please notice the wealth of information you can use in other runbooks. For example look at the ComputerNameString that contains the actual computer name of the VM:

image

 

A VM is created by VMM:

image

 

Our first subroutine runbook creates an entry in the Service Manager CMDB:

image

 

And we start seeing output from our process runbook:

image

 

If we click on the Output details we can see our Databus Values nicely being returned:

image

 

Our process runbook has completed:

image

 

And we can see all the data in the History Output:

image

 

Our final subroutine runbook has inserted our CostCenterCode into the VM properties, nice!

image

 


I hope that I have been able to demonstrate how you can further light up your Orchestrator Runbooks, reach out to Service Manager and realize SMA integration.

Happy automation and until next time!