Invoking Orchestrator 2019 Runbook from Windows Powershell

Adarsh 1 Reputation point
2022-04-08T12:43:11.333+00:00

My requirement is to invoke an orchestrator runbook through Windows PowerShell. I followed the below links to create the PowerShell script:

http://www.laurierhodes.info/?q=node/101
https://learn.microsoft.com/en-us/answers/questions/417562/trigerring-powershell-script-via-orchestrator-webs.html

My script:

# Powershell Example of calling an Orchestrator Runbook  
# and retrieving the runbook output   

#Credentials  
$secpasswd = ConvertTo-SecureString "password" -AsPlainText -Force  
$mycreds   = New-Object System.Management.Automation.PSCredential ("username", $secpasswd)  

#Orchestrator Server Hostname  
$OrchServer = "scorchvm1"  

# Runbook to be called with an example Property and Value  
$RunBookName          = "Test"  
$RunbookInputProperty = "Short Description"  
$RunbookInputValue    = "PC12345"  

#Begin ################  

cls  
# First Grab the GUID of the desired runbook  

$OrchURI        = "http://$($OrchServer):81/Orchestrator2012/Orchestrator.svc/Runbooks?`$filter=Name eq '$RunBookName'"   
$ResponseObject = invoke-webrequest -Uri $OrchURI -method Get -Credential $mycreds   
$XML            = [xml] $ResponseObject.Content  
$RunbookGUIDURL = $XML.feed.entry.id  

write-host "Runbook GUID URI = " $RunbookGUIDURL  

# User the runbook GUID to retrieve GUID values for Input Properties  
# This example will retrieve an input property titled "Input1" as set in the variables  
# in the header of this script  

$ResponseObject = invoke-webrequest -Uri "$($RunbookGUIDURL)/Parameters" -method Get -Credential $mycreds   
[System.Xml.XmlDocument] $XML = $ResponseObject.Content  

# A runbook contains a number of properties for the inputs and results returned from that runbook.  
# All values within the returned XML need to be parsed to find which elements are Input properties  
# with the desired name.  Once found, the "Id" or GUID for that particular property must be returned.  

function GetScorchProperty([System.Object]$XMLString, [string]$Name, [string]$Direction, [string]$DesiredData){  

   $nsmgr = New-Object System.XML.XmlNamespaceManager($XMLString.NameTable)      
   $nsmgr.AddNamespace('d','http://schemas.microsoft.com/ado/2007/08/dataservices')  
   $nsmgr.AddNamespace('m','http://schemas.microsoft.com/ado/2007/08/dataservices/metadata')  


   # Create an Array of Properties based on the 'Name' value  

    $inputs = $XMLString.SelectNodes('//d:Name',$nsmgr)  

   foreach ($parameter in $inputs){  
      # Each 'Name' has related elements at the same level in XML  
      # So the parent node is found and a new array of siblings   
      # is created.  

      #Reset Property values   
      $obName          =""  
      $obId            =""  
      $obType          =""  
      $obDirection     =""  
      $obDescription   =""  

      $siblings = $($parameter.ParentNode.ChildNodes)  

      # Each of the sibling properties is identified  
      foreach ($elements in $siblings){  
      # write-host "Element = " $elements.ToString()  
          If ($elements.ToString() -eq "Name"){  
            $obName = $elements.InnerText  
          }     
          If ($elements.ToString() -eq "Id"){  
             $obId = $elements.InnerText  
          }  
          If ($elements.ToString() -eq "type"){  
             $obType = $elements.InnerText  
          }  
          If ($elements.ToString() -eq "Direction"){  
             $obDirection = $elements.InnerText  
          }  
         If ($elements.ToString() -eq "Description"){  
            $obDescription = $elements.InnerText  
         }  
         If ($elements.ToString() -eq "Value"){  
           # write-host "Value = "$elements.InnerText  
            $obValue = $elements.InnerText  
         }  
       }  

        if (($Name -eq $obName) -and ($Direction -eq $obDirection)){  
          # "Correct input found"  
          #Return the Requested Property  

         If ($DesiredData -eq "Id"){  
            return $obId   
         }  
         If ($DesiredData -eq "Value"){  
            return $obValue  
         }  
          }  
   }  
   return $Null  
}  

#The Function is called to retreive the "Id" Property  
# This occurs by:  
# + Passing in an XML object  
# + Specifying the name of the propery being searched for (Input1)  
# + Specifying that the runbook property is an "In" direction property  
# + Specifying that the element neded for that property is the GUID based Id  

$RetreivedGUID = GetScorchProperty $XML $RunbookInputProperty "In" "Id"  
write-host "Property GUID = " $RetreivedGUID  

# Derive the Runbook GUID  
$urlstring = $RunbookGUIDURL  
#    eg.     "http://server2012:81/Orchestrator2012/Orchestrator.svc/Runbooks(guid'c88ca155-e067-4f37-9723-ef977ac74047')"  

$RunbookID = $RunbookGUIDURL.Substring($RunbookGUIDURL.Length - 38,36)  
write-host "RunbookID = " $RunbookID   

# Submitting an Orchestrator Request requires a POST to call a runbook based on its GUID Id value  
# Values for required inputs are submitted alongside Property GUIDs  
# The XML structure of the data section will resemble:  
#  
# <Data>  
# <Parameter>  
#   <ID></ID>  
#   <Value></Value>  
# </Parameter>  
# <Parameter>  
#   <ID></ID>  
#   <Value></Value>  
# </Parameter>  
# </Data>  
#  
# The XML structure uses HTML special entities to represent greater than & less than chracters.  

$POSTBody = @"  
<?xml version="1.0" encoding="utf-8" standalone="yes"?>  
<entry xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/Atom">  
<content type="application/xml">  
<m:properties>  
<d:RunbookId type="Edm.Guid">{$($RunbookID)}</d:RunbookId>  
<d:Parameters>&lt;Data&gt;&lt;Parameter&gt;&lt;ID&gt;{$($RetreivedGUID)}&lt;/ID&gt;&lt;Value&gt;$($RunbookInputValue)&lt;/Value&gt;&lt;/Parameter&gt;&lt;/Data&gt;</d:Parameters>  
</m:properties>  
</content>  
</entry>  
"@  


# Submit Orchestrator Request  
$OrchURI = "http://$($OrchServer):81/Orchestrator2012/Orchestrator.svc/Jobs/"  
write-host "POST request URI " $OrchURI   

$ResponseObject = invoke-webrequest -Uri $OrchURI -method POST -Credential $mycreds -Body $POSTBody -ContentType "application/atom+xml"   

#Retrieve the Job ID from the submitted request  
$XML               = [xml] $ResponseObject.Content  
$RunbookJobURL     = $XML.entry.id  

write-host "Runbook Job URI " $RunbookJobURL  

# Runbooks will take some time to complete  
# This example ues a simple loop to check if the job is still running  
# a production script would use more error handling to ensure that the runbook hadn't failed  

$status = $xml.entry.content.properties.Status  
write-host "Current Status = " $status  

do  
{  
    if($status -eq "Pending")  
    {  
        start-sleep -second 5  
        $SleepCounter = $SleepCounter + 1  
            if($SleepCounter -eq 20)  
            {  
                $DoExit="Yes"  
            }  
    }  
    Else  
    {  
        $DoExit="Yes"  
    }  

    # Query the web service for the current status  
     $ResponseObject = invoke-webrequest -Uri "$($RunbookJobURL)" -method Get -Credential $mycreds   
     $XML      = [xml] $ResponseObject.Content  
     $RunbookJobURL = $XML.entry.id  
     $status = $xml.entry.content.properties.Status  
     write-host "Current Status = " $status  
}While($DoExit -ne "Yes")  


# As the runbook is no longer active, query the Instance of the submitted job  
$ResponseObject = invoke-webrequest -Uri "$($RunbookJobURL)/Instances" -method Get -Credential $mycreds   

#Retrieve the Instance ID  
$XML                = [xml] $ResponseObject  
$RunbookInstanceURL = $XML.feed.entry.id  
write-host "Runbook Instance URI " $RunbookInstanceURL  

#The Instance can be used to retrieve the Parameters for the particular job  
$ResponseObject                 = invoke-webrequest -Uri "$($RunbookInstanceURL)/Parameters" -method Get -Credential $mycreds   
[System.Xml.XmlDocument] $xml   = $ResponseObject.Content  

#The parameters can be again parsed with the earlier function  
# This occurs by:  
# + Passing in an XML object  
# + Specifying the name of the propery being searched for (Result)  
# + Specifying that the runbook property is an "Out" direction property  
# + Specifying that the element neded for that property is the "Value" of the property  

$RunbookResult                   = GetScorchProperty $xml "Result" "Out" "Value"  

write-host "Runbook Result " $RunbookResult  

When I ran this script, I got the following result:

Runbook GUID URI = http://scorchvm1:81/Orchestrator2012/Orchestrator.svc/Runbooks(guid'26a6f904-8cef-42fa-876b-c0306bf40a57')
Property GUID = 0d829251-ca42-4e81-b11a-ca0fefb08f41
RunbookID = 26a6f904-8cef-42fa-876b-c0306bf40a57
POST request URI http://scorchvm1:81/Orchestrator2012/Orchestrator.svc/Jobs/
Runbook Job URI http://scorchvm1:81/Orchestrator2012/Orchestrator.svc/Jobs(guid'48730b49-a799-4710-bbcb-2b87f7f4545c')
Current Status = Pending
Current Status = Pending
Runbook Instance URI
invoke-webrequest : Invalid URI: The hostname could not be parsed.
At line:203 char:35

  • ... = invoke-webrequest -Uri "$($RunbookInstanceURL)/Parameters ...
  • ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  • CategoryInfo : NotSpecified: (:) [Invoke-WebRequest], UriFormatException
  • FullyQualifiedErrorId : System.UriFormatException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand

Runbook Result

I'm able to open the URIs on the browser but fails in PowerShell. Please assist
Thanks

System Center Orchestrator
System Center Orchestrator
A family of System Center products that provide an automation platform for orchestrating and integrating both Microsoft and non-Microsoft IT tools.
219 questions
Windows Server PowerShell
Windows Server PowerShell
Windows Server: A family of Microsoft server operating systems that support enterprise-level management, data storage, applications, and communications.PowerShell: A family of Microsoft task automation and configuration management frameworks consisting of a command-line shell and associated scripting language.
5,462 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Rich Matheisen 45,906 Reputation points
    2022-04-08T18:28:35.737+00:00

    On line #200 of your script I see write-host "Runbook Instance URI " $RunbookInstanceURL, but in the output you provided:

    Runbook Instance URI

    Appears right before the invoke-webrequest : Invalid URI: The hostname could not be parsed.. Note that there's no value displayed where you'd expect to see the URL contained in the $RunbooInstanceURL variable.

    0 comments No comments