OU Management with PowerShell

I’ve got a few questions on Active Directory Organizational Unit management with PowerShell so I thought I would post a few examples on OU-related operations (using Active Directory cmdlets - note that for some of those like browsing OUs using AD provider is a viable alternative).

The first thing obstacle that you meet when deciding to start working with OUs is that at the moment (in version 1.0.1) specific cmdlets for OUs have not made it into the snapin yet. Which of course won’t stop us - as there are the wonderful *-QADObject cmdlets that help us survive while waiting for all type-specific cmdlets to become available.

So here we go:

Get the list of OUs:

PS C:> Get-QADObject -Type OrganizationalUnit  

Name               Type               DN
----               ----               --
Domain Controllers organizationalUnit OU=Domain Controllers,DC=ps64,DC=local
Microsoft Excha... organizationalUnit OU=Microsoft Exchange Security Groups,DC=ps64,DC=local

Create New OU in domain root:

PS C:\> New-QADObject -Type organizationalUnit -Name TestOU -ParentContainer ps64.local/

Name               Type               DN
----               ----               --
TestOU             organizationalUnit OU=TestOU,DC=ps64,DC=local

Create 5 test users in the new OU:

PS C:> 1..5 | ForEach { New-QADUser -ParentContainer ps64.local/TestOU -Name ("TestUser" + $_)}

Name               Type               DN
----               ----               --
TestUser1          user               CN=TestUser1,OU=TestOU,DC=ps64,DC=local
TestUser2          user               CN=TestUser2,OU=TestOU,DC=ps64,DC=local
TestUser3          user               CN=TestUser3,OU=TestOU,DC=ps64,DC=local
TestUser4          user               CN=TestUser4,OU=TestOU,DC=ps64,DC=local
TestUser5          user               CN=TestUser5,OU=TestOU,DC=ps64,DC=local

Get a list of users in an OU (and all nested OUs):

PS C:\> Get-QADUser -SearchRoot ps64.local/TestOU

Name               Type               DN
----               ----               --
TestUser1          user               CN=TestUser1,OU=TestOU,DC=ps64,DC=local
TestUser2          user               CN=TestUser2,OU=TestOU,DC=ps64,DC=local
TestUser3          user               CN=TestUser3,OU=TestOU,DC=ps64,DC=local
TestUser4          user               CN=TestUser4,OU=TestOU,DC=ps64,DC=local
TestUser5          user               CN=TestUser5,OU=TestOU,DC=ps64,DC=local

Get only users placed directly in the OU (and not in sub-OUs):

PS C:\> Get-QADUser -SearchRoot ps64.local/TestOU -SearchScope OneLevel

Name               Type               DN
----               ----               --
TestUser1          user               CN=TestUser1,OU=TestOU,DC=ps64,DC=local
TestUser2          user               CN=TestUser2,OU=TestOU,DC=ps64,DC=local
TestUser3          user               CN=TestUser3,OU=TestOU,DC=ps64,DC=local
TestUser4          user               CN=TestUser4,OU=TestOU,DC=ps64,DC=local
TestUser5          user               CN=TestUser5,OU=TestOU,DC=ps64,DC=local

Modify all users from an OU:

PS C:\> Get-QADUser -SearchRoot ps64.local/TestOU | Set-QADUser -City TestCity

PS C:> Get-QADUser -SearchRoot ps64.local/TestOU | Format-Table Name, City

Name                                                City
----                                                ----
TestUser1                                           TestCity
TestUser2                                           TestCity
TestUser3                                           TestCity
TestUser4                                           TestCity
TestUser5                                           TestCity

Get statistics on the number of objects in each OU:

PS C:\> Get-QADObject -Type organizationalUnit | foreach { Write-Host $_.Name: (Get-QADObject -SearchRoot $_.DN).Count}

Domain Controllers : 5
Microsoft Exchange Security Groups : 6
TestOU : 6

Get the list of AD objects by OU:

PS C:\> Get-QADObject -Type organizationalUnit | foreach { Write-Host ([char]10) $_.Name ([char]10); Get-QADObject -SearchRoot $_.DN }

Domain Controllers  

Name               Type               DN
----               ----               --
Domain Controllers organizationalUnit OU=Domain Controllers,DC=ps64,DC=local
SPB9880            computer           CN=SPB9880,OU=Domain Controllers,DC=ps64,DC=local
RID Set            rIDSet             CN=RID Set,CN=SPB9880,OU=Domain Controllers,DC=ps64,DC=local
NTFRS Subscript... nTFRSSubscriptions CN=NTFRS Subscriptions,CN=SPB9880,OU=Domain Controllers,DC=ps64,DC=local
Domain System V... nTFRSSubscriber    CN=Domain System Volume (SYSVOL share),CN=NTFRS Subscriptions,CN=SPB9880,OU=Do...  

Microsoft Exchange Security Groups  

Microsoft Excha... organizationalUnit OU=Microsoft Exchange Security Groups,DC=ps64,DC=local
Exchange Servers   group              CN=Exchange Servers,OU=Microsoft Exchange Security Groups,DC=ps64,DC=local
Exchange Organi... group              CN=Exchange Organization Administrators,OU=Microsoft Exchange Security Groups,...
Exchange Recipi... group              CN=Exchange Recipient Administrators,OU=Microsoft Exchange Security Groups,DC=...
Exchange View-O... group              CN=Exchange View-Only Administrators,OU=Microsoft Exchange Security Groups,DC=...
ExchangeLegacyI... group              CN=ExchangeLegacyInterop,OU=Microsoft Exchange Security Groups,DC=ps64,DC=local  

TestOU  

TestOU             organizationalUnit OU=TestOU,DC=ps64,DC=local
TestUser1          user               CN=TestUser1,OU=TestOU,DC=ps64,DC=local
TestUser2          user               CN=TestUser2,OU=TestOU,DC=ps64,DC=local
TestUser3          user               CN=TestUser3,OU=TestOU,DC=ps64,DC=local
TestUser4          user               CN=TestUser4,OU=TestOU,DC=ps64,DC=local
TestUser5          user               CN=TestUser5,OU=TestOU,DC=ps64,DC=local

Notes:

  • For CSV-based OU/user provisioning just add import-csv as I described in earlier posts.
  • All the user operations are applicable to other types as well -just use *-QADGroup, *-QADComputer, etc. instead of *-QADUser.
  • The last statistics examples can be also made specific for users, groups, etc. by just changing the Get-QADObject cmdlet to a more specific one.

Tags: , , , ,

6 Responses to “OU Management with PowerShell”


  1. 1 Ambers June 13, 2007 at 5:14 am

    How would you go about grouping the output? For example I would like to be able to do the following:

    Root: Total Objects
    OU: Total Objects
    SubOU: Total Objects
    SubOU: Total Objects
    OU: Totat Objects

    ..etc.

    Thanks.

  2. 2 dmitrysotnikov June 13, 2007 at 2:57 pm

    Here’s the oneliner which worked for me (using AD cmdlets 1.0.3):

    PS:\> Get-QADObject | Group-Object ParentContainer -NoElement

    If you want the name to be first (and not cut by PowerShell) use format -table in the end:

    PS:\> Get-QADObject | Group-Object ParentContainer -NoElement | Format-Table Name, Count -AutoSize

    I hope that helps!

  3. 3 Anders May 9, 2008 at 11:54 am

    Hi.
    I’m writing a PS script to automate the creation of Mailboxes in Exchange 2007 on server 2008.
    I have installed the Quest cmdlets to be able to modify the AD.
    What i need is a script to check if an OU exists, and if not, create an OU based on data from a csv-file.
    I have tried, but havnt quite got it right.
    This is what I have so far:

    ## Import data from csv and store it in variable ‘data’

    $data = import-csv $args[0]

    $ou = get-qadobject -type organizationalunit

    if ( -not $ou = $data.Domain)
    {Some code to create a new OU based on the Domain from the CSV}
    else
    {Go on with the rest of the script}

    Am I on the right track?

    Regards
    Anders

  4. 4 dmitrysotnikov May 12, 2008 at 3:25 pm

    Anders,

    I believe Shay has already answered your question in this thread: http://powergui.org/thread.jspa?messageID=19543

    Dmitry

  1. 1 Extend AD cmdlets' reach « Dmitry’s PowerBlog Trackback on May 30, 2007 at 9:50 pm
  2. 2 Quick Reference to AD cmdlets 1.0.4 « Dmitry’s PowerBlog: PowerShell and beyond Trackback on August 30, 2007 at 10:13 am

Leave a Reply




View Dmitry Sotnikov's profile on LinkedIn

Archives

See you at:

Legal

The posts on this blog are provided “as is” with no warranties and confer no rights. The opinions expressed on this site are mine and mine alone, and do not necessarily represent those of my employer Quest Software or anyone else for that matter. All trademarks acknowledged.

© 2007 Dmitry Sotnikov