Search code examples
powershellazureazure-automation

How are exported Azure Automation Graphical Runbook definition (.graphrunbook) encoded/encrypted?


This is the (trimmed) content of a .graphrunbook after Exported from the Azure Portal.

{ 
    "SchemaVersion" : "1.2", 
    "RunbookDefinition" : "AAA....AAA=" 
}

The runbook definition is presumably XML- or XAML-based, and while this looks like base64 encoded text, decoding it as such results in large portions that are still encoded/illegible.

Context: I'm working on a revamped version of the Sync-VsoGitRunbook that works with ARM, doesn't require an arbitrary folder hierarchy (by automatically determining dependencies), and can deploy graphical runbooks as well - because why not! This is all pretty much wrapped up for Native & Workflow, these are just the last piece to implement.

I'm not using any graphical runbooks currently, but if/once we do, I want them to fall in line with the architecture. I'm also planning on open-sourcing the code once I get it wrapped/cleaned up.


Solution

  • Using the Azure Automation Graphical Authoring SDK is the only supported way of inspecting and modifying the content of .graphrunbok files. For example, a script like this will give you a list of commands used by the runbook:

    param(
        [Parameter(Mandatory = $true)]
        $RunbookPath,
    
        $GraphicalAuthoringSDKPath = 'C:\Program Files (x86)\Microsoft Azure Automation Graphical Authoring SDK'
    )
    
    function Get-RunbookActivities($Runbook, $ActivityType)
    {
        $Runbook.Activities | %{ $_ -as $ActivityType } | ?{ $_ }
    }
    
    Add-Type -Path $GraphicalAuthoringSDKPath\Orchestrator.GraphRunbook.Model.dll
    
    $SerializedRunbook = Get-Content $RunbookPath
    
    $Runbook = [Orchestrator.GraphRunbook.Model.Serialization.RunbookSerializer]::Deserialize($SerializedRunbook)
    
    @{
        'Invoked runbooks' = Get-RunbookActivities $Runbook Orchestrator.GraphRunbook.Model.InvokeRunbookActivity |
                                %{ $_.RunbookActivityType.CommandName }
    
        'Commands' = Get-RunbookActivities $Runbook Orchestrator.GraphRunbook.Model.CommandActivity |
                                %{ "$($_.CommandType.ModuleName)/$($_.CommandType.CommandName)" }
    
        'Code activity content' = Get-RunbookActivities $Runbook Orchestrator.GraphRunbook.Model.WorkflowScriptActivity |
                                %{ $_.Process }
    }
    

    The data provided by this script is incomplete: it lists only activities shown as boxes on the runbook diagram. However, there are other ways to introduce PS code into runbooks (such as link conditions, retry conditions, PS expressions in activity parameters, etc.) If you are interested in this data as well, the script can be improved: all the data stored in a graphical runbook can be retrieved using this API.

    Please download the latest version of the SDK from the link provided by Chris. The latest version contains some important fixes.