OU Structure

Automate More of The Things

A few weeks ago I wrote about how to maintain a folder structure with PowerShell. That was a lot more involved than this, but when you are managing dozens to hundreds of domains, keeping things tidy is important. A peer over in the MSPGeek Slack was asking for input on just such a thing a few days ago, and I shared with him an ancient and terrible but functional script for creating our minimum required OUs, as well as security groups. Well, I’ve went and cleaned it up a little. This script will create all of the requested OUs, checking to see if they exist first before trying. This means you can regularly run this on an environment to ensure compliance.

Much like my previous script folder maintenance I made a function that does the core of creating an OU. After that, I just call that for every new OU I want created. Reducing code and making revisions easier. I didn’t do the same for making the security group, but if you had a small list of groups you always used, you could certainly do the same for it.

The only real issues you might find are:

  1. Azure AD Sync can be configured to sync based on OU, so moving things around may cause accidental deletion in Azure AD
  2. There are a lot of other things that work off OU. Be careful when moving things around if you have an Active Directory integrations like LDAP user authentication on firewalls.
  3. GPOs are often tied to OU. Better make sure the client doesn’t have GPOs linked to OUs, and if they do, mirror the OU structure and linked GPOs inside your new structure.

It may be wise to audit your client’s use of protocols like LDAP before rearranging everything. Once everything is in the proper OUs, it will make it much easier to find what you are looking for, and

Code Time

Function New-OU {
    param (
        [Parameter(Mandatory = $true)]
        [string]$Name,

        [Parameter(Mandatory = $false)]
        [string]$Path
    )
    $OU = Get-ADOrganizationalUnit -Filter "name -eq '$Name'" ;
    if (!$OU) {
        if ($Path) {
            New-ADOrganizationalUnit -name $Name -Path $Path;
        }
        else {
            New-ADOrganizationalUnit -name $Name;
        }
        $OU = Get-ADOrganizationalUnit -Filter "name -eq '$Name'";
    }
    return $OU
}

#Make the primary OU that all the others will go under
$OUPrimary = New-OU "Company"
if ($OUPrimary) {
    #Make all the Children OUs
    $OUEmployees = New-OU "Employees" $OUPrimary.DistinguishedName
    $OUDisabledEmployees = New-OU "Disabled Employees" $OUPrimary.DistinguishedName
    $OUServiceAccounts = New-OU "Service Accounts" $OUPrimary.DistinguishedName
    $OUSecurityGroups = New-OU "Security Groups" $OUPrimary.DistinguishedName
    #Make Security Groups inside of the Security Groups OU
    if ($OUSecurityGroups) {
        Try {$EmployeeSG = Get-ADGroup -Identity "Employees"}
        Catch {
            write-host "Creating Employees Security Group"
            New-ADGroup -name "Employees" -GroupCategory Security -GroupScope Global -Path $OUSecurityGroups.DistinguishedName;
            $EmployeeSG = Get-ADGroup -Identity "Employees";
        }
    }
}