Allgemein

Using Optional Parameters in Service Management Automation (SMA) runbooks

Using Optional Parameters in Service Management Automation (SMA) runbooks

In this post, I would like to share an interesting observation I have made when working with optional parameters in SMA runbooks. The requirement is pretty basic – pass an optional [datetime] parameter to an SMA runbook and trigger an action, depending on the whether a value has been passed or not.

The error message I had to deal with was:

“The values provided for the root activity’s arguments did not satisfy the root activity’s requirements: ‚DynamicActivity‘: Expected an input parameter value of type ‚System.DateTime‘ for parameter named ‚DateEntered‘. Parameter name: rootArgumentValues”

Let’s dig a bit deeper and find out what actually happens.

For demonstration pursposes I have created a simple workflow, which will help us understand how values are passed over the Windows Azure Pack portal to SMA:

 

Workflow ShowDateDifference
{
 param
 (
  [parameter(Mandatory=$false)]
  [datetime]$DateEntered
 )

 $WorkerName = Get-Content ENV:ComputerName
 Write-Verbose –Message "START RUNBOOK: Worker [$WorkerName]"
 
try
 {
  #Get the current date
  if ($DateEntered)
  {
   $CurrentDate = (Get-Date)
   New-TimeSpan -Start $CurrentDate -End $DateEntered
  }
  else
  {
   Write-Output "No date has been entered"
  }
 }
 catch
 {
  #generate an error message
  $ErrorMessage = $_
  Write-Verbose "ErrorMessage: $ErrorMessage"
  Throw $ErrorMessage
 }
 Write-Verbose "END: ShowDateDifference"
}

 

This simple workflow takes the optional [datetime] parameter, named Dateentered ($DateEntered) and either calculates the time difference between the entered date and the current date or writes a simple output.

As you might have noticed the runbook parameter $DateEntered has been defined as optional (Mandatory=$false). So let’s first start it with a correct datetime value.

 

Entering a proper datetime value for the parameter

After publishing the runbook and on the attempt to Start it we first notice that the parameter is properly identified as a datetime:

 

Providing a date to the parameter of type [datetme]

So let’s select a date and see how the runbook behaves:

 

Correct date entered

 

Right away after starting the runbook with a proper value entered, we see the following, showing under the input parameters section of the runbook:

 

Correct date entered

 

The first thing we notice here is the format of the value when the runbook has been assigned to a worker (queued) and then the format of the datetime value on runbook completion:

 

Proper runbook execution

 

No surprises, the date difference is properly calculated by the runbook and presented in the Output section. Let’s now see what happens when a value has not been provided.

 

Leaving the optional datetime parameter blank

Now let’s take this same example, but this time leave the optional parameter blank (don’t provide a value for the datetime). This is what we wanted since the beginning as we have a requirement for an optional parameter.

In this particular case, right after submitting the runbook we get “Invalid Date” in the input parameter section:

 

Leaving the optional parameter blank

 

After the runbook has been compiled and started the “Invalid Date” changes to „\/Date(NaN)\/“ (The NaN stands for “Not a Number”):

 

Datetime formating on blank, optional parameters

 

So in this particular case the Windows Azure Pack portal is unable to deal with the (Mandatory=$false) parameter definition and interprets the missing value as invalid date.

It then fails and generates and generates the exception:

 

“The values provided for the root activity’s arguments did not satisfy the root activity’s requirements: ‚DynamicActivity‘: Expected an input parameter value of type ‚System.DateTime‘ for parameter named ‚DateEntered‘. Parameter name: rootArgumentValues”

 

Error message in blank, optinal parameter

 

One way of dealing with this would be to use a [string] type for the parameter $DateEntered. Let us take a close look at this option.

 

Specify the optional datetime parameter as a string and leave it blank

In the next example I have changed the type of the $DateEntered parameter to [string] and tried running the runbook without providing a value for $DateEntered. Opposite to scenario 2 (Leaving the optional datetime parameter blank), where we got an error message when intentionally left the optional datetime parameter blank, here we see the SMA handles well the missing [string] value, outputs what is expected (“No date has been entered”) and completes in a successful matter:

 

Successful runbook completion on optional [string] parameter

Proper runbook execution

 

If you decide to go this way, you should be very careful when entering datetime values as strings and should always ensure you are passing the date string in the proper format.

 

Specify the optional datetime parameter as a string and enter a date

This is one of the “last resort” workarounds if you want to have an optional parameter, which you could leave blank if needed still and ensure the runbook does not fail. Why I’ve labeled it “last resort”? Well, because it works, only if you provide the data in a proper format, which can be actually parsed into [datetime].

Which are the [datetime] formats, which are not handled successfully, when passed as a string:

  • DD.MM.YYYYY

  • DD-MM-2017

  • DD/MM/2017

When providing a string in one of those formats, the runbook fails with the same, expected error message:

Error message, when entering incorrect string value for a datetime parameter

 

So what are the datetime formats, we could use, if we decide to have an optional parameter for a date, but declared as a string?

If you go for one of those, you can still use a string:

  • MM-DD-2017

  • MM/DD/2017

Then the date is passed properly to the runbook and it executes without an error. Here an example where the datetime has been passed as a string in the proper format:

Entering date in a correct format for a parameter of type [string]

Entering date in a correct format for a parameter of type [string]

 

It is interesting to note, how SMA displays the $DateEntered when passed as string – “MM-DD-YYYY” and when passed as [datetime] parameter type – Wed, 15 Mar 2017 00:00:00 GMT

 

Successful completion of the runbook on entering proper daytime format for a parameter of type string

 

Conclusion

SMA is a great automation tool and I am glad to see that it is used more often in customer environments, despite the fact that it has no GUI, like the Orchestrator. I also like the fact that Microsoft removed the PowerShell workflow limitation in SMA 2016 and now you are able to use native PowerShel to automate day-to-day tasks.

Still, when working with optional parameters in SMA workflows and especially when those have different data types then [string], you should be careful how you define them and pass values.

As we already witnessed, leaving optional parameters empty, can lead to error messages if those parameter types are not defined as string. I have currently tested and reproduced the behavior with [datetime] and [double], but I assume this is the case for all other types.

If you decide to go for the suggested workaround in order to be able to leave the param without a value, then you have to ensure that the values you are passing to the workflow have been properly formatted.

 

 

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.