Make PowerShell Clever With Decision-Making

Make PowerShell Clever With Decision-Making

This example involving middle names shows you how

Over the past couple months, in “Cryptic PowerShell One-Liner to Clarified Script, Part 1” and “Cryptic PowerShell One-Liner to Clarified Script, Part 2,” we’ve created a nicely formatted, easy-to-read script that reconstructed every user account’s DisplayName by combining each account’s GivenName attribute, a space, and its sn attribute, and using that to replace the existing DisplayName. That’s a pretty cool capability, but in all honesty, it’s not quite the whole job. Building a complete DisplayName, you see, is a little more complex—as you’ll see this month.

The shortcoming in our approach is that we’ve ignored Active Directory’s (AD’s) Initials attribute. If a user’s GivenName is “Susan,” her Initials value is “T,” and her sn is “Wallace,” then with our current script we’d end up populating her DisplayName attribute with “Susan Wallace,” rather than the more complete (and probably preferred) “Susan T. Wallace.”

Why is that so difficult? Why not just take the current line of our script that says

set-aduser $_ -displayname ($_.givenname + " " + $_.sn)

and just add Initials, a period, and a space, as in

set-aduser $_ -displayname ($_.givenname + " " + $_.Initials+ ". " + $_.sn)

That wouldn’t work because not everyone has or chooses to use a middle initial. Folks who forego the initial would end up with a DisplayName built of their first and last names but with a space, a period, and a space in between them. (Trust me, this messing-with-names thing isn’t trivial. Delta Airlines has been slowly converting my name from “Mark Jerome Minasi” to a first name of “Mark Jerome,” no middle initial, and “Minasi” as the last name, to my current moniker, “Markjerome Minasi.” It’s going to earn me a rubber-glove session with some TSA agent one day, I fear.)

The unreliably existent nature of initials means that we’re going to need to be ready to execute either the first set-aduser command or the second one, depending on whether the user has an initial. One way to tackle this would be to replace the first and simpler set-aduser with another approach. We might start off by first constructing the two possible values for a user’s DisplayName, then choose which to use based on whether there’s an initial. For example, we could construct a no-initial name into a variable $dn1, then an including-initials name into another variable named $dn2, like so:

$dn1 = ($_.givenname + " " + $_.sn)
$dn2 = ($_.givenname + " " + $_.Initials+ " ". + $_.sn)

Once we have those, we would then figure out which to use. One approach would be to create a third variable with a name like $goodname and make it equal to either $dn1 or $dn2 based on whether the user has an initial, as in (not real PowerShell code):

IF this user has no initial, THEN $goodname=$dn1 ELSE $goodname=$dn2

To do that, we need to see how to test whether $_.Initial is empty (“null” in many languages, including PowerShell). In PowerShell, we can test any value’s null-ness by comparing it with a built-in PowerShell variable named $null. That test would look like (in our not-yet-official-PowerShell syntax):

IF ($_.Initials -eq $null) THEN $goodname=$dn1 ELSE $goodname=$dn2

To write that in official PowerShell-ese, let’s look at how PowerShell expresses If/Then/Else situations. It looks like

If (test condition) {commands to execute if true} Else {commands to execute otherwise}

So, “If” needs a condition as well as two “scriptblocks”—one or more commands separated by a semicolon, surrounded by braces. Here’s the simplest (but silliest) example I can think of:

If (1 –eq 1) {“They are equal.”} else {“Those things are different.”}

Run that, and you’ll see the text “They are equal.” Change one of the 1s, and you’ll get the other message. Our crucial decision, then, can be expressed in PowerShell as

If ($_.initials -eq $null) {$goodname = $dn1} Else {$goodname = $dn2 }

With that done, we can do the final work of setting the DisplayName like so:

set-aduser -Displayname $goodname

Putting it all together, we can assemble our more complete DisplayName fixer:

$AllUsers= ( get-aduser -filter * -properties *) |
foreach {
                $dn1 = ($_.givenname + " " + $_.sn)
                $dn2 = ($_.givenname + " " + $_.Initials+ ". " + $_.sn)
                If ($_.Initials -eq $null)
                                {$goodname = $dn1 }
                                Else {$goodname = $dn2 }
                set-aduser $_ -DisplayName $goodname
}

What’s that? You don’t want to have to save that into a file? You want a one-liner? Well, OK, but it ain’t gonna be pretty, and remember, type it all on one line, even if it’s broken on the page (and do this only in a test AD environment!):

$AllUsers= ( get-aduser -filter * -properties *) | % {    $dn1 = ($_.givenname + " " + $_.sn); $dn2 = ($_.givenname + " " + $_.Initials+ ". " + $_.sn); If ($_.Initials -eq $null) {$goodname = $dn1 } Else {$goodname = $dn2 }; Set-aduser $_ -DisplayName $goodname}

Sometimes a script is a far better delivery mechanism than a one-liner. See you next month!

Hide comments

Comments

  • Allowed HTML tags: <em> <strong> <blockquote> <br> <p>

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
Publish