...building hybrid clouds that can support any device from anywhere
A question came up on a recent SMA blog post Automation–Service Management Automation Runbook Spotlight–Exchange Distribution List Creation and the answer deserves its own blog post. Understanding the underlying moving parts of why we do what we do in SMA is just as important as the development of knowledge we provide through examples. Some concepts were taken for granted in the post referenced above that I wanted to dive into a little bit and provide more reading for those that need further detail.
Q: Stijn asks: I was wondering why you use the $pscomputername and $pscredential parameters of the inline script. In the inlinescript activity you use the $using scope modifier to access the variables exchangeserver and credentials.
Could you elaborate? thanks
And more specifically
Why use remoting twice?
Once for executing the inlinescript on the exchange server and then creating a session to the same exchange server?
Well, first – thank you! Since PowerShell Workflow is so new and the details on how you use it are not always obvious, and since SMA uses PowerShell workflow, our examples are all about how you can use workflow within the realms of SMA to get your automation done from end to end. These types of questions are great and key to pushing the envelope of understanding.
A: In this post, we’re going to dive into some of the specifics around why we use InlineScript and $Using:Variable configurations in our examples to get the data we need. I’ll use this post Automation–Service Management Automation Runbook Spotlight–Exchange Distribution List Creation as a reference to explain these details so we close the gap on the initial question that came up.
At our top level process Runbook (Build-Exchange-Distribution-List) we instantiate a handful of variables that can be used throughout the processing of subroutine Runbooks. The two variables referenced below are leveraged for making connections directly to the Exchange server via an InlineScript for our example solution.
Note $PSCredName is actually referencing a string "Contoso Creds" which is a name of an SMA Credential object that has been created/stored in the SMA database and can be leveraged by name within our SMA Runbooks to make credential management easier. $ExchangeServer is obviously the Exchange server we'll be connecting to (EX01).
Following the example provided in the post, we execute a subroutine Runbook called Create-Exchange-Distribution-List to execute the logic for the creation of our DL from our process Runbook Build-Exchange-Distribution-List.
Skipping way ahead and diving into a subroutine Runbook (Get-Exchange-Distribution-List), we then leverage the top level variables defined as parameters sent to the subroutine Runbooks similar to the below example:
Then within the subroutine Runbook we leverage the SMA cmdlet Get-AutomationPSCredential leveraging (by name) the $PSCredName to retrieve the credentials and store them in a credential variable to be used by this Runbook for this session.
Now, using the subroutine Runbook Get-Exchange-Distribution-List as an example, we need to determine if an Exchange DL actually exists (that is the function of this Runbook at least). In order to do this, we are making a connection to the Exchange server ($ExchangeServer) leveraging the stored credentials ($PSUserCred) to do a quick check and then return those results to the calling Runbook.
This is where the InlineScript comes in. We need to leverage an InlineScript so we can run a non-workflow execution to get results and return back that data back to the workflow. We do this to make a remote connection to the system (Exchange server in our example), process our request, get our data, and bring it back to the workflow.
Note We are leveraging the workflow variables as parameters for the InlineScript.
While in the InlineScript, if we want to use workflow variables (parameters, credentials) we need to leverage the $Using:Variable option which tells the InlineScript to use the variable from the workflow.
The example below is leveraging the $Using:PSUserCred to access the stored credential variable for reuse in the connection to the Exchange server within the InlineScript.
Note Pay attention to where the $ is defined. It moves to before Using instead of with the PSUserCred portion of the string.
Remote management of Microsoft Exchange required us to create a PSSession that had a configuration name of "Microsoft.Exchange". We found that the InlineScript does not allow for this type of PSSession, so we created a remote InlineScript connection to the Exchange server, and then leveraged a Microsoft.Exchange PSSession to execute the cmdlets within an Invoke-Command.
To ensure we don't leave anything behind, we clean up the session with a Remove-PSSession before we return to the InlineScript and then back to workflow.
All of that, to be able to return the following
This returns an object with information (we execute Get-ExchangeDistributionGroup Exchange PowerShell CMDLET and if it finds our distribution list, we have data, if it doesn't, the return data returns a NULL).
I elaborated quite a bit in the weeds on some of this. Hopefully you got your answer in there :) if not, please ask for more clarification. URLs for great reference since SMA is literally consuming PowerShell v3 Workflow:
Running Windows PowerShell Commands in a Workflow Hey, Scripting Guy! Blog (PowerShell Workflow Posts)
That’s it! For more information, tips/tricks, and example solutions for SMA, be sure to watch for future blog posts in the Automation Track!
Till next time, Happy Automating
Thanks for the dedicated post ;-)
Hopefully I got the use of using 2 'hops' (1 for the inlinescript and 1 for the pssession):
The PSCredentials automatically adds 'localhost' to the PSComputer property unless PSComputerName or PSConnectionUri are present.
This allows the to reuse of the pscredential in the new-pssession cmdlet by specifying the -credential parameter and referring to the psUserCred defined in the workflow by making use of the $using scope. And because the inlinescript did not allow to create an Exchange configuration
But the following draw my attention:
"Remote management of Microsoft Exchange required us to create a PSSession that had a configuration name of "Microsoft.Exchange". We found that the InlineScript does not allow for this type of PSSession...."
Funny thing, as I do not have SMA installed just yet nor have access to an on-premise Exchange, when adding the credentials as a parameter and the PSConnectionUri (as they are linked) the use of the inlinescript parameters just works, so omitting the session creation in the inlinescript (tested against O365).
$result = inlinescript
} -psConfigurationName Microsoft.Exchange `
-psAuthentication Basic `
-DisplayName "Get Dirstribution list Exchange online"
Get-Exchange-Distribution-List -Name "Something" -PSCredential $cred -PSConnecionUri "ps.outlook.com/powershell"
As the get-Exchange-Distribution-List is a 'sub-runbook' the parent 'runbook' can easily call the workflow providing the PS parameters.
@Stijn C, thanks for the follow up here. This will also help others as they look at different ways to build out their solutions. I do really appreciate the extra set of eyes and feedback helps improve adoption! Have a great weekend!