System Center 2012 SP1 – Orchestrator: Disk Maintenance and Runbooks

Welcome back, in this post we will continue where we left off on our last post on System Center 2012 Sp1 – Orchestrator and disk maintenance, completing our remaining runbooks and adding in some PowerShell to assist in the process.

With the Archive runbook already created, in this second post, we will guide our way through the remaining three runbooks needed to complete the project.

System Center 2012 SP1 – Orchestrator: Purge Files Runbook

The second runbook I create will be called 2.3 Purge Files. This runbook will accept the details of the purge job, including the source and age of the files for purging.

On the canvas I will place and hook up the following:

  • Add an Initialize Data activity to accept in the parameters for the job.
  • Next, I use a Run .NET Script activity to do the actual archival, which I rename to Purge Files.
  • And finally I will add two Return Data activities, first for a successful execution, which I rename to Success. Second, for a failed execution that I also rename, this time to Failure.

System Center 2012 SP1 - Orchestrator: Disk Maintenance and Runbooks

Starting with the Initialize Data Activity I configure the following properties:

  • Details page (Add three parameters as follows)
    • Name: SourcePath, Type: String
    • Name: SourceMask, Type: String
    • Name: Age, Type: Integer

Next, on my Purge Files activity I define the following setting:

    • Details page
      • Language Type: Powershell
      • Script:
      $groomingFolder = {SourcePath from “Initialize Data”}{SourceMask from “Initialize Data”}
      $groomingAge = {Age from “Initialize Data”}
      
      function Remove-Files {
      <#
      .SYNOPSIS
         This function will Remove files from your file system based on some simple paramaters
      .DESCRIPTION
      
      .PARAMETER 
      
      .EXAMPLE 
         Delete-Files \\UNC\Path -Recursive -RemoveFolders -DaysOld 30 -Testing 
      #> 
         [cmdletbinding()]
         param(
            [Parameter(Mandatory = $true, Position = 0, ValueFromPipeLine= $true)] 
            [string]$Path,              
      	  [Parameter(Mandatory = $False)] 
            [switch]$Recursive,
      	  [Parameter(Mandatory = $False)] 
            [switch]$RemoveFolders,
      	  [Parameter(Mandatory = $False)] 
            [switch]$Testing,
      	  [Parameter(Mandatory = $False)] 
            [int]$DaysOld = 0              
      	)
          begin {
              $Now = Date
              $LastWrite = $Now.AddDays(-$DaysOld); 
              Write-Verbose ("Starting Script...")
              Write-Verbose ("We will remove Files older than $DaysOld from the file System - Last Updated After $LastWrite ")
              if ($Recursive) { Write-Verbose ("We will Recurse trough the file System") }
              if ($RemoveFolders) { Write-Verbose ("We will Remove Folders as well as Files") }
              if ($Testing) { Write-Verbose ("Running in TEST MODE") }
              Write-Verbose ("Process starting at $Path")
          }
          process {
              if($Testing) {
                 get-childitem $Path -Recurse:$Recursive | ? {$_.LastWriteTime -le "$LastWrite"} | ? {$_.PSIsContainer -eq $RemoveFolders} | select name, length 
              } else {
                  get-childitem $Path -Recurse:$Recursive | ? {$_.LastWriteTime -le "$LastWrite"} | ? {$_.PSIsContainer -eq $RemoveFolders} | Remove-Item
              }
          }
      }
      
      $error.clear()
      
      Remove-Files -Path $groomingFolder -Recursive -DaysOld $groomingAge
      
      $error
      • Published Data page
        • Name = Error, Type = String, Variable Name = Error

      Finally, Select the Pipeline/Link from the Purge Files activity to the Failure activity, and set its properties

      • Include Page
        • Click on the entry Success and from the Results dialog select the option Warning and Failed and clear the option Success then click OK
      • Options Page
        • Set the Colour to Red

Job Enumeration Runbook

The next runbook I create will be called 2.1 Enumerate Maintenance Plan. This runbook will connect to our SQL table, and gather the list of tasks for orchestrator to process.

To implement this I am going to defined the following

  • First, a Run .NET Script activity will be used to store the configuration details of where our table is stored so that we can pass this detail to the pipeline. I do this because I am not a fan of the Global Variables settings in Orchestrator, especially when importing and exporting runbooks.
  • Second, we will connect to the SQL Server with a Query Database activity, and return the results to the pipeline.
  • I will then add two Invoke Runbook activities to the canvas. The first we will rename to Archive runbook. The other we will rename to Purge runbook. Finally, I will add a Junction activity to have all the flows get to this point before finally completing the runbook with a Return Data activity.

Once I have all the activities on the canvas, connect the links as described in the plan.

System Center 2012 SP1 - Orchestrator: Disk Maintenance and Runbooks

Starting with the Run .NET Activity, rename the activity to Maintenance Variables, and then
configure its properties similar to the following:

  • Details page
    • Language Type = PowerShell
    • Script :
    $SQLServer = "PDC-DB-SQL01"
    $SQLDatabase = "ITServices"
    $SQLTable = "ITStorageMaintenancePlan"
  • Published Data page
    • Name = SQL Server, Type = String, Variable Name = SQLServer
    • Name = SQL Database, Type = String, Variable Name = SQLDatabase
    • Name = SQL Table, Type = String, Variable Name = SQLTable

    Next, on the Query Database activity

  • Connection page
    • Database Type = SQL Server
    • Authentication = Windows Authentication
    • Server = {SQL Server from “Maintenance Variables”}
    • Initial Catalog = {SQL Databse from “Maintenance Variables”}
  • Details Page
      • Query

    SELECT [SourcePath], [SourceMask], [Action], [Age], [TargetPath] FROM [ITStorageMaintenancePlan]

Select the Pipeline/Link from the Query Database activity to the Archive Files activity, and set its properties

Include Page:
  • Click on the entry Query Database and from the Published Data dialog, select the option Full line as a string with fields separated by a “;”. Then click OK.
  • Click on the entry equals and from the Conditions dialog select the option Contains then click OK.
  • Click on the entry Value and in the Data dialog enter ;Archive; then click OK.
General Page:
  • Set the name to Archive Job.

In a similar fashion, we will now configure the other link for Purge Jobs, begin by selecting the Pipeline/Link from the Query Database activity to the Purge Files activity, and set its properties.

Include Page:
  • Click on the entry Query Database and from the Published Data dialog, select the option Full line as a string with fields separated by a “;”. Then click OK.
  • Click on the entry equals and from the Conditions dialog select the option Contains then click OK.
  • Click on the entry Value and in the Data dialog enter ;Purge; then click OK.
General Page:
  • Set the name to Purge Job.

Select our Archive runbook activity, and set its properties

Details Page:
  • Runbook = Use the ‘…’ button to browse and select the Archive Runbook.
  • Enable the check box on the setting Wait for completion.
  • Set the parameters as follows:
    • SourceMask = [Field({Full line as a string with fields separated by a ‘;’ from “Query Database” },’;’,2)]
    • SourcePath = [Field({Full line as a string with fields separated by a ‘;’ from “Query Database” },’;’,1)]
    • TargetPath = [Field({Full line as a string with fields separated by a ‘;’ from “Query Database” },’;’,5)]
    • Age = [Field({Full line as a string with fields separated by a ‘;’ from “Query Database” },’;’,4)]

Similarly, we can now also set the properties of the Purge runbook

Details Page:
  • Runbook = Use the ‘…’ button, to browse and select the Purge Runbook.
  • Enable the check box on the setting Wait for completion.
  • Set the parameters as follows
    • SourceMask = [Field({Full line as a string with fields separated by a ‘;’ from “Query Database” },’;’,2)]
    • SourcePath = [Field({Full line as a string with fields separated by a ‘;’ from “Query Database” },’;’,1)]
    • Age = [Field({Full line as a string with fields separated by a ‘;’ from “Query Database” },’;’,4)]

Trigger Runbook

The final runbook we are going to create is the trigger flow runbook. This will use a monitor style activity to trigger the main Job Enumeration runbook based on a time/date event, essentially a scheduled start. I am calling this runbook Monitor – 2. Trigger Disk Maintenance.

We will drag two activities to the canvas: a Monitor Date/Time activity followed by the Invoke Runbook Activity, which we will rename to Start Job Enumeration.

With these on the canvas we can create a simple link to connect these together.

System Center 2012 SP1 - Orchestrator: Disk Maintenance and Runbooks

On the Properties of the Monitor Date/Time activity

Details Page:
  • Interval = Set this to a suitable period, for example AT 01:15 AM, to trigger nightly.

Select our Start Enumerate Maintenance Plan activity and set its properties.

Details Page:
  • Runbook = Use the ‘…’ button to browse and select the runbook 2.1 Enumerate Maintenance Plan.
  • Enable the check box on the setting Wait for completion.

Conclusion

Cool right? Over the last two posts we have created a very simple implementation with no logging or error handling, but have learned how to use different activities to run our jobs. In this post we also leveraged Powershell as part of one of the runbooks simply to illustrate the ease of mixing these technologies.

Go ahead and build this out in your test environment, and ill look forward to your comments. In the next post we will try another solution, until then – happy automations!