Guy’s Scripting Ezine 127 – PowerShell And Active Directory

Guy’s Scripting Ezine 127 – PowerShell And Active Directory

 ♣

This Week’s Secret

I always believed that PowerShell would support Active Directory.  If not, then how could it possibly manage Exchange 2007?  The hidden message is don’t believe everything that you read, double-check important information, research keywords in your favourite browser.  To be fair, beta and RC software reminds me of pre-season games where the coaches try different formations.  Once the season proper arrives (the product is actually released), the team has a different look with all the key personnel in their best positions.

One unfortunate by-product of the beta program is that some commands that worked in Monad or PowerShell RC1, do not work in RC2, for example,
$root.get_Children()   No longer works, instead try:
$root.psbase.children  This displays the distinguishedName of the OUs.   It’s unfair but we have to adapt, a bit like a sports league changing the offside rule just before the season starts.  My message is check your PowerShell version against the version of any scripts that you copy.

My copy of PowerShell RC2 reports as FileVersion 6.0.5429.0.  To check your version, try this command
Get-command PowerShell | format-list

With PowerShell my main message remains, it’s easy to get started.  That said becoming even a minor expert may be more challenging that I first thought.  As ever, our saving grace is that we can copy paste and amend other people’s scripts – more research with your favourite browser.

This Week’s Mission

This Week’s Mission is to connect to Active Directory using PowerShell commands.  Our ultimate goal, which cannot be achieved in one ezine, is to do with PowerShell everything we coded with VBScript.  Even if we merely achieve the same objectives as before, we will do so by using fewer PowerShell commands.  All the while we will gradually develop skills that are going to be useful in Exchange 2007 and Longhorn.

One feature of scripting with PowerShell is that the commands may look few and simple, but nevertheless they deliver awesome results.

This week’s featured syntax element is the tiny ` 

To be clear, I am talking about `, the top left key on your keyboard.  The character corresponds to ASCII 96, a fact which you can confirm by holding down the Alt key and typing 96 on the numeric keypad.  The benefit of ` is for controlling output such as tab (`t) and carriage return (`r or `n).  Used on its own ,` enables commands to be split over two lines.  (Sometimes word-wrap may cause complications.)

Example 1 – Query Active Directory using a hard-coded domain name

Prerequisites

  1. Install PowerShell RC2
  2. Important: Change $Dom to reflect the LDAP name of your domain
  3. Copy and paste the example below into notepad.  Save the file with .ps1 extension. 
    For example: c:\ scripts\ADUsers.ps1
  4. In powershell cd c:\ scripts
  5. From the command line issue this command: .\ADUsers  (Note; dot backslash adusers)
  6. If the above does not work try typing c:\ scripts\adusers

# ADUsers.ps1
# Illustrates using PowerShell for connecting to AD
# Connect to hard-coded active directory root
# Author: Guy Thomas
# Version 2.1 October 2006 tested on PowerShell RC2

$Dom = ‘LDAP://DC=cp;DC=mosel’
$Root = New-Object DirectoryServices.DirectoryEntry $Dom
cls
Write-host "PowerShell connects to domain: $Dom `n"

# Create a selector and start searching from the Root of AD
$selector = New-Object DirectoryServices.DirectorySearcher
$selector.SearchRoot = $root

# Filter the users with -like "CN=Person*". Note the ForEach loop
$adobj= $selector.findall() `
| where {$_.properties.objectcategory -like "CN=Person*"}
foreach ($person in $adobj){
$prop=$person.properties
Write-host "First name: $($prop.givenname) " `
"Surname: $($prop.sn) User: $($prop.cn)"
}
"There are $($adobj.count) users in the $($root.name) domain"

Guy Recommends:  SolarWinds’ Free Bulk Import ToolFree Download Solarwinds Bulk Import Tool

Import users from a spreadsheet.  Just provide a list of the users with their fields in the top row, and save as .csv file.  Then launch this FREE utility and match your fields with AD’s attributes, click and import the users.

Optionally, you can provide the name of the OU where the new accounts will be born. Download your FREE bulk import tool.

If you need more comprehensive software, download a free trial of SAM (Server & Application Monitor)

Learning Points

Note 1: New-Object is such an insignificant command, yet it is vital for connecting to Active Directory.  Incidentally, another job for new-object is for creating COM objects, the benefit is that you can then manipulate applications such as Internet Explorer or Winword.exe.

Note 2: DirectoryServices.DirectoryEntry is one of the key commands to create an Active Directory object.  I think of this as a connection or pipeline to the root of my domain’s namespace.

Note 3: ‘LDAP://DC=cp;DC=mosel’.  Rather than using the traditional .local namespace for non-internet domains, I prefer the .mosel merely as it happens to be the road where I live.  Naturally you changed the value for this variable in your live script?  Didn’t you?

Note 4: DirectoryServices.DirectorySearcher creates a search object, a gopher that trawls Active Directory. Observe that .DirectorySearcher is different from .DirectoryEntry.

Note 5: I introduced a ‘Where’ clause to filter the active directory objects, also note the pipe command at the start: | where {$_.properties.objectcategory -like "CN=Person*"}

Note 6: foreach ($person in $adobj){   Here we have a straightforward looping command.  As always, pay attention to the type of brackets, PowerShell places significance on whether the command is enclosed by {braces}, [square] or (round) brackets.

Note 7: Write-Host an easy command to output the results to the screen rather than a text file.

Note 8: I have already introduced the ` character.  Trace how I use this ASCII character 96 to force a new line and also how I employ ` to join two lines of code, that would otherwise produce one long line that may, or may not, word-wrap when copied to your machine.

Guy’s Challenges

Challenge 1:  Experiment with different filters instead of:
where {$_.properties.objectcategory -like "CN=Person*"    Try | where {$_.properties.displayname -notlike ""}

Better still, invent your own filters.

Challenge 2:  Refresh your knowledge of LDAP properties.  Then experiment with different values for $($prop.sn), for example $($prop.displayname) .company, .description and .dn.

Guy Recommends: Tools4ever’s UMRAUMRA The User Management Resource Administrator

Tired of writing scripts? The User Management Resource Administrator solution by Tools4ever offers an alternative to time-consuming manual processes.

It features 100% auto provisioning, Helpdesk Delegation, Connectors to more than 130 systems/applications, Workflow Management, Self Service and many other benefits. Click on the link for more information onUMRA.

Example 2 – Query an Active Directory named OU.  Script calculates LDAP domain name

Confession time.  Everyone else uses hard-coded LDAP domain names, such as ‘LDAP://DC=cp;DC=mosel’ in Example 1.  One reason I seek scripts that calculate the domain automatically is that it saves readers a job and is therefore one less thing that can go wrong with a script.  Another reason that I choose this convoluted method is that as the operating system knows the domain name, therefore we should be able to create a script to winkle out the LDAP value for our domain.  While I am in confession mode, I believe that this script could be a lot better and more efficient, therefore any suggestions for improvement will be gratefully received.

Pre-requisites

  1. Install PowerShell RC2
  2. Important: Change $OU = "/OU=Accounts,".  Either use "/CN=Users," or else use one of your OUs.
  3. Copy and paste the example below into notepad.  Save the file with .ps1 extension. 
    For example: c:\ scripts\ADLDAP.ps1
  4. In powershell cd c:\ scripts
  5. From the command line issue this command: .\ADLDAP(Note dot backslash adusers)
  6. If the above does not work try typing c:\ scripts\adldap

# PowerShell RC2 adLDAP
# ADLDAP.ps1
# Illustrates using PowerShell for connecting to AD
# Connect to hard-coded active directory root
# Author: Guy Thomas October 2006
# Version 3.1 for PowerShell RC2
# ———————————————————-
# Prepare, locate, connect to the LDAP name of the container
cls
$OU = "/OU=Accounts,"
$Root = [ADSI]”
$DN = $Root.DistinguishedName

# Strip the DC= from LDAP Root name
$a = $DN -as[string] -ireplace "dc=", ""
$h = @{}
$a = $a.split(",")
$h.Dom = $a[0]
$h.Top = $a[1]

$Domain = $h.Dom
$LDAP = "LDAP://$Domain$OU$DN"

# Create a selector and start searching from the root
$selector = New-Object DirectoryServices.DirectorySearcher
$selector.SearchRoot = $LDAP

# ———————————————————–
# Filter the users with -like "CN=Person*". Note the ForEach loop
$adobj= $selector.findall() `
| where {$_.properties.objectcategory -like "CN=Person*"}
foreach ($person in $adobj){
$prop=$person.properties
Write-host "First name: $($prop.givenname) " `
"Surname: $($prop.sn) Account: $($prop.cn)"
}
"There are $($adobj.count) users in the OU called $OU"

Learning Points

Trap: $Root = [ADSI]”  This seems strange, but it works.  Please note that these are two single quotes and not a double quote.

Readers’ Help

I know you are busy, but you I really appreciate help by sending in a PowerShell script, or a suggestion of what you want, how you learn or what you like.   You can see by my previous responses that readers help has been invaluable in shaping this ezine.

Summary of PowerShell And Active Directory

Good news PowerShell RC2 can connect to Active Directory.  Here are two straightforward script that employ DirectoryServices.DirectoryEntry and .DirectorySearcher to interrogate domain objects.  There is much to learn as each work in a PowerShell script is loaded with meaning.

If you like this page then please share it with your friends

 


See more Windows PowerShell tutorials

PShell Home   • Introduction   • Dreams   • 3 Key Commands   • PowerShell Help About   • Get-Help

PowerShell v 3.0   • Set-ExecutionPolicy   • Get-Command   • Cmdlet scripts   • Import-Module

PowerShell Version Check   • Backtick   • PowerShell examples   • PowerShell ISE   • Get-Member

Please email me if you have a better example script. Also please report any factual mistakes, grammatical errors or broken links, I will be happy to correct the fault.