Running a vCAC Workflow from PowerShell

Calling PowerShell from vCAC is easy, right. But how about the other way round? Suppose you want to start the ‘ReclaimDestroyedStaticIPAddresses’ or the ‘WFStubMachineExpired’ workflow manually? As usual this can be done via the vCAC MetaModel ODATA REST service and of course with PowerShell. For a brief overview about the MetaModel you can have a look at Investigating vCAC 5.2 Models.

Internally vCAC workflows are triggered by inserting a DB record into the repository database which is encapsulated via a call to the ODATA repository. For a workflow to be triggered you have to link it to the its definition and optionally add some arguments to it. These are added to the repository as well and attach to the newly created workflow instance. Here you find some example code to trigger the MachineExpired workflow stub.

# 1. Establish connection to the vCAC MetaModel.svc
PS > $UriMetaModel = 'https://vcac52.sharedop.org/Repository/Data/MetaModel.svc';
PS > $MetaModel = New-Object DynamicOps.Repository.RepositoryModel.RepositoryModelEntities
  -ArgumentList $UriMetaModel;
PS > $MetaModel.Credentials = [System.Net.CredentialCache]::DefaultCredentials;
PS > $MetaModel.SaveChangesDefaultOptions =
  [System.Data.Services.Client.SaveChangesOptions]::Batch;

# 2. Get the workflow to run
PS > $wfDefinition = $metamodel.WorkflowDefinitions |?
  {($_.name -eq 'WFStubMachineExpired') -and ($_.Revision -eq 2)}

# 3. Create workflow instance object
PS > $wfi = New-Object DynamicOps.Repository.RepositoryModel.WorkflowInstance;
PS > $wfi.CreatedDatetime = [datetime]::UtcNow;
PS > $wfi.TriggeringUser = '{0}\{1}' -f $ENV:USERDOMAIN, $ENV:USERNAME;
PS > $wfi.ExecutionState = 0;
PS > $wfi.WorkflowDefinition = $wfDefinition;
PS > $metamodel.AddToWorkflowInstances($wfi);
PS > $metamodel.SetLink($wfi, 'WorkflowDefinition', $wfDefinition);

# 4a. Attach VirtualMachineID to the workflow
# make sure you serialize the parameter and have it passed on as a GUID type and not a string
$wfia1 = New-Object DynamicOps.Repository.RepositoryModel.WorkflowInstanceArgument;
$wfia1.Name = "VirtualMachineId"
$wfia1.Value = [DynamicOps.Common.Utils.SerializeUtils]::SerializeEntity([guid]('87cdf6d9-cb69-46d9-bc06-157eb0d5fd56'))
$metamodel.AddToWorkflowInstanceArguments($wfia1)
$wfi.WorkflowInstanceArguments.Add($wfia1);
$metamodel.SetLink($wfia1, 'WorkflowInstance', $wfi);
$metamodel.AddLink($wfi, 'WorkflowInstanceArguments', $wfia1);

# 4b. Attach ExternalWorkflowId to the workflow and create a new Guid for it
$wfia2 = New-Object DynamicOps.Repository.RepositoryModel.WorkflowInstanceArgument;
$wfia2.Name = "ExternalWorkflowId"
$wfia2.Value = [DynamicOps.Common.Utils.SerializeUtils]::SerializeEntity([guid]::NewGuid())
$metamodel.AddToWorkflowInstanceArguments($wfia2)
$wfi.WorkflowInstanceArguments.Add($wfia2);
$metamodel.SetLink($wfia2, 'WorkflowInstance', $wfi);
$metamodel.AddLink($wfi, 'WorkflowInstanceArguments', $wfia2);

# 5. Start workflow by saving the changes to the repository
PS > $metamodel.SaveChanges();
Descriptor                        Headers                           StatusCode Error
----------                        -------                           ---------- -----
System.Data.Services.Client.En... {[Content-ID, 243], [Cache-Con... 201
System.Data.Services.Client.En... {[Content-ID, 245], [Cache-Con... 201
System.Data.Services.Client.Li... {[Content-ID, 246], [Cache-Con... 204
System.Data.Services.Client.Li... {[Content-ID, 247], [Cache-Con... 204
System.Data.Services.Client.En... {[Content-ID, 248], [Cache-Con... 201
System.Data.Services.Client.Li... {[Content-ID, 249], [Cache-Con... 204
System.Data.Services.Client.Li... {[Content-ID, 250], [Cache-Con... 204

The resulting ODATA REST call might look like this (as we specified ‘batch’ as the SaveDefaultOption we will see a single HTTP POST instead of separate requests):

POST https://vcac52.sharedop.org/Repository/Data/MetaModel.svc/$batch HTTP/1.1
User-Agent: Microsoft ADO.NET Data Services
DataServiceVersion: 1.0;NetFx
MaxDataServiceVersion: 2.0;NetFx
Repository-Cache: AuthorizationStore=Sat, 15 Feb 2014 23:37:24 GMT;ModelConfiguration=Mon, 14 Oct 2013 14:38:27 GMT;ReadPermissions=Wed, 19 Jun 2013 01:45:17 GMT;WritePermissions=Wed, 19 Jun 2013 01:45:45 GMT
Accept: application/atom+xml,application/xml
Accept-Charset: UTF-8
Content-Type: multipart/mixed; boundary=batch_2fd1e8ff-834e-4ec1-b621-5eb46d73627d
Host: vcac52.sharedop.org
Content-Length: 5100

--batch_2fd1e8ff-834e-4ec1-b621-5eb46d73627d
Content-Type: multipart/mixed; boundary=changeset_8af42a29-1a42-42d6-bca0-a83d7e626e7a

--changeset_8af42a29-1a42-42d6-bca0-a83d7e626e7a
Content-Type: application/http
Content-Transfer-Encoding: binary

POST https://vcac52.sharedop.org/Repository/Data/MetaModel.svc/WorkflowInstances HTTP/1.1
Content-ID: 243
Content-Type: application/atom+xml;type=entry
Content-Length: 1064

<?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">
 <title />
 <author>
  <name />
 </author>
 <updated>2014-02-15T23:37:38.916Z</updated>
 <id />
 <link href="https://vcac52.sharedop.org/Repository/Data/MetaModel.svc/WorkflowDefinitions(243)" rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/WorkflowDefinition" type="application/atom+xml;type=entry" />
 <content type="application/xml">
  <m:properties>
   <d:ClaimedDatetime m:type="Edm.DateTime" m:null="true" />
   <d:CreatedDatetime m:type="Edm.DateTime">2014-02-15T23:37:38.448Z</d:CreatedDatetime>
   <d:DEMSessionId m:type="Edm.Guid" m:null="true" />
   <d:ExecutionState m:type="Edm.Int16">0</d:ExecutionState>
   <d:Id m:type="Edm.Int32">0</d:Id>
   <d:TriggeringUser>SHAREDOP\vcacservice</d:TriggeringUser>
  </m:properties>
 </content>
</entry>
--changeset_8af42a29-1a42-42d6-bca0-a83d7e626e7a
Content-Type: application/http
Content-Transfer-Encoding: binary

POST https://vcac52.sharedop.org/Repository/Data/MetaModel.svc/WorkflowInstanceArguments HTTP/1.1
Content-ID: 245
Content-Type: application/atom+xml;type=entry
Content-Length: 679

<?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">
 <title />
 <author>
  <name />
 </author>
 <updated>2014-02-15T23:37:38.916Z</updated>
 <id />
 <content type="application/xml">
  <m:properties>
   <d:Id m:type="Edm.Int32">0</d:Id>
   <d:Name>VirtualMachineId</d:Name>
   <d:Value>&lt;guid xmlns="http://schemas.microsoft.com/2003/10/Serialization/"&gt;87cdf6d9-cb69-46d9-bc06-157eb0d5fd56&lt;/guid&gt;</d:Value>
  </m:properties>
 </content>
</entry>
--changeset_8af42a29-1a42-42d6-bca0-a83d7e626e7a
Content-Type: application/http
Content-Transfer-Encoding: binary

PUT $245/$links/WorkflowInstance HTTP/1.1
Content-ID: 246
Content-Type: application/xml
Content-Length: 145

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<uri xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">$243</uri>
--changeset_8af42a29-1a42-42d6-bca0-a83d7e626e7a
Content-Type: application/http
Content-Transfer-Encoding: binary

POST $243/$links/WorkflowInstanceArguments HTTP/1.1
Content-ID: 247
Content-Type: application/xml
Content-Length: 145

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<uri xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">$245</uri>
--changeset_8af42a29-1a42-42d6-bca0-a83d7e626e7a
Content-Type: application/http
Content-Transfer-Encoding: binary

POST https://vcac52.sharedop.org/Repository/Data/MetaModel.svc/WorkflowInstanceArguments HTTP/1.1
Content-ID: 248
Content-Type: application/atom+xml;type=entry
Content-Length: 681

<?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">
 <title />
 <author>
  <name />
 </author>
 <updated>2014-02-15T23:37:38.916Z</updated>
 <id />
 <content type="application/xml">
  <m:properties>
   <d:Id m:type="Edm.Int32">0</d:Id>
   <d:Name>ExternalWorkflowId</d:Name>
   <d:Value>&lt;guid xmlns="http://schemas.microsoft.com/2003/10/Serialization/"&gt;45e20302-8521-439e-a6e4-c41b15eafb90&lt;/guid&gt;</d:Value>
  </m:properties>
 </content>
</entry>
--changeset_8af42a29-1a42-42d6-bca0-a83d7e626e7a
Content-Type: application/http
Content-Transfer-Encoding: binary

PUT $248/$links/WorkflowInstance HTTP/1.1
Content-ID: 249
Content-Type: application/xml
Content-Length: 145

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<uri xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">$243</uri>
--changeset_8af42a29-1a42-42d6-bca0-a83d7e626e7a
Content-Type: application/http
Content-Transfer-Encoding: binary

POST $243/$links/WorkflowInstanceArguments HTTP/1.1
Content-ID: 250
Content-Type: application/xml
Content-Length: 145

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<uri xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">$248</uri>
--changeset_8af42a29-1a42-42d6-bca0-a83d7e626e7a--
--batch_2fd1e8ff-834e-4ec1-b621-5eb46d73627d--

And the ODATA response would look like this:

HTTP/1.1 202 Accepted
Cache-Control: no-cache
Content-Length: 7421
Content-Type: multipart/mixed; boundary=batchresponse_8f180c8d-8869-41c6-b55f-bbe8baaedf30
DataServiceVersion: 1.0;
Repository-Cache: AuthorizationStore=Sat, 15 Feb 2014 23:37:24 GMT;ModelConfiguration=Mon, 14 Oct 2013 14:38:27 GMT;ReadPermissions=Wed, 19 Jun 2013 01:45:17 GMT;WritePermissions=Wed, 19 Jun 2013 01:45:45 GMT
Persistent-Auth: true
Date: Sat, 15 Feb 2014 23:37:38 GMT

--batchresponse_8f180c8d-8869-41c6-b55f-bbe8baaedf30
Content-Type: multipart/mixed; boundary=changesetresponse_d2f4adf3-b716-4c85-9010-40e400adba41

--changesetresponse_d2f4adf3-b716-4c85-9010-40e400adba41
Content-Type: application/http
Content-Transfer-Encoding: binary

HTTP/1.1 201 Created
Content-ID: 243
Cache-Control: no-cache
DataServiceVersion: 1.0;
Content-Type: application/atom+xml;charset=utf-8
Location: https://vcac52.sharedop.org/Repository/Data/MetaModel.svc/WorkflowInstances(38118)
ETag: W/"null"

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<entry xml:base="https://vcac52.sharedop.org/Repository/Data/MetaModel.svc/" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" m:etag="W/&quot;null&quot;" xmlns="http://www.w3.org/2005/Atom">
  <id>https://vcac52.sharedop.org/Repository/Data/MetaModel.svc/WorkflowInstances(38118)</id>
  <title type="text"></title>
  <updated>2014-02-15T23:37:38Z</updated>
  <author>
    <name />
  </author>
  <link rel="edit" title="WorkflowInstance" href="WorkflowInstances(38118)" />
  <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/DEM" type="application/atom+xml;type=entry" title="DEM" href="WorkflowInstances(38118)/DEM" />
  <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/WorkflowHistoryResult" type="application/atom+xml;type=entry" title="WorkflowHistoryResult" href="WorkflowInstances(38118)/WorkflowHistoryResult" />
  <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/WorkflowInstanceArguments" type="application/atom+xml;type=feed" title="WorkflowInstanceArguments" href="WorkflowInstances(38118)/WorkflowInstanceArguments" />
  <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Skills" type="application/atom+xml;type=feed" title="Skills" href="WorkflowInstances(38118)/Skills" />
  <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/WorkflowSchedule" type="application/atom+xml;type=entry" title="WorkflowSchedule" href="WorkflowInstances(38118)/WorkflowSchedule" />
  <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/WorkflowDefinition" type="application/atom+xml;type=entry" title="WorkflowDefinition" href="WorkflowInstances(38118)/WorkflowDefinition" />
  <category term="DynamicOps.Repository.RepositoryModel.WorkflowInstance" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
  <content type="application/xml">
    <m:properties>
      <d:Id m:type="Edm.Int32">38118</d:Id>
      <d:TriggeringUser>SHAREDOP\vcacservice</d:TriggeringUser>
      <d:ExecutionState m:type="Edm.Int16">0</d:ExecutionState>
      <d:CreatedDatetime m:type="Edm.DateTime">2014-02-15T23:37:38.448Z</d:CreatedDatetime>
      <d:ClaimedDatetime m:type="Edm.DateTime" m:null="true" />
      <d:DEMSessionId m:type="Edm.Guid" m:null="true" />
    </m:properties>
  </content>
</entry>
--changesetresponse_d2f4adf3-b716-4c85-9010-40e400adba41
Content-Type: application/http
Content-Transfer-Encoding: binary

HTTP/1.1 201 Created
Content-ID: 245
Cache-Control: no-cache
DataServiceVersion: 1.0;
Content-Type: application/atom+xml;charset=utf-8
Location: https://vcac52.sharedop.org/Repository/Data/MetaModel.svc/WorkflowInstanceArguments(932)

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<entry xml:base="https://vcac52.sharedop.org/Repository/Data/MetaModel.svc/" 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">
  <id>https://vcac52.sharedop.org/Repository/Data/MetaModel.svc/WorkflowInstanceArguments(932)</id>
  <title type="text"></title>
  <updated>2014-02-15T23:37:38Z</updated>
  <author>
    <name />
  </author>
  <link rel="edit" title="WorkflowInstanceArgument" href="WorkflowInstanceArguments(932)" />
  <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/WorkflowInstance" type="application/atom+xml;type=entry" title="WorkflowInstance" href="WorkflowInstanceArguments(932)/WorkflowInstance" />
  <category term="DynamicOps.Repository.RepositoryModel.WorkflowInstanceArgument" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
  <content type="application/xml">
    <m:properties>
      <d:Id m:type="Edm.Int32">932</d:Id>
      <d:Name>VirtualMachineId</d:Name>
      <d:Value>&lt;guid xmlns="http://schemas.microsoft.com/2003/10/Serialization/"&gt;87cdf6d9-cb69-46d9-bc06-157eb0d5fd56&lt;/guid&gt;</d:Value>
    </m:properties>
  </content>
</entry>
--changesetresponse_d2f4adf3-b716-4c85-9010-40e400adba41
Content-Type: application/http
Content-Transfer-Encoding: binary

HTTP/1.1 204 No Content
Content-ID: 246
Cache-Control: no-cache
DataServiceVersion: 1.0;

--changesetresponse_d2f4adf3-b716-4c85-9010-40e400adba41
Content-Type: application/http
Content-Transfer-Encoding: binary

HTTP/1.1 204 No Content
Content-ID: 247
Cache-Control: no-cache
DataServiceVersion: 1.0;

--changesetresponse_d2f4adf3-b716-4c85-9010-40e400adba41
Content-Type: application/http
Content-Transfer-Encoding: binary

HTTP/1.1 201 Created
Content-ID: 248
Cache-Control: no-cache
DataServiceVersion: 1.0;
Content-Type: application/atom+xml;charset=utf-8
Location: https://vcac52.sharedop.org/Repository/Data/MetaModel.svc/WorkflowInstanceArguments(933)

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<entry xml:base="https://vcac52.sharedop.org/Repository/Data/MetaModel.svc/" 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">
  <id>https://vcac52.sharedop.org/Repository/Data/MetaModel.svc/WorkflowInstanceArguments(933)</id>
  <title type="text"></title>
  <updated>2014-02-15T23:37:38Z</updated>
  <author>
    <name />
  </author>
  <link rel="edit" title="WorkflowInstanceArgument" href="WorkflowInstanceArguments(933)" />
  <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/WorkflowInstance" type="application/atom+xml;type=entry" title="WorkflowInstance" href="WorkflowInstanceArguments(933)/WorkflowInstance" />
  <category term="DynamicOps.Repository.RepositoryModel.WorkflowInstanceArgument" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
  <content type="application/xml">
    <m:properties>
      <d:Id m:type="Edm.Int32">933</d:Id>
      <d:Name>ExternalWorkflowId</d:Name>
      <d:Value>&lt;guid xmlns="http://schemas.microsoft.com/2003/10/Serialization/"&gt;45e20302-8521-439e-a6e4-c41b15eafb90&lt;/guid&gt;</d:Value>
    </m:properties>
  </content>
</entry>
--changesetresponse_d2f4adf3-b716-4c85-9010-40e400adba41
Content-Type: application/http
Content-Transfer-Encoding: binary

HTTP/1.1 204 No Content
Content-ID: 249
Cache-Control: no-cache
DataServiceVersion: 1.0;

--changesetresponse_d2f4adf3-b716-4c85-9010-40e400adba41
Content-Type: application/http
Content-Transfer-Encoding: binary

HTTP/1.1 204 No Content
Content-ID: 250
Cache-Control: no-cache
DataServiceVersion: 1.0;

--changesetresponse_d2f4adf3-b716-4c85-9010-40e400adba41--
--batchresponse_8f180c8d-8869-41c6-b55f-bbe8baaedf30--

And from the ‘MetaModel’ we see a running workflow via the ‘WorkflowInstances’ method:

Id                        : 38155
TriggeringUser            : SHAREDOP\vcacservice
ExecutionState            : 0
CreatedDatetime           : 2/16/2014 4:54:45 AM
ClaimedDatetime           : 2/16/2014 4:54:59 AM
DEMSessionId              : 9e6cd39a-e041-4e14-9451-8d5927e267f5
DEM                       : DynamicOps.Repository.RepositoryModel.DEM
WorkflowHistoryResult     : DynamicOps.Repository.RepositoryModel.WorkflowHistoryResult
WorkflowInstanceArguments : {VirtualMachineId, ExternalWorkflowId}
Skills                    : {}
WorkflowSchedule          :
WorkflowDefinition        : DynamicOps.Repository.RepositoryModel.WorkflowDefinition

In case you are not sure what input parameters or argument a workflow takes you can have a look at the ‘XamlDefinition’ attribute of the ‘WorkflowDefinition’ entity. In that XMl you will see ‘Property’ nodes with an attribute ‘Type’ and a value of ‘InArgument’:

PS > $wfDefinition.XamlDefinition.Split("`n") | sls 'Property.*InArgument'
  <x:Property Name="VirtualMachineId" Type="InArgument(s:Guid)" />
  <x:Property Name="ExternalWorkflowId" Type="InArgument(s:Guid)" />

Or took at the it with a more ‘typeful’ approach:

PS > ([xml] $wfDefinition.XamlDefinition).Activity.Members.Property;
Name               Type
----               ----
VirtualMachineId   InArgument(s:Guid)
ExternalWorkflowId InArgument(s:Guid)^

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: