Archive for the ‘workflows’ Tag

High Availability for Runbook Servers on Invoking Runbooks   Leave a comment

I’ve moved everything from this blog over to jmattivi.blogspot.com and updated all of the scripts to have straight quotes.  If any don’t work as posted, please let me know!

For further posts please see jmattivi.blogspot.com.

Thanks!

 

Here’s just a quick tidbit for specifying runbook servers used in the Invoke Runbook standard activity.  It’s beneficial to keep the runbook server names stored in Global Variables.  This way you can insert the variable in the Invoke Runbook activity instead of hardcoding the server name.

In case a runbook server has issues and is powered down or unavailable, the invoke runbook activity will automatically start the invoked runbook on the next runbook server in line.  Another benefit is the ability to add/remove runbook servers and just update a variable than trying to find/replace every invoke runbook activity w/ the new server name.

You can also use the variables to group runbook servers based on their role in the environment.  So to load balance runbooks, depending on how many runbook servers you have (for this example we’ll say three internal).  You could specify three variables which have the following values.

Primary:  myrunbookserver1;myrunbookserver2;myrunbookserver3

Secondary:  myrunbookserver2;myrunbookserver3;myrunbookserver1

Tertiary:  myrunbookserver3;myrunbookserver1;myrunbookserver2

So for runbook servers interacting w/ servers on an internal domain you could use:

So for runbook servers interacting w/ servers on a dmz domain you could use:

Finally, subscribe to the variable in the Invoke Runbook activity.

Implementing SSL on the OC and Web Service   Leave a comment

I’ve moved everything from this blog over to jmattivi.blogspot.com and updated all of the scripts to have straight quotes.  If any don’t work as posted, please let me know!

For further posts please see jmattivi.blogspot.com.

Thanks!

 

This post I’ll explain how to setup SSL on the Orchestration Console (OC) and Web Service (WS) while also redirecting http traffic to https.  For these examples, I’ve setup the OC on port 443 and the WS on 8443.

Since the OC and WS are now hosted through IIS, all the settings will be set through IIS.  First off you need to setup the bindings on the sites for each like below.  I’ll explain in a bit why we want to leave 80 enabled in the bindings.

Orchestration Console Bindings

Within the https port from Edit, you can upload and select the cert you wish to use on the server from the drop down list.

Web Service Bindings

Now that the OC and WS are enabled for https, we need to setup redirection from port 80 over to port 443 on the Orchestration Console.  Based on what was previously done, we only need to do this for the OC since the WS is only enabled for port 8443.  For a great resource on the redirection, see this link that explains how to do this using the URL Rewrite tool – http://www.jppinto.com/2010/03/automatically-redirect-http-requests-to-https-on-iis7-using-url-rewrite-2-0/.

To have the redirection work successfully using the URL Rewrite tool, it’s necessary that the SSL settings are left at the default NOT to require SSL on the OC.  This allows the traffic to hit port 80 and then the redirection will kick in.  This is why port 80 is left on the bindings as well.

Finally, we need to edit the OC’s web.config file with the new “https://” address and fqdn path of the WS.  You can also see at the bottom of the screenshot below where the URL Rewrite tool adds the redirection.

If you don’t edit the OC’s web.config file, you’ll get this error after opening/logging into the OC since it can’t find the web service.

Now when you browse to the Orchestration Console on port 80 using the server’s host name, IIS will automatically redirect the connection over to https.

By default, the Orchestration Console and Web Service also have pass through authentication enabled.  If you use privileged accounts to perform administrative tasks besides the account you regularly login to Windows with, you’ll also want to setup Basic Authentication on both the OC and WS.  This way when you browse to the site, it will prompt for a username and password to login with.

Prevent Multiple Invocations of a Runbook   Leave a comment

I’ve moved everything from this blog over to jmattivi.blogspot.com and updated all of the scripts to have straight quotes.  If any don’t work as posted, please let me know!

For further posts please see jmattivi.blogspot.com.

Thanks!

 

There are many occasions where you may want to prevent someone (or schedule) from starting (queuing up) another instance of a Runbook if it’s already running.  There are three ways I’ve found to accomplish this….using counters, the database query activity to look up a running job, and the web service.

While using counters may be the best solution to prevent workflows from running before a prerequisite workflow completes, it’s not the best solution to prevent inadvertently queuing up another runbook instance.

The database query activity can be used in this scenario to query the PolicyInstances table to see if a specific runbook is already running.

The query used would look like this.  Note you need to use the specific Runbook name in the query.

Select POLICIES.Name,POLICYINSTANCES.Status,POLICYINSTANCES.TimeStarted,POLICYINSTANCES.TimeEnded
From POLICYINSTANCES,POLICIES
Where (POLICIES.UniqueID = POLICYINSTANCES.PolicyID) AND TimeEnded is null AND POLICIES.Name = ‘0.1 Runbook B’

Based on the query results, you can use the Link logic to either start the Runbook or send an email that the Runbook is already running and cannot start at this time.

The .NET Script activity can be used in this scenario to query the Jobs collection of the Web Service to see if a specific runbook is already running.

The Powershell script to query the Jobs collection is a little different than I’ve used in prior posts.  Sometimes it’s tedious to look up the RunbookID guid, so this way you can specify the name of the runbook without the guid.  This is accomplished by pointing to the Jobs collection, but also expanding the runbook collection as well to grab it’s associated data.  Then you can use the filter and select statements in the odata query to filter on the name of the runbook.

Here is the URL for the GET request.  Note you need to specify the collection name and property name together for the collection that’s expanded.

$url = “http://scorch.domain:81/Orchestrator2012/Orchestrator.svc/Jobs()?`$expand=Runbook&`$filter=(Status eq ‘Running’) and (Runbook/Name eq ‘0.1 Runbook B’)&`$select=Runbook/Name,Status”

Here is the complete script to query the web service (fields in red would need to be updated per your environment):

#########################################################################################

$user = “domain\username
$pass = ConvertTo-SecureString “password” -AsPlainText -Force
$creds = New-Object System.Management.Automation.PsCredential($user,$pass)

$url = “http://scorch.domain:81/Orchestrator2012/Orchestrator.svc/Jobs()?`$expand=Runbook&`$filter=(Status eq ‘Running’) and (Runbook/Name eq ‘0.1 Runbook B‘)&`$select=Runbook/Name,Status”
$request = [System.Net.HttpWebRequest]::Create($url)
$request.Credentials = $creds
$request.Timeout = 120000
$request.ContentType = “application/atom+xml,application/xml”
$request.Headers.Add(“DataServiceVersion”, “2.0;NetFx”)
$request.Method = “GET”

$response = $request.GetResponse()
$requestStream = $response.GetResponseStream()
$readStream=new-object System.IO.StreamReader $requestStream
$Output = $readStream.ReadToEnd()
$readStream.Close()
$response.Close()
$Output

#########################################################################################

Here is the output from the request when Runbook B is NOT running:

<?xml version=”1.0″ encoding=”utf-8″ standalone=”yes”?>
<feed xml:base=”https://scorch.domain:81/Orchestrator2012/Orchestrator.svc/&#8221; xmlns:d=”http://schemas.microsof
t.com/ado/2007/08/dataservices” xmlns:m=”http://schemas.microsoft.com/ado/2007/08/dataservices/metadata&#8221; xmlns=”http://
http://www.w3.org/2005/Atom”&gt;
<title type=”text”>Jobs</title>
<id>https://scorch.domain:81/Orchestrator2012/Orchestrator.svc/Jobs</id&gt;
<updated>2012-02-19T18:59:26Z</updated>
<author>
<name />
</author>
<link rel=”self” title=”Jobs” href=”Jobs” />
</feed>

Here is the output when Runbook B is currently running:

<?xml version=”1.0″ encoding=”utf-8″ standalone=”yes”?>
<feed xml:base=”https://scorch.domain:81/Orchestrator2012/Orchestrator.svc/&#8221; xmlns:d=”http://schemas.microsof
t.com/ado/2007/08/dataservices” xmlns:m=”http://schemas.microsoft.com/ado/2007/08/dataservices/metadata&#8221; xmlns=”http://
http://www.w3.org/2005/Atom”&gt;
<title type=”text”>Jobs</title>
<id>https://scorch.domain:81/Orchestrator2012/Orchestrator.svc/Jobs</id&gt;
<updated>2012-02-19T19:01:19Z</updated>
<link rel=”self” title=”Jobs” href=”Jobs” />
<entry m:etag=”W/&quot;datetime’2012-02-19T19%3A00%3A53.29’&quot;”>
<id>https://scorch.domain:81/Orchestrator2012/Orchestrator.svc/Jobs(guid’4f104fcd-d626-421d-9f75-c8c83200
48e0′)</id>
<title type=”text”></title>
<published>2012-02-19T19:00:49-05:00</published>
<updated>2012-02-19T19:00:53-05:00</updated>
<author>
<name />
</author>
<link rel=”edit” title=”Job” href=”Jobs(guid’4f104fcd-d626-421d-9f75-c8c8320048e0′)” />
<link rel=”http://schemas.microsoft.com/ado/2007/08/dataservices/related/Runbook&#8221; type=”application/atom+xml;type=e
ntry” title=”Runbook” href=”Jobs(guid’4f104fcd-d626-421d-9f75-c8c8320048e0′)/Runbook”>
<m:inline>
<entry m:etag=”W/&quot;datetime’2012-02-19T03%3A57%3A55’&quot;”>
<id>https://scorch.domain:81/Orchestrator2012/Orchestrator.svc/Runbooks(guid’034d6f78-0529-4111-b31
7-24d75fb42493′)</id>
<title type=”text”>0.1 Runbook B</title>
<published>2012-02-19T03:57:20-05:00</published>
<updated>2012-02-19T03:57:55-05:00</updated>
<author>
<name />
</author>
<link rel=”edit” title=”Runbook” href=”Runbooks(guid’034d6f78-0529-4111-b317-24d75fb42493’)” />
<category term=”Microsoft.SystemCenter.Orchestrator.WebService.Runbook” scheme=”http://schemas.microsoft.com/
ado/2007/08/dataservices/scheme” />
<content type=”application/xml”>
<m:properties>
<d:Name>0.1 Runbook B</d:Name>
</m:properties>
</content>
</entry>
</m:inline>
</link>
<category term=”Microsoft.SystemCenter.Orchestrator.WebService.Job” scheme=”http://schemas.microsoft.com/ado/2007/0
8/dataservices/scheme” />
<content type=”application/xml”>
<m:properties>
<d:Status>Running</d:Status>
</m:properties>
</content>
</entry>
</feed>

So you can see in the output above, you can use link logic to find “<d:Status>Running</d:Status>” in the output from the query to determine if 0.1 Runbook B can be started.

Start Runbooks from SharePoint List   Leave a comment

I’ve moved everything from this blog over to jmattivi.blogspot.com and updated all of the scripts to have straight quotes.  If any don’t work as posted, please let me know!

For further posts please see jmattivi.blogspot.com.

Thanks!

 

After stopping all running/pending runbooks to perform maintenance on the SCOrch environment, it becomes cumbersome to start all runbooks that begin with a monitor date/time activity (especially when the number of runbooks to start climbs above 100….).

You can create a SharePoint list (Figure A) of runbooks that need to be started after maintenance (good to document nonetheless) that Orchestrator can reference to start all of them automatically!

The main field that we need to use is the RunbookID in the SP list.  I also use a field called “Active” in the list to exclude workflows that may not need started in case there is any reason that they shouldn’t be started for the time being.

Figure A

The workflow is made up of three runbooks.  A main which queries the SP list for the active runbook ids to start, the execute which starts the targeted runbook, and a seperate runbook to keep track of processed runbooks to later check for any errors.

Main (Figure B)

Figure B

The main starts by resetting a counter to cleanup from previous runs.  Then it uses the Microsoft SharePoint IP by Jeff Fanjoy (more info here http://orchestrator.codeplex.com/releases/view/75877) to query the list identified in the SP IP configuration in options.  Within the properties of the Get Active Runbooks activity, the filter is modified to choose the “Active” field set on the list object (Figure C).

Figure C

From the runbooks found in the list query, it will invoke the execute runbook with the runbook id and runbook name.  It also invokes the counter modification runbook with a parameter – increment (note this invoke must set the property to wait for completion – See Figure E).

Exploring the execute runbook that’s invoked in Figure D….it uses the Standard Logging IP (more info here http://orchestrator.codeplex.com/releases/view/76097).  It starts the targeted runbook (you can reference this from my previous post – https://jmattivi.wordpress.com/2012/01/08/scorch-powershell-startrunbook_part1/).  Upon success or failure to start the runbook, it invokes the counter modification runbook with a parameter – decrement (note this invoke must set the property to wait for completion – See Figure E).

Figure D

Figure E

Moving back to the Main runbook (Figure B), it waits for the counter value to be 0 – indicating processing has completed.  If not it hits a timeout after 15 minutes and sends an error email for investigation.  It then queries the Standard Logging table in the database for any failures to start runbooks from the execute runbook.  If errors are found, it uses a Powershell script to parse the flattened data back into multi-valued data and send that information in an email.  If no failures are found, it sends a success email that all targeted scheduled runbooks have been started successfully.

Workflow to Stop all Runbook Jobs   Leave a comment

I’ve moved everything from this blog over to jmattivi.blogspot.com and updated all of the scripts to have straight quotes.  If any don’t work as posted, please let me know!

For further posts please see jmattivi.blogspot.com.

Thanks!

 

There’s not a lot I miss about the Opalis Operator Console compared to the new Orchestration Console….however, there was one feature that is not present in the new OC.  That is the ability to stop all Runbook Jobs.  Whenever there’s maintenance that needs to be done to the runbook servers or database, to prevent creating orphaned jobs, all running/pending jobs need to be stopped.

This is a job for the new web service and powershell!  In my previous posts, I showed how to query runbooks that have a status of running or pending and how to stop/cancel a runbook job.  This ties them together creating a workflow right in Orchestrator using a combination of the two to stop all running and pending jobs.

The runbook below queries jobs with a status of running and then invokes the runbook which actually stops the job.  The query returns the necessary properties of the runbook to pass to the stopping job – jobID, RunbookID, and LastModifiedTime.  I have another similar runbook that runs in parallel that queries for pending jobs and calls the same stopping runbook.  These runbooks will loop until the total running/pending jobs = 0.

Be sure to exclude the runbooks that are running this workflow from the query or this runbook will stop itself :).  Here is an example of the url in the query script to exclude the runbookIDs of the runbooks which run the workflow.

$url = “https://scorch.domain:81/Orchestrator2012/Orchestrator.svc/Jobs()?`$filter=Status eq ‘Running’ and RunbookId ne guid’10000000-0000-0000-0000-000000000000′ and RunbookId ne guid’20000000-0000-0000-0000-000000000000′ and RunbookId ne guid’30000000-0000-0000-0000-000000000000′&`$select=Id,RunbookId,LastModifiedTime,Status”

Figure A

Figure B

In Figure A, I reset a counter and then run the powershell script to query for running jobs.  For every running job it finds, it then increments a counter and invokes the stop jobs runbook.  I also decrement the same counter in Figure B so that we know every runbook found was processed successfully.  After the junction, we check to make sure the counter was decremented back to 0.  Then we query for any running jobs again and publish that back to the main runbook that will loop until that is 0.

In Figure B, I implement the Standard Logging IP by Charles Joy to log the stopping script.  This will allow parsing the table for failures and reporting at the end.  As mentioned above, on success or failure, I decrement the counter again to ensure the running job was processed.

Now with one click to start a runbook, you can stop all runbook jobs again!  I had to come up with another workflow to automate starting all necessary jobs again that run with a Monitor Date/Time activity from a Sharepoint list….but that’ll be saved for the next post.