Thursday, May 17, 2018

Invoke WFA workflow with PowerShell

It was brought to my attention that I never really posted the Powershell code to invoke a workflow.  It seemed so elementary, and I tend to use it in many scripts, that I simply forgot.

So here are  2 simple functions to list workflows and to invoke a workflow.




Get list of workflows

function Get-WfaWorkflows {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$True,HelpMessage="The Url of the wfa-server")]
        [string]$url,
        
        [Parameter(Mandatory=$True,HelpMessage="Your credentials")]
        [pscredential]$credentials
    )

    # Force TLS
    [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

    # Find RESTful execution url for WFA workflow
    [string]$restCommand = $url + "/rest/workflows" 

    logInfo "Getting workflow information..."

    try {
        $output = Invoke-RestMethod -Method Get -Uri $restCommand -Credential $credentials
    } catch {
        write-warning "Could not find wfa-server, or access denied"
        return
    }

    $output.collection.workflow
}

Invoke a single workflow

function Invoke-WfaWorkflow {
    param(
        [Parameter(Mandatory=$true,HelpMessage="The Url of the workflow-server",ParameterSetName = "Set 1")]
        [parameter(Mandatory=$true,HelpMessage="The Url of the workflow-server",ParameterSetName = "Set 2")]
        [string]$url,
        
        [Parameter(Mandatory=$True,HelpMessage="The name of the workflow",ParameterSetName = "Set 1")]
        [parameter(Mandatory=$True,HelpMessage="The name of the workflow",ParameterSetName = "Set 2")]
        [string]$workflowName,

        [Parameter(Mandatory=$True,HelpMessage="Your credentials",ParameterSetName = "Set 1")]
        [parameter(Mandatory=$True,HelpMessage="Your credentials",ParameterSetName = "Set 2")]
        [pscredential]$credentials,

        [Parameter(Mandatory=$True,HelpMessage="The path to a json input file",ParameterSetName = "Set 1")]
        [string]$jsonPath,

        [Parameter(Mandatory=$True,HelpMessage="A json input string",ParameterSetName = "Set 2")]
        [string]$jsonInput
    )

    # Force TLS
    [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

    # Find RESTful execution url for WFA workflow
    $restCommand = $url + "/rest/workflows/?name=$workflowName" 

    write-host -foregroundcolor magenta "Getting Workflow information..."
    write-host -ForegroundColor cyan "Name : $workflowName"

    try {
        $output = Invoke-RestMethod -Method Get -Uri $restCommand -Credential $credentials
        
    } catch {
        write-warning -foregroundcolor yellow "Could not find workflow-server, no such workflow or access denied"
        write-warning -foregroundcolor yellow $_
        return
    }

    $workflow_execution_uri = ($output.collection.workflow.link | ?{$_.rel -eq 'execute'}).href

    # Initiate workflow execution
    try{
        write-host -foregroundcolor magenta "Executing workflow $workflowName"
        if($jsonPath){
            try{
                $jsonInput = Get-Content $jsonPath
            }catch{
                write-warning -foregroundcolor yellow "Invalid jsonpath"
                write-warning -foregroundcolor yellow $_
                return
            }
        }
        $output = Invoke-RestMethod -Method Post -Uri $workflow_execution_uri -Credential $credentials -Body $jsonInput -ContentType "application/json"
    }catch{
        write-warning -foregroundcolor yellow "Could not find workflow-server, no such workflow or access denied"
        write-warning -foregroundcolor yellow $_
        return
    }

    # Find RESTful job monitoring link for WFA workflow
    $job_status_uri = ($output.job.link | ?{$_.rel -eq 'self'}).href
    if ($job_status_uri.Count -gt 1){$job_status_uri = $job_status_uri[0]}

    # Wait until workflow job either completes successfully or fails
    $prev_status=""
    do {
        Start-Sleep -Seconds 2
        $output = Invoke-RestMethod -Method Get -Uri $job_status_uri -Credential $credentials
        $jobStatus = $output.job.jobStatus.jobStatus
        if($prev_status -ne $jobStatus){
            write-host -ForegroundColor cyan "status : $jobStatus"
        }
        $prev_status = $jobStatus
    } while (($jobStatus -ne "COMPLETED") -and ($jobStatus -ne "FAILED"))
    
    $o = @{jobStatus = $jobStatus}
    if($output.job.jobStatus.returnParameters.returnParameters -ne $null){
        $o.returnParameters = @{}
        foreach($r in $output.job.jobStatus.returnParameters.returnParameters){
            $key = $r.key
            $value = $r.value
            $o.returnParameters."$key" = $value
        }
    }
    if($output.job.jobStatus.errorMessage -ne $null){
        $o.errorMessage = $output.job.jobStatus.errorMessage
    }
    New-Object -TypeName psobject -Property $o
}

json example

$json = @"
{
    "comments":"triggered by rest",
    "userInputValues":[
        {
            "key":"ClusterName",
            "value":"$cluster_name"
        },
        {
            "key":"SvmName",
            "value":"$svm_name"
        },
        {
            "key":"VolumeName",
            "value":"$volume_name"
        },
        {
            "key":"VolumeSizeUsedMB",
            "value":"$volume_size"
        }
    ]
}
"@

1 comment :