Note : This tool has been included and replaced by the SMART Documentation and Conversion Helper 2.0 tool, see the blog post here. The download link below points to SMART Documentation and Conversion Helper 2.0

If you have been reading about and testing the new features from System Center 2012 R2, you’ve probably heard about Service Management Automation (SMA), a new automation engine based on PowerShell Workflows and shipping as part of System Center 2012 R2 Orchestrator, along with the existing Orchestrator engine.

If you haven’t yet looked closely at SMA, fear not : My peers Charles Joy and Jim Britt have also blogged extensively about this feature in this blog post series. And we also highlighted this post from the Orchestrator & SMA team.

 

As you can probably guess, there is no easy way to “convert” an Orchestrator Runbook to a PowerShell Workflow for SMA, and you would likely take the “migration” as an opportunity to rework your Runbooks and optimize them for the new framework.

That being said, you might be interested in getting some semi-automated guidance to lay down the backbone for the new PowerShell Workflow. Especially if you are new to PowerShell or PowerShell Workflows. Things like:

  • Laying down the structure of your SMA Runbook based on the branches in the source Orchestrator Runbook : subroutines, “param”, “parallel” & “sequence” keywords,…
  • Pasting PowerShell in the SMA Runbook when a PowerShell script was found in the source Orchestrator Runbook
  • Pasting detailed information about non-PowerShell activities as comments

At the very least, having all details in a single PS1 file could provide a foundation that you can work with and tweak, and save a few copy/paste!

 

This leads me to the “SMART Runbook Conversion Helper” tool. Fully written in PowerShell, this solution is designed to help an Orchestrator user understand how Runbooks could be moved to SMA . It covers the previous scenarios, as well as others.

clip_image001

This post explains the capabilities of the tool, where to download it from and how to use it. If anything, you could also use this tool to document the structure and content of your Orchestrator Runbooks, similar to the work delivered in the Word documentation feature from the Orchestrator Visio and Word Generator (the two tools actually share some DNA).

The Runbook Conversion Helper is the second tool in the SMA Runbook Toolkit (SMART), after SMART for Runbook Import and Export by Jim Britt.

I hope you will find it useful, and am definitely interested in the feedback on this solution!

 

How does it work?

1. The tool lets you connect to an Orchestrator database and browse through available Runbooks

2. Once you have picked a Runbook, the “Export” button creates a PS1 file which can have two layouts:

    • Skeleton export” : Basically, this is the structure of the source Runbook branches and conditions in a PowerShell Workflow syntax, with “workflow”, “param”, “parallel”, “sequence” and the potential “if” conditions.
    • Full export” (default mode) : The same structure as “skeleton mode” is exported, but with details about all properties of all activities in the source Orchestrator Runbook. Specific parsing is done for Run .NET Script activities (including PowerShell), Initialize Data, Return Data, Schedules, Counters. For each properties, published data and variables are replaced by their actual display names (no GUIDs!), so you can easily relate to what they mean. At the bottom of the script, the tool provides a summary of variables, counters, schedules, initialize data activities, return data activities, loops, merging branches. That way, you have a list of items potentially worth investigating when porting your Runbook.

3. The tool also provides the option to open the PS1 file  automatically into PowerShell ISE for direct modifications

Sweet, where can I get it?

Note : The download link has been updated to point to the SMART Documentation and Conversion Helper 2.0 tool, which replaces this tool and this version. Actual blog post for the SMART Documentation and Conversion Helper 2.0 is here.

Orchestrator Visio and Word Generator 1.5

Installation and use

1. Copy SMA-RunbookConversionHelper.ps1 to any machine that has network access to an Orchestrator database

2. Right-click and “Run with PowerShell”

3. The Runbook to export can be chosen by double-clicking it in the folder hierarchy, or by clicking on the Export button. The PS1 file will be created in the same directory as the tool.

4. If you checked the “Open in ISE after conversion” option, ISE is opened to display the new file

The tool should be able to run on any machine, and without any parameters. By default, it will just time out if you do not have an Orchestrator DB locally (it defaults to localhost), and will give you the option to select another server in the GUI. You can also set the DB server via the command line (-DBServer switch), or in the script itself. Finally, the tool also remembers the last server used, thanks to a configuration file automatically saved/loaded.

Important note : Once again, remember the output PowerShell file is NOT ready to be imported right away into SMA. This is a helper and you do have to review the output and edit it. A very simple example would be the Orchestrator published data inside PowerShell scripts : The tool parses them and replaces them right inside the script, with lines like the two below, that you would have to update with PowerShell variables coming from other parts of the workflow or from a subroutine. Given how they are used in PowerShell, the use of curly bracket may not be the most adequate choice to surround variables and publish data in the ouput process, but it made sense to use them as this is how they are represented in Orchestrator.

$Cloud = Get-SCCloud -Name "{Variable:Deployment - VMM Cloud}"
New-SCVirtualMachine -ComputerTier $CT -Name "{Variable:Placement - Dedicated-NoHA-Instance - VM Prefix}-{Activity:Get New VM Number.PublishedData:newVMNb}.{Variable:General - Domain Name (FQDN)}"

Sample outputs

Orchestrator Runbook named “Manage Disk Free Space”:

Output in skeleton mode:

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
#################################################################################
# WORKFLOW CREATED BY THE SMA RUNBOOK CONVERSION HELPER
# This was created in 'Skeleton Mode', to only display
# the overall structure of the source Orchestrator Runbook
#################################################################################

workflow Invoke-1Managefreespace {

   
    Monitor Free Space Alert
   
   
    Delete File
   
   
    Get Disk Space Status
   
    Parallel {
        If ({Activity:Get Disk Space Status}.Percent-avail -lt "20") {
           
            Send Email
           
           
            Create Incident with Template
           
            }
        If ({Activity:Get Disk Space Status}.Percent-avail -ge "20") {
           
            Close Alert
           
            }
        }

}
#################################################################################

 

Orchestrator Runbook named “Deploy New Standalone Server w SQL”

 

clip_image002

Output in skeleton mode:

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
#################################################################################
# WORKFLOW CREATED BY THE SMA RUNBOOK CONVERSION HELPER
# This was created in 'Skeleton Mode', to only display
# the overall structure of the source Orchestrator Runbook
#################################################################################

workflow Invoke-DeployNewStandaloneServerwSQL {

      (
      [parameter(Mandatory=$true)]
      [String]$Instance_Name,
      [parameter(Mandatory=$true)]
      [String]$DB_Engine_Admin
         )

   
    Initialize Data
   
   
    Get Service
   
    Parallel {
        If ({Activity:Get Service}.Count -eq "0") {
           
            Inject Instance Name on File
           
            }
        If ({Activity:Get Service}.Count -eq "1") {
           
            Get New VM Number
           
            Parallel {
                Sequence {
                   
                    Send Platform Event
                   
                   
                    Scale Out Service
                   
                   
                    Send Platform Event (3)
                   
                   
                    Return Data
                   
                    }
               
                Inject Instance Name on File
               
                }
                }
        If ({Activity:Get Service}.Count -eq "0") {
           
            Send Platform Event (2) (2)
           
           
            Deploy Service Template
           
           
            Send Platform Event (2)
           
           
            Return Data
           
            }
        }

}
#################################################################################

Output in full mode:

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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#################################################################################
# WORKFLOW CREATED BY THE SMA RUNBOOK CONVERSION HELPER
# Make sure you review the summary analysis at the end of this file
# to make final adjustements to the runbook
#################################################################################

workflow Invoke-DeployNewStandaloneServerwSQL {

      (
      [parameter(Mandatory=$true)]
      [String]$Instance_Name,
      [parameter(Mandatory=$true)]
      [String]$DB_Engine_Admin
         )

   
    # START ACTIVITY - Initialize Data (Activity Type : Initialize Data)
    # Parameters were added in the workflow definition
    # Instance Name=> [String]$Instance_Name
    # DB Engine Admin=> [String]$DB_Engine_Admin
    # END ACTIVITY - Initialize Data
   
   
    # START ACTIVITY - Get Service (Activity Type : Get Service)
    # Configuration = sc-vmm2012sp1
    # Properties =
    # Filter : Service Name [equals] {Variable:Placement - Dedicated-NoHA-Instance - VMM Service Farm}
    # END ACTIVITY - Get Service
   
    Parallel {
        If ({Activity:Get Service}.Count -eq "0") {
           
            # START ACTIVITY - Inject Instance Name on File (Activity Type : Trigger Policy)
            # PolicyObjectID = {A500A175-6F9A-400C-87C8-7A5BE678BD92}
            # PolicyPath = Policies\SQL Server Provisioning\Subroutines\Other\Inject Instance Name on File
            # TriggerByPolicyPath = False
            # TargetActionServers =
            # WaitToComplete = False
            # Input parameter : Server Name = {Variable:Placement - Dedicated-NoHA-Instance - VM Prefix}-1
            # Input parameter : Instance Name = {Activity:Initialize Data.PublishedData:Instance Name}
            # END ACTIVITY - Inject Instance Name on File
           
            }
        If ({Activity:Get Service}.Count -eq "1") {
           
            # START ACTIVITY - Get New VM Number (Activity Type : Run .NET Script)
            # Script Type = PowerShell
             $newVMNb=Invoke-Command -Computer {Variable:General - VMM Server Name} -ScriptBlock {
           
            import-module virtualmachinemanager
            $result = Get-SCVMMServer -ComputerName "{Variable:General - VMM Server Name}"
            $nbVM = (get-VM | where-object {$_.name -match "{Variable:Placement - Dedicated-NoHA-Instance - VM Prefix}"}).count
            $newVMNb = $nbVM +1
            $newVMNb
            }
            # Published Data - Name : newVMNb / Type : String / Value : newVMNb -
            # END ACTIVITY - Get New VM Number
           
            Parallel {
                Sequence {
                   
                    # START ACTIVITY - Send Platform Event (Activity Type : Send Platform Event)
                    # EventType = information
                    # EventSummary = Scaling out SQL Farm for dedicated databases/instances
                    # EventDetails =
                    # END ACTIVITY - Send Platform Event
                   
                   
                    # START ACTIVITY - Scale Out Service (Activity Type : Run .NET Script)
                    # Script Type = PowerShell
                     $result=Invoke-Command -Computer {Variable:General - VMM Server Name} -ScriptBlock {
                   
                    import-module virtualmachinemanager
                    $result = Get-SCVMMServer -ComputerName "{Variable:General - VMM Server Name}"
                    $Svc = Get-SCService -name "{Variable:Placement - Dedicated-NoHA-Instance - VMM Service Farm}"
                    $CT = Get-SCComputerTier -Service $Svc
                    New-SCVirtualMachine -ComputerTier $CT -Name "{Variable:Placement - Dedicated-NoHA-Instance - VM Prefix}-{Activity:Get New VM Number.PublishedData:newVMNb}.{Variable:General - Domain Name (FQDN)}"
                    }
                    # Published Data - None
                    # END ACTIVITY - Scale Out Service
                   
                   
                    # START ACTIVITY - Send Platform Event (3) (Activity Type : Send Platform Event)
                    # EventType = information
                    # EventSummary = VM {Variable:Placement - Dedicated-NoHA-Instance - VM Prefix}-{Activity:Get New VM Number.PublishedData:newVMNb} was added to the farm
                    # EventDetails =
                    # END ACTIVITY - Send Platform Event (3)
                   
                   
                    # START ACTIVITY - Return Data (Activity Type : Return Data)
                    # DeploymentStatus = Success
                    # VMName = {Variable:Placement - Dedicated-NoHA-Instance - VM Prefix}-{Activity:Get New VM Number.PublishedData:newVMNb}
                    # END ACTIVITY - Return Data
                   
                    }
               
                # START ACTIVITY - Inject Instance Name on File (Activity Type : Trigger Policy)
                # PolicyObjectID = {A500A175-6F9A-400C-87C8-7A5BE678BD92}
                # PolicyPath = Policies\SQL Server Provisioning\Subroutines\Other\Inject Instance Name on File
                # TriggerByPolicyPath = False
                # TargetActionServers =
                # WaitToComplete = False
                # Input parameter : Instance Name = {Activity:Initialize Data.PublishedData:Instance Name}
                # Input parameter : Server Name = {Variable:Placement - Dedicated-NoHA-Instance - VM Prefix}-{Activity:Get New VM Number.PublishedData:newVMNb}
                # END ACTIVITY - Inject Instance Name on File
               
                }
                }
        If ({Activity:Get Service}.Count -eq "0") {
           
            # START ACTIVITY - Send Platform Event (2) (2) (Activity Type : Send Platform Event)
            # EventType = information
            # EventSummary = Creating SQL Farm for dedicated databases/instances
            # EventDetails =
            # END ACTIVITY - Send Platform Event (2) (2)
           
           
            # START ACTIVITY - Deploy Service Template (Activity Type : Run .NET Script)
            # Script Type = PowerShell
             $result=Invoke-Command -Computer {Variable:General - VMM Server Name} -ScriptBlock {
           
            import-module virtualmachinemanager
            $result = Get-SCVMMServer -ComputerName "{Variable:General - VMM Server Name}"
            $Cloud = Get-SCCloud -Name "{Variable:Deployment - VMM Cloud}"
            $ST= Get-SCServiceTemplate -Name "{Variable:Deployment - VMM Service Template for SQL Farm}"
            $ServiceConfig = New-SCServiceConfiguration -ServiceTemplate $ST -Name "{Variable:Placement - Dedicated-NoHA-Instance - VMM Service Farm}" -Cloud $Cloud -Description "This is a test"
            $NewService = New-SCService -ServiceConfiguration $ServiceConfig
            }
            # Published Data - None
            # END ACTIVITY - Deploy Service Template
           
           
            # START ACTIVITY - Send Platform Event (2) (Activity Type : Send Platform Event)
            # EventType = information
            # EventSummary = VM {Variable:Placement - Dedicated-NoHA-Instance - VM Prefix}-1 was added to the farm
            # EventDetails =
            # END ACTIVITY - Send Platform Event (2)
           
           
            # START ACTIVITY - Return Data (Activity Type : Return Data)
            # VMName = {Variable:Placement - Dedicated-NoHA-Instance - VM Prefix}-1
            # DeploymentStatus = Success
            # END ACTIVITY - Return Data
           
            }
        }

}
########################### CONVERSION HELPER SUMMARY ###########################
# RUNBOOK START : Starting activity in the source Runbook is an Initialize Data activity. Actual parameters have been added at the beginning of the resulting workflow. Spaces in the parameters' names have been replaced by underscore characters.
# VARIABLES : Variables were found in the source Runbook and should be replaced by SMA variables. Here is the list of variables discovered, and how many times they were used in the source Runbook :
# - {Placement - Dedicated-NoHA-Instance - VMM Service Farm} (x3) - Current Value = SQL Farm 01
# - {Placement - Dedicated-NoHA-Instance - VM Prefix} (x8) - Current Value = DEMO-SQL
# - {General - VMM Server Name} (x6) - Current Value = sc-vmm2012sp1
# - {General - Domain Name (FQDN)} (x1) - Current Value = ad.corp.local
# - {Deployment - VMM Cloud} (x1) - Current Value = Cloud for Red BU
# - {Deployment - VMM Service Template for SQL Farm} (x1) - Current Value = SQL Server Farm
# SUBROUTINES : Subroutines are involved through Invoke Runbooks activities in the source Orchestrator Runbook. You would likely replace these subroutines by SMA subroutine Runbooks. Here is the list of invoked Runbooks discovered, and how many times they were called by the source Runbook :
# - Inject Instance Name on File (x2)
# OUTUT DATA : Return Data activities are used in the source Orchestrator Runbook. Properties returned are embedded earlier in the script. Here is a list of names for the corresponding activities, and how many times they were called by the source Runbook :
# - Return Data (x2)
# SCHEDULES : No Check Schedule activities were used in this source Runbook.
# COUNTERS : No Counter-related activities were used in this source Runbook.
# PARALLEL BRANCHES : The following activities had multiple outbound links. These have been added to the script as 'parallel' script paragraphs, but you might also want to look if the use of 'parallel' is actually needed or could be optimized.
# - Get Service
# - Get New VM Number
# LINK CONDITIONS : No string conditions were used in this source Runbook's links.
# LOOPS : If there are loops within the source Runbooks, they are listed below, and you may also need to look at the exit/non-exit conditions to convert them:
# MERGING BRANCHES : If there are activities with multiple inbound branches, they are listed below and the script output may be simplified (right now it duplicates code for each branch, in this situation)
# JUNCTIONS : No junctions were used in this source Runbook.
#################################################################################