Last month, in “Make PowerShell Clever with Decision-Making,” I showed you how to use If/Else statements to give PowerShell the necessary decision-making capability to effect some otherwise tedious Active Directory (AD) housekeeping. But that decision-making was sort of simple. It chose from two mutually exclusive and collectively exhaustive situations: Do you have a middle initial, or do you not? This month, I’ll show you a more complex bit of housekeeping that you’ll accomplish by creating another, more complex script, and in the process you’ll meet the switch statement. You’ll also meet a PowerShell cmdlet called move-adobject that lets you move user accounts around inside a domain.
Imagine the following simple but nontrivial problem. You’ve been running an AD environment for quite some time, and over the years you’ve been diligent about filling the Office AD attribute for each user with the name of the city where he or she works. (ADSIEdit and LDAP show the attribute as PhysicalDeliveryOfficeName, but the Directory Services folks have kindly renamed the attribute to just Office in the AD cmdlets.) Let’s also say that your organization has seven offices, located in Woodstock and Farmville (Virginia); Lima and Dublin (Ohio); and Bellevue, Seabrook, and Miami (Texas). That organization has worked well for you, but now you’ve decided to reorganize things a bit, creating OUs named Virginia, Ohio, and Texas. Your task is to populate those OUs and—as you’ve probably guessed—you’d like PowerShell to move each user account into its correct OU based on the current value of Office in that user account.
Now, I can think of many ways to solve this problem, but I want to focus on the very useful PowerShell switch statement. Essentially, you’ll instruct PowerShell to examine every user, one by one, and for every user it finds, you’ll have a piece of PowerShell code that says, for example, “If office=Woodstock, move the user to the Virginia OU, or if office=Farmville, move the user to the Virginia OU, or if office=Lima, move the user to the Ohio OU…,” and so on. (Yes, the If and Else statements you learned last month would work, but they would be cumbersome.)
You’re going to do this with a script rather than a one-liner because a one-liner would be insanely ugly. Because you’ve built only a couple of scripts so far, let me back up a bit and offer some advice on how to get started writing a script. Many folks who do any kind of coding—whether it’s PowerShell scripts, VBScript, C#, or whatever—start from something called pseudocode, a mix of English and programming-ese. There are no rules for pseudocode; you just do whatever works to help you sketch out what you’re trying to do. Here’s my sample pseudocode for this job:
Collect all AD users and stuff them into the pipeline For each user in the pipeline: Grab the user’s name and the value of his or her “office,” and store them into variables If Office=Woodstock, move the user to the Virginia OU If Office=Farmville, move the user to the Virginia OU If Office=Miami, move the user to the Texas OU If Office=Dublin, move the user to the Ohio OU [all the If statements for the remaining offices] If the user isn’t in any of those offices, don’t move him/her
Notice that I’m abstracting what I plan to do. I’m using indenting to show what will happen in the eventual ForEach loops. So, what’s the PowerShell syntax to get these tasks done? How on Earth do I move an AD user? Can PowerShell do that? I do know that AD lets me move uses from one OU to another within a domain, so I expect that PowerShell can accomplish that somehow. The beauty of pseudocode is that it lets me lay out a plan without getting bogged down in the syntax details.
The next step? If you’re a regular Windows Power Tools reader, you already know some of the important syntax, and clearly you could cook this thing up with a pile of If/Then statements rather than this switch statement. But you’d be brought up short while trying to move that AD object, so figuring out which cmdlet gets that job done should be your next focus. A tiny amount of get-command and get-help reveals a cmdlet called move-adobject that has pretty easy syntax:
move-adobject DN-or-GUID-of-object DN-or-GUID-of-destination
It’s a lot like other tools I’ve shown you, but SAMAccountNames and SIDs need not apply. For example, to move a user named Tom in the Users container to the Virginia OU in bigfirm.com, you’d type
move-aduser "cn=Tom,cn=Users,dc=bigfirm,dc=com" "OU=Virginia,dc=bigfirm,dc=com"
The cmdlet is picky about needing those double quotation marks, so don’t skip them! Now, we can get a little closer to assembling this script—which we’ll do next month. See you then!