Automating the creation of an OU structure based on a template

Discussing OU structures in an Active Directory can easily get into a religious matter. 🙂
Anyhow, the reality is that different organizations have different needs. Therefore, you sometimes end up with more or less complex OU structures. In order to make the creation of the ‘more complex structures’ as the one in the screenshot below easier, I’ve created a small function that lets you copy the structure from a template or from an existing, already properly configured site/structure.
2014-11-28_22-10-48

function Copy-JDOrganizationalUnit {
<#
.SYNOPSIS
    The script copies an OU structure from one OU to another. The destination OU must already be created.
.EXAMPLE
    Copy-JDOrganizationalUnit -SourcePath "OU=HAB,OU=SE,OU=Sites,DC=lucernepublishing,DC=local" -DestinationPath "OU=HEL,OU=FI,OU=Sites,DC=lucernepublishing,DC=local" -Verbose
.PARAMETER SourceOU
    Plain name of the source OU to copy the structure from.
.PARAMETER DestinationOU
    Plain name of the destination OU to replicate the structure to.
.PARAMETER ProtectOU
    Sets the flag ProtectOUFromAccidentialDeletion
.NOTES
    File Name: Copy-JDOrganizationalUnit
    Author   : Johan Dahlbom, johan[at]dahlbom.eu
    Blog     : 365lab.net
    The script are provided “AS IS” with no guarantees, no warranties, and they confer no rights.
#>

  [CmdletBinding(SupportsShouldProcess=$true,HelpUri = 'http://www.365lab.net/')]
  param (
    [Parameter(Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
    [ValidateScript({Get-ADOrganizationalUnit -Identity $_})]
    [string]$SourcePath,
    [Parameter(Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
    [ValidateScript({Get-ADOrganizationalUnit -Identity $_})]
    [string]$DestinationPath,
    [switch]$ProtectOU
  )
  Write-Verbose "Copying structure from $SourcePath to $DestinationPath..."
  Get-ADOrganizationalUnit -SearchBase $SourcePath -Filter {Distinguishedname -ne $SourcePath} -Properties canonicalname| Select-Object DistinguishedName,canonicalname,Name  | Sort-Object -Property CanonicalName | ForEach-Object {
    try {
      $NewOU = @{
        Path = $_.DistinguishedName.replace("OU=$($Name),",'').Replace("$SourcePath","$DestinationPath")
        Name = $_.Name
        ProtectedFromAccidentalDeletion = $ProtectOU
      }
      New-ADOrganizationalUnit @NewOU -ErrorAction Stop
      Write-Verbose "Created OU OU=$Name,$DestPath"
    } catch {
      Write-Warning "Error with creating OU=$Name,$DestPath`r`n$_"
    }
  }
}

Running the example as below, will copy the entire structure from OU=JKG to OU=BRU. It will not overwrite any existing OU’s.

$OUs = @{
    SourcePath = 'OU=JKG,OU=SE,OU=Sites,DC=365lab,DC=internal'
    DestinationPath = 'OU=BRU,OU=BE,OU=Sites,DC=365lab,DC=internal'
}
Copy-JDOrganizationalUnit @OUs -Verbose -ProtectOU

2014-11-28_23-13-57

As you can see above, the entire structure has now been copied according to the Source OU. Let me know if you have feedback or suggestions on improvements!

/Johan

Advertisements

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