Automation–Service Management Automation Runbook Spotlight–Exchange Distribution List Creation

Automation–Service Management Automation Runbook Spotlight–Exchange Distribution List Creation

  • Comments 16
  • Likes

Hello Readers!  I’m excited to provide you all with some cool new stuff that was introduced recently with System Center 2012 R2.  If you haven’t reviewed our Introduction post on SMA, go check it out here: Automation–An Introduction to Service Management Automation to get the “nickel tour” of all the rundown of Service Management Automation (SMA) and PowerShell Workflow.

SMA_thumb[4]

Once you’ve fully digested that post, this information will make a bit more sense  – at least you’ll have the terms fresh in your brain Open-mouthed smile.  Another great post to review is the Automation—Service Management Automation – Getting Started with SMA Runbooks where we go through the “6 Steps to Success with Getting Started with SMA” that include setup, configuration, testing and execution of SMA Runbooks in your environment.


What’s This Post All About?

For this post I’m going to introduce a collection of example SMA Runbooks that you can use to get acquainted with the platform.  Along the way, we’ll dive a bit into some compare/contrast to show how it is done in Orchestrator and how we’re handling the same process in SMA.  The Orchestrator content in this article: Automation–Orchestrator and the Exchange PowerShell Activity will be elaborated and this post will show you how to translate that solution into a set of SMA Runbooks.  At the end of this post you will be able to see on how things translate from from Orchestrator to SMA.

This post will cover:

  1. Some configuration steps specific to this solution
  2. A series of SMA Runbooks that will
    • Create a distribution list in Exchange (checking first to see if it exists)
    • Read a list of users from a file (this can be any list that you feed it but for this post, a file)
    • Add those users into the distribution list (again making sure the DL exists)
  3. A few points of comparison on how doing this in SMA differs over Orchestrator

On With the Example!

First things first, we need to get some pre-requisite stuff out of the way to ensure you have the best chance of success in getting up and running. We’ll be covering the specific configuration items needed to get this example up in running by leveraging the key steps outlined in the Automation—Service Management Automation – Getting Started with SMA Runbooks.

Ensure Your SMA Environment is Up and Available

Make sure you have SMA installed.  If you haven’t already, refer to our initial intro blog post for more information on that: Automation–An Introduction to Service Management Automation, then come back.

Configure Environment Specific Settings for Creating an Exchange DL with SMA

Next we need to get some specific settings done for Exchange and SMA to get this example executing successfully.

  • Prepare Exchange and SMA for the Runbooks: Go here http://technet.microsoft.com/en-us/library/jj614529.aspx  and follow the steps in the Configure Windows PowerShell and WinRM for the Exchange Admin Integration Pack (only – no need to do the rest).  Essentially we need to get the PowerShell environment all setup to support the automation between the SMA Worker and the Exchange Server.  Some of this you may have already got taken care of if you reviewed the Automation—Service Management Automation – Getting Started with SMA Runbooks post.
  • Create an Input File for Your User List: Create a basic text file with user accounts (UserListFile.txt) that you want to add to your distribution list and put it on your Runbook Worker server in [Default: c:\SMA\content]The example name and location of the file provided here are not critical, we’ll dive into modifying those details that in the overview section below
    Example
    image

Download the Example SMA Runbooks for Creation of an Exchange DL

The sample Runbooks we are going to review in this post are all located on the TechNet Gallery location here: SMA Example - Build Exchange Distribution List (w/PowerShell v3 Workflow) .  Go out and get them downloaded, extracted, and we’ll jump into the process of importing them below.

Validating Connection with Exchange and PowerShell Remoting

The user ID you are leveraging for creating the Exchange Distribution List needs to have the appropriate rights to do so.  We also need to ensure you can connect to the Exchange environment using PowerShell Remoting.

A way to validate rights for the service account you have created / been given, is to make the same connection to your Exchange server in a PowerShell session as you do with the SMA Runbooks being leveraged.  Execute a simple script within PowerShell ISE from the SMA Runbook Worker to validate you have the necessary rights (see below).

Example

001
002
003
004
005
006
$conn = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://ex01.contoso.com/PowerShell/ -Authentication Kerberos -Credential (Get-Credential)
Import-PSSession $conn
Get-User 

#Don't forget to remove the session :)
Remove-PSSession $conn

You should see something like the below output. 

image_thumb

Note   This will only validate you can make a connection and that you’ve setup PowerShell correctly for remote access – you need to ensure the account also has the rights it needs (delegated in Exchange) to perform the operations you are going after.  I’ll be covering some of the code we used to create the Exchange DL in the overview section below, so you could certainly execute that in this session as validation of rights.

Import the Runbooks into SMA

If you have any questions on this process, follow the details outlined here in Step 5: Automation—Service Management Automation – Getting Started with SMA Runbooks.

Once all the Runbooks are imported, you should see within the AUTOMATION section of Windows Azure Pack (WAP) console, a series of (5) Runbooks related to to this project.  We’ll get into some best practices in a later post to show you how to organize these Runbooks, but for now you are ensuring you have the following Runbooks in your view (they may span across pages so you may have to click page 2, 3, etc. to see all Runbooks).

image

Create Your Test Exchange Distribution List

Final step is to test the solution in your environment within the WAP console.  If you need a refresh on executing SMA Runbooks in WAP, all details on how this done can be referenced in the Automation—Service Management Automation – Getting Started with SMA Runbooks.


Overview of SMA Runbooks

Let’s break down each Runbook and talk about how they are all related and key in on some new ideas and constructs to be aware of.

Build-Exchange-Distribution-List

This is the top Process level Runbook that is used to execute the entire process.

  1. Sets the variables for the execution of the entire process
  2. Gathers members to add to a DL from an input file
  3. Creates a DL if one by that name doesn’t already exist
  4. Adds users to the defined distribution list (validating first that the DL exists).
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
workflow Build-Exchange-Distribution-List
{
<#
    Project Name: Build Exchange Distribution List
    Runbook Name: Build-Exchange-Distribution-List
    Runbook Type: Process
    Runbook Tags: Type:Process, Proj:Build Exchange Distribution List
    Runbook Description: Process Runbook for the "Build Exchange Distribution List" Project
    Runbook Author: Charles Joy & Jim Britt
    Runbook Creation Date: 06/20/2013
    #>

   
    $PSCredName = "Contoso Creds"
    $ExchangeServer = "EX01"
    $UserListFile = "C:\sma\content\UserListFile.txt"
    $DomainFQDN = "contoso.com"
    $DistributionListName = "DIST123"
    $DLOU = "contoso.com/rooms"

   
   
    $Members = Get-Users-From-File -UserListFile $UserListFile
   
    $DLCreated = Create-Exchange-Distribution-List -DistributionListName $DistributionListName -DLOU $DLOU -DomainFQDN $DomainFQDN -ExchangeServer $ExchangeServer -PSCredName $PSCredName
    If($DLCreated){
        $UsersAdded = Add-Exchange-Distribution-List-Members -DistributionListName $DistributionListName -DomainFQDN $DomainFQDN -ExchangeServer $ExchangeServer -Members $Members -PSCredName $PSCredName
    }
}

Note   One thing to keep in mind, the “Contoso Creds” above is an SMA credential variable. Variables (credential or otherwise) are located and created in the RESOURCES section within the AUTOMATION area of the portal. SMA credential variables enable you to create and store PowerShell credential objects as connections to resources in your environment.  These can then be referenced by name (as we did above) and leveraged throughout your Runbook execution without hard coding or prompting.  Pretty slick! Laughing out loud
image

Process level Runbooks in SMA function the same as they do in Orchestrator.  They are the top level Runbook that triggers all the subroutine Runbooks.  They essentially control the flow of the Runbook execution.  Take a look at this post where we covered Process level Runbooks as part of our best practice series:  Automation–System Center 2012 – Orchestrator Best Practice Series–Naming Conventions.  To compare / contrast, the above Runbook may look like the below in Orchestrator to accomplish the same task. The highlighted area above would represent variables that would be defined in the Global Settings section within Orchestrator.  We’ll use these throughout the execution of the Runbooks, but define them at the top level Process Runbook (much in the same way we do in Orchestrator).

image

Get-Users-From-File

This subroutine Runbook gets an array of users from a text file. This one is pretty straightforward, but essentially we’re just gathering content from an input file.

  1. Param from process Runbook containing the file name and path to collect required information
  2. Returning the list of users to the process Runbook as an array

Note    This is where I’d recommend getting a bit fancier than I did Hot smile.  Making a connection to Active Directory and obtaining a list of users or from a CMDB, etc.  Static files are rarely a good idea, but they work well for this example.

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
workflow Get-Users-From-File
{
   
<#
    Project Name: Build Exchange Distribution List
    Runbook Name: Get-Users-From-File
    Runbook Type: Subroutine
    Runbook Tags: Type:Sub, Proj:Build Exchange Distribution List
    Runbook Description: Subroutine Runbook for obtaining users from a test file
    Runbook Author: Charles Joy & Jim Britt
    Runbook Creation Date: 06/20/2013
    #>

   
    param(
    [string]$UserListFile
    )
  
    $UserList = Get-Content $UserListFile
    $UserList
}

To compare / contrast, the above Runbook may look like the below in Orchestrator to accomplish the same task. 

image

Create-Exchange-Distribution-List

This subroutine Runbook creates an Exchange distribution list (validates that it doesn’t already exist before creating).

  1. Taking in parameters from the parent Process level Runbook
  2. Checking for the existence of of the defined Exchange distribution list we want to create
  3. If it doesn’t exist, we connect to Exchange using defined credentials and creating the distribution list accordingly
  4. Finally, we close the PowerShell session and return the results to the parent Runbook
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
workflow Create-Exchange-Distribution-List
{
   
<#
    Project Name: Build Exchange Distribution List
    Runbook Name: Create-Exchange-Distribution-List
    Runbook Type: Subroutine
    Runbook Tags: Type:Sub, Proj:Build Exchange Distribution List
    Runbook Description: Subroutine Runbook for creating an Exchange DL
    Runbook Author: Charles Joy & Jim Britt
    Runbook Creation Date: 06/20/2013
    #>

   
    param(
    [string]$ExchangeServer,
    [string]$DomainFQDN,
    [string]$DistributionListName,
    [string]$DLOU,
    [string]$PSCredName
    )
    $PSUserCred = Get-AutomationPSCredential -Name $PSCredName
       
    $DLExists = Get-Exchange-Distribution-List -DistributionListName $DistributionListName -DomainFQDN $DomainFQDN -ExchangeServer $ExchangeServer -PSCredName $PSCredName
    $DLExists
    If(!$DLExists)
    {
        $DLCreated = InlineScript{
            $ConnectionURI = "http://$Using:ExchangeServer.$Using:DomainFQDN/PowerShell/"
            $CreateDLConn = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri $ConnectionURI -Authentication Kerberos -Credential $Using:PSUserCred 
            $CreateDL = Invoke-Command{ 
                param(
                [string]$DistributionListName,
                [string]$DLOU
                )
   
                New-DistributionGroup -Name $DistributionListName -OrganizationalUnit $DLOU 
            } -Session $CreateDLConn -ArgumentList $Using:DistributionListName, $Using:DLOU
            $CreateDL
            Remove-PSSession $CreateDLConn
        } -psComputerName $ExchangeServer -psCredential $PsUserCred
        $DLCreated
    }
}

To compare / contrast, the above Runbook may look like the below in Orchestrator to accomplish the same task. 

image

Get-Exchange-Distribution-List

This subroutine Runbook is used to check for the existence of an Exchange distribution list

  1. Take in parameters sent from the parent Process Runbook
  2. Connect to Exchange with the defined named SMA credential variable
  3. Execute a query against Exchange to determine if the distribution list exists
  4. Clean up the PowerShell session (remove it)
  5. Return the status of the existence of the distribution list to the Parent Process Runbook
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
workflow Get-Exchange-Distribution-List
{
   
<#
    Project Name: Build Exchange Distribution List
    Runbook Name: Get-Exchange-Distribution-List
    Runbook Type: Subroutine
    Runbook Tags: Type:Sub, Proj:Build Exchange Distribution List
    Runbook Description: Subroutine Runbook for validating the existence of an Exchange DL
    Runbook Author: Charles Joy & Jim Britt
    Runbook Creation Date: 06/20/2013
    #>

   
    param(
    [string]$ExchangeServer,
    [string]$DomainFQDN,
    [string]$DistributionListName,
    [string]$PSCredName
    )
    $PSUserCred = Get-AutomationPSCredential -Name $PSCredName
   
    $DLData = InlineScript{
        $ConnectionURI = "http://$Using:ExchangeServer.$Using:DomainFQDN/PowerShell/"
        $GetDLConn = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri $ConnectionURI -Authentication Kerberos -Credential $Using:PSUserCred 
        Try{
            $GetDL = Invoke-Command{ 
                param(
                [string]$DistributionListName
                )
   
                Get-DistributionGroup $DistributionListName -ErrorAction SilentlyContinue
            } -Session $GetDLConn -ArgumentList $Using:DistributionListName
        $GetDL
        } 
        catch{}
        Remove-PSSession $GetDLConn
    } -psComputerName $ExchangeServer -psCredential $PSUserCred
    $DLData
}

To compare / contrast, the above Runbook may look like the below in Orchestrator to accomplish the same task. 

image

Add-Exchange-Distribution-List-Members

This subroutine Runbook adds the users gathered from the input file into the targeted Exchange distribution list

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
workflow Add-Exchange-Distribution-List-Members
{
   
<#
    Project Name: Build Exchange Distribution List
    Runbook Name: Add-Exchange-Distribution-List-Members
    Runbook Type: Subroutine
    Runbook Tags: Type:Sub, Proj:Build Exchange Distribution List
    Runbook Description: Subroutine Runbook for adding users to an Exchange DL
    Runbook Author: Charles Joy & Jim Britt
    Runbook Creation Date: 06/20/2013
    #>


    param(
    [string]$ExchangeServer,
    [string]$DomainFQDN,
    [string]$DistributionListName,
    [string[]]$Members,
    [string]$PSCredName
    )
    $PSUserCred = Get-AutomationPSCredential -Name $PSCredName
   
    $DLExists = Get-Exchange-Distribution-List -DistributionListName $DistributionListName -DomainFQDN $DomainFQDN -ExchangeServer $ExchangeServer -PSCredName $PSCredName
    If($DLExists)
    {
        $DLMembersAdded = InlineScript{
            $ConnectionURI = "http://$Using:ExchangeServer.$Using:DomainFQDN/PowerShell/"
            $AddMemberDLConn = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri $ConnectionURI -Authentication Kerberos -Credential $Using:PSUserCred 
            $AddMemberDL = ""
            foreach($Member in $Using:Members) 
            { 
                $AddMemberDL += Invoke-Command{ 
                    param(
                    [string]$DistributionListName,
                    [string]$Member
                    )

                    Add-DistributionGroupMember -Identity $DistributionListName -Member $Member 
                } -Session $AddMemberDLConn -ArgumentList $Using:DistributionListName, $Using:Member 
            }
            $AddMemberDL
            Remove-PSSession $AddMemberDLConn
        } -psComputerName $ExchangeServer -psCredential $PSUserCred
        $DLMembersAdded
    }
}

To compare / contrast, the above Runbook may look like the below in Orchestrator to accomplish the same task. 

image


That’s it!  I hope this post has provided you with a helpful overview of an end-to-end example solution in SMA and how it compares to what can also be accomplished in Orchestrator. Thanks for reading!

Oh, and if you want more examples for SMA and PowerShell v3 Workflow, be sure to check out this list (to be updated as more examples are provided):

And 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!

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • Great and very interesting blog. I think it’s also an informative. Thanks for sharing.

  • 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,

    Stijn

  • @New York Warehousing - thanks for the feedback.  We'll get more examples out as time permits, and we appreciate your interest!

    @Stijn -- my response became so big that I've decided to create a blog post on it.  That will be coming in the next 24 hours hopefully :).

  • @Jim - thanks, will wait for the blog post.

    After reading my own comment it reads kind of funny. So a small rephrase:

    Why use remoting twice?

    Once for executing the inlinescript on the exchange server and then creating a session to the same exchange server?

  • @Stijn C, this will also be detailed as part of the post that will come out tomorrow (I'll update the thread when it releases) but this is the short answer to your question:

    ----

    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.

    ----

    As always, there are many ways to get to the same conclusion.  You may also have find an alternate approach to what we've done and you can share that as well here - I'd encourage in fact.  The blog post tomorrow in the AM PST, will cover "$Using:Variable" as well as leveraging the credentials variables in SMA.  Probably beyond your question but it sparked a good topic to share either way :).

  • @Stijn - the related blog post covering $Using:Variable and InlineScript has been posted here: blogs.technet.com/.../automation-service-management-automation-tip-trick-leveraging-inlinescript-and-using-variable-with-powershell-workflow.aspx

    Thanks again for the feedback and questions.  If nothing else, the above post will help drive home some concepts around workflow in a bit more detail.

  • Gorgeous post ,An amazing article once again I am wondering the code is well written you effort and blog both are admirable thanks dude give awareness by this post .Click here .