Thanks, Ed, and thank you for the opportunity to put this series of articles together.

This is the last article of this series on Windows PowerShell workflows but by no means the last word on the subject. Workflows is a new concept with Windows PowerShell and, like all new concepts, it needs to be tested and experimented with to determine where it best fits into our administrator’s toolbox.

For this article, I thought I’d pull together the various strands of the series and present the development of a workflow. The scenario involves an organization that is expanding. It keeps creating new offices and needs to automate as much as possible of the IT administration associated with those new offices coming online. The list of activities that has to be performed includes:

Create OU – parent OU for location

Create Users OU as child

Create Computers OU as child

Create UPN

Create accounts

Create 35 computer accounts in correct OU

Create 35 user accounts in correct OU

Create home drives

Create AD Site

Create AD subnet & link to site

Create AD Site Link

Link GPOs

Link GPO to Users OU

Link GPO to Computers OU

The first and most important point is that this doesn’t need to be done as a workflow. I’d be surprised if there is any task that has to be performed as a workflow. It may be more complicated as a suite of scripts, but it will be possible. Having said that, we will use a workflow.

The big thing that workflows bring is parallelism, so you need to decide what can be done in parallel and what must be done sequentially. The other factor for the design is the order in which things happen, for instance, you need to create the OUs before you create the user accounts.

Programmers have a concept called pseudo-code. It is used to map the logic of a piece of code under development. It’s not something that many scripters use, but for complicated situations like this, it can save a lot of rework.

If you turn the list of requirements into pseudo-code, you get something like this:

workflow pseudocode {

parallel {

create parent OU

create UPN

create AD site

}

parallel {

sequence {

create users OU

read user data

parallel {

create user accounts

create home drives

}

link GPO to users OU

}

sequence {

create computers OU

read computer data

parallel {

create computer accounts

}

link GPO to computers OU

}

sequence {

create AD subnet

create AD site link

}

}

}

Start with a parallel block to create the top OU, AD site, and UPN. These can be performed in parallel because there is no interaction between them. The bulk of the workflow occupies a parallel block that contains three sequence blocks—one for user accounts, one for computer accounts, and one for the remaining Active Directory topology. Within the sequence blocks, there is some scope for performing tasks—such as creating users—in parallel.

There are other possible ways to group these tasks—this is the way that it works for me. The workflow after some development and testing comes out like this:

These tasks can be performed in parallel. There are no links or dependencies between the three tasks, so you don’t care about processing order. The New-ADReplicationSite cmdlet is new in Windows Server 2012. If you don’t have access to the cmdlet, you can modify this script:

Moving into the bulk of the script, you have three sequence blocks that are processed in parallel. This where the real power of a workflow lies—you can create user accounts; computer accounts, and modify the Active Directory topology all in one pass. The first sequence block creates the user accounts:

An OU is created for the user accounts. The locationname variable is referenced in a number of places. You are using the variable that is defined in a higher scope, and as you are working with parallel/sequence block, you just need the variable name.

A password is set. No, I wouldn’t do this in production—I’d pass it in as another parameter. Never code passwords in production scripts! The user information is read from a CSV file. In this case, the file contains first name; last name, and logon ID. Other data can be easily added and other parameters on the New-ADUser cmdlet utilized. If you have not used that cmdlet, I recommend looking at the Help file to see what is available. One oddity is the way I’ve had to create the name of the user account—pure string substitution didn’t work and you can’t use subexpressions in workflows.

I’ve hard-coded the file name, but the workflow could be modified to have the location name as part of the work flow. How about the idea of using the Windows PowerShell event engine to watch a particular folder. When a new file is dripped into it, the event triggers and runs the workflow! You can’t get much more automated than that!

The user account creation is performed using a foreach –parallel loop. These are freakily powerful. In this case, 35 user accounts created in parallel. The account creation and home drive creation steps are executed in sequence, but the 35 sets of that activity are performed in parallel. Trying to keep track of where the workflow is at a particular time is an interesting job. I think that with something like this it is only possible if you log the individual steps with timestamps.

An OU is created for the computer accounts. I want to create 35 computers. I’ve hard-coded this for simplicity, but again, this could be a parameter. Alternatively, you could count the number of user accounts you are creating and create one computer account per user.

I’m using string formatting to create the computer name according to the organization’s naming convention. That is passed into New-ADComputer. A foreach –parallel loop is used again to maximize the parallelism of the workflow.

These would have to be used via an Inlinescript block. Remember you will need the “using” keyword to access variables from the higher parts of the workflow.

My hope is that this series of articles has shown you the power of workflows and how to get started using them. They are a very powerful resource that the Window PowerShell community is just starting to understand. This series is a step on that journey to understanding but is by no means the last. I would encourage you to experiment with workflows in your environment and share what you discover with the Windows PowerShell community. I can be contacted via my blog.

I suspect this won’t be my last word on workflows but until then—enjoy!

~Richard

Richard, thank you for a superb effort, a wonderful series, and an awesome amount of really great information on Windows PowerShell workflows.

Hey, I see that you have a very deep knowledge on workflows. I’m making a installation script that installs in silent mode a list of applications. Some of them require a reboot, so I thought of workflows to achieve the "Reboot and Restart" feature. I would
like a workflow than is able to wrap this functionality (cheking if a reboot is required, reboot if so and execute an arbitrary function after the reboot.