The Surly Admin

Father, husband, IT Pro, cancer survivor

Get the FQDN for your OU’s

As I have delved into Powershell more and more, I’ve noticed that a lot of the Microsoft cmdlet’s require the use of FQDN’s and finding that full name isn’t as easy as it really should be.  Typically I have to go into ADSI Edit, drill down the Active Directory tree and then go into the properties of the object I want and locate the cn property.  The FQDN I find myself needing most often is for my Organization Units (OU’s).  Here’s a little function I created to help me find that information quickly and painlessly–it even puts the information into the clipboard so you can paste it into your script with ease.  Read on, fearless readerer!

Background

It’s always a good idea to know what you want your script to accomplish before you start writing it, and a general idea of how you want it to present to the user.  Since most scripts are written to accomplish administration tasks you don’t have to get too complex with user presentation.  The audience for this script is experienced IT Pro’s so I’ve made the presentation about as basic as you can get.  It’s a simple text menu where you select the item you want and then the script does it’s thing.

I used the Get-ADOrganizationalUnit cmdlet for this script, so you’ll need to have RSAT already loaded.

The Script

So let’s run through the script, and then I’ll talk about how to actually implement it.  First thing we need to do is get a parameter for searching the OU’s.  You’ll want this if you have a lot of OU’s and don’t want to see them all in the menu.  Just put in a search string and any OU that contains that string anywhere in the FQDN will be displayed.

Param (
 [string]$Search
 )
Import-Module ActiveDirectory -ErrorAction SilentlyContinue

Also go ahead and load the ActiveDirectory module from RSAT if it’s not already loaded (I load mine automatically in my $PROFILE).  Next I want to get all of the OU’s from your Active Directory, use the Where statement to include your search string (if any) and then sort it by the name of the OU then stash the information into a variable.

$OUs = Get-ADOrganizationalUnit -filter * | where { $_.distinguishedname -like "*$Search*" } | Sort Name

Next I want to build the menu:

$MenuItem = 0
 cls
 Write-Host "Select the OU you want and the LDAP value will be copied to the clipboard.`n"
 ForEach ($OU in $OUs)
 { $MenuItem ++
 $MenuText = ($OU | Select Name,DistinguishedName | Format-Table -HideTableHeaders | Out-String).Trim()
 If ($MenuItem -lt 10)
 { [string]$Select = " $MenuItem"
 }
 Else
 { [string]$Select = $MenuItem
 }
 Write-Host "$Select. $MenuText"
 }

Couple of things to explain here.  First is the $MenuText line.  What in the name of heck am I trying to do here?!  So even though I have a very basic interface here, I still want it to look presentable because if it’s too hard to read you won’t use it.  The idea here is I want to print a menu number (that’s $MenuItem), the Name of the OU and then the FQDN of the OU (since Name is not a unique value).  But I’d like everything to line up nicely and look good.

Now, I could do the old fashion way of using variables with a bunch of spaces, then use Length to cut it down and build the menu up and all that, but it occurred to me that the Format-Table cmdlet does all that for output.  Wouldn’t it be cool if I could use that?  Turns out I can, but there were a few issues to deal with.  First we need to limit the number of fields to just the 2 we want:

[Sourcecode language=powershell]
$OU | Select Name,DistinguishedName
[/sourcecode]

Easy enough so far.  Then pipe that into Format-Table, but ran into a problem right off the bat.  Format-Table includes a header row so you can see what column is what.  Well, in this case I didn’t want that.  So I consulted Get-Help Format-Table -Full and found the -HideTableHeaders parameter.  Perfect!  But then I ran into another problem, which is the Format-Table outputs a System.Array object and I need a String type.  Why do I need a string type, you ask?  Well the other thing Format-Table does is put a bunch of carriage returns at the end of the text, and I don’t want those.  So I have to then output my headerless table into the Out-String cmdlet to convert it to string.  That’s great, but what about those carriage returns?  Wrap the entire thing in parenthesis (think of it as gathering all of the output together) and then use the .Trim() method to remove those blanks.

($OU | Select Name,DistinguishedName | Format-Table -HideTableHeaders | Out-String).Trim()

It’s not perfect as very long OU’s will wrap around the screen depending on the size of your window, but this accomplishes the goal good enough.  I could start chopping the end’s of the OU’s off to fit the screen but I have no way of knowing if that’s the information you actually need so I’d rather display some of it ugly but have the information there then have it not be there and be a frustration.

The next problem came with the MenuItem piece.  So to present a nice numbered menu we use this variable and then increment it after we display each line.  But items 1-9 are 1 digit in length, and 10+ are 2 so my menu was suddenly offset by one digit for the first 9 items!  So we do a quick check of the $MenuItem and add a space in there for looks.  Now, if you have hundreds of OU’s, sorry you’re on your own!  You’ll need to use the -Search parameter to cut things down anyway as the menu would just be a mess.

Now we need to prompt the user for what OU they want to use.

$Prompt = Read-Host -Prompt "`n`nEnter number of the OU you want"
 If (-not $Prompt)
 { Break
 }
 Try
 { $Prompt = [int]$Prompt
 }
 Catch
 { Write-Host "`nSorry, invalid entry. Try again!"
 Break
 }
 If ($Prompt -lt 1 -or $Prompt -gt $MenuItem)
 { Write-Host "`nSorry, invalid entry. Try again!"
 }
 Else
 { Write-Host "`n`n$($OUs[$Prompt - 1].distinguishedName) copied to clipboard"
 $($OUs[$Prompt - 1].distinguishedName) | Clip
 }

The first check is to see if the user just hits the ENTER key (which produces a $null value).  If we detect that just exit the script.  The next part is about converting the entry the user put in to a integer.  Normally Read-Host creates a string value but we need to check if the user made a valid menu choice, and those are numbers/integers.   To convert it I just use the [int] clause, but the problem comes that if the user typed “Hello” the conversion will fail, and throw an error.  That’s where Try/Catch comes in.  Try essentially says do these commands between { and } (this is known as a scriptblock) but if you have an error, go to the Catch scriptblock and execute those commands.  Otherwise just keep going.

Good, now $Prompt is an integer and I can test if they put in a valid number, if not throw an error and exit the script.  But if it’s a valid number then write on the screen the result and then copy the OU into the clipboard.

Clip.exe is a program (not a cmdlet) that comes with Windows and allows you to pipe information into it and it will place that information into the clipboard.  Nice, easy and clean method.  I would have preferred a Powershell cmdlet for this but there aren’t any native ones (though plenty of people have written their own functions).

Implementation

The intention of this function was always to be put in my custom $Profile so it will always be available to me.  Follow the link to read about the Powershell Profile and create your own.

Usage

Pretty easy to use at this point!

Get-OULDAP

Would present you a full list of all of your OU’s–no screen shots to protect the innocent, I really need to get a test environment built–select the one you want and paste the results into your script/cmdlet.

Narrow down your OU search by using the -Search parameter:

Get-OULDAP -Search foo

The search is not case sensitive, by the way.  That’s it.  The full source code has been posted on Spiceworks and includes full comment-based help so don’t forget to:

Get-Help Get-OULDAP -Full

Hope you find it helpful.

Advertisements

October 4, 2012 - Posted by | PowerShell | , , , ,

4 Comments »

  1. […] an OU–the reason for this is knowing the full FQDN of an OU can be a pain (though I do have a script for that).  Second goal is I wanted to validate the OU was correct by using the Get-ADOrganizationUnit […]

    Pingback by Who’s Logged in Where? « The Surly Admin | November 15, 2012 | Reply

  2. […] that retrieves all of your OU’s and want to pick one and save it in your clipboard?  Get-OULDAP.   Honestly have to come up with a better noun […]

    Pingback by Usings Verbs and Nouns « The Surly Admin | January 17, 2013 | Reply

  3. Heya are using WordPress for your blog platform? I’m new to the blog world but I’m trying
    to get started and set up my own. Do you need any html coding knowledge to make your own blog?
    Any help would be really appreciated!

    Comment by Randi | October 2, 2014 | Reply

    • It is WordPress, from WordPress.com. No HTML coding needed, but it doesn’t hurt.

      Comment by Martin9700 | October 2, 2014 | Reply


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: