Sunday, March 11, 2012

PowerShell: AD Create OU and Copy Group Policies

A few weeks ago, a need to came up for a script that would create a new dept OU, and standard sub OUs inside it, and then assign the same 60+ group policies from an another dept OU (including the standard sub OUs). Below the script that took care of this request.

########################################################
# Script Name: AD_Create_OU_and_Link_GPOs.ps1
# Author: Dean Bunn
# Description: Creates Dept OU and Assigns GPOs
########################################################

#Load Group Policy Module
Import-Module grouppolicy

#Var for New Department Name
$deptName = "DeptA"

#Var for Distinguished Path of Parent OU
$parentD = "OU=DEPARTMENTS,DC=ChildDomain,DC=MyCollege,DC=EDU"

#Var for GPO Source OU
$gpoSrcOU = "OU=DeptB,OU=DEPARTMENTS,DC=ChildDomain,DC=MyCollege,DC=EDU"

#LDAP String for Parent Path
$ldapParent = "LDAP://" + $parentD

#Var for OU Class
$class = "organizationalUnit"

#Array for Storing OU Info
$arrOUs = @()

#Array of OU Path with ? for Dept Name Place Holder
$deptOUs = @("OU=?",
"OU=?-OU-Computers,OU=?",
"OU=?-OU-Groups,OU=?",
"OU=?-OU-LocalUsers,OU=?",
"OU=?-OU-Servers,OU=?",
"OU=?-OU-Test Servers,OU=?",
"OU=Faculty-Staff-Grad,OU=?-OU-Computers,OU=?",
"OU=IT,OU=?-OU-Computers,OU=?",
"OU=LAB,OU=?-OU-Computers,OU=?",
"OU=STAFF,OU=?-OU-Computers,OU=?"
)

#Retrieve Parent OU using ADSI
$parentOU = [ADSI]$ldapParent

#Split GPO Source OU String to Get OU First Name
$gOFN = ($gpoSrcOU.ToString().Split(","))[0].ToString().ToLower().Replace("ou=","")

#Loop Through OU Paths
foreach($dOU in $deptOUs)
{
#Replace ? Character with Name of Dept
$ouDN = $dOU.ToString().Replace("?",$deptName)
#Create OU Object and Save It
$oOU = $parentOU.create($class,$ouDN)
$oOU.setInfo()
#Replace ? Character with Name of GPO Source OU and Extra Comma (Will Be Used Later to Compare)
$gpoOUStart = $dOU.ToString().Replace("?",$gOFN) + ","
#Var for the Full Path of the New OU (Used Later When Assigning Linked GPOs)
$newOUFullPath = $ouDN + "," + $parentD
#Create PS Object and Assign OU Data
$uEntry = new-Object PSObject
$uEntry | add-Member -memberType noteProperty -name "gpoOUStart" -Value $gpoOUStart.ToString().ToLower()
$uEntry | add-Member -memberType noteProperty -name "newOUFullPath" -Value $newOUFullPath.ToString()
#Add PS Object to OU Array
$arrOUs += $uEntry
}

#Pause the Script for One Minute to Give AD Time to Acknowledge OU Creation
Start-Sleep -Seconds 60

#Var for LDAP String Path
$gSOLP = "LDAP://" + $gpoSrcOU

#Query AD for All OUs in the GPO Source OU Path
$ADsPath = [ADSI]$gSOLP
$Search = New-Object DirectoryServices.DirectorySearcher($ADsPath)
$Search.filter = "(objectClass=organizationalunit)"
$Search.PageSize = 900
$Search.SearchScope = "SubTree"
$Results = $Search.FindAll()

#Loop Through Each Result
foreach($result in $Results)
{
#Retrieve OU Directory Entry
$objOU = $result.GetDirectoryEntry()
#Loop Throuh Each Individual OU PS Object in the OU Array
foreach($iOU in $arrOUs)
{
#See If Source GPO OU Path Starts with the Same Structure as One We Created Earlier
if($objOU.DistinguishedName.ToString().ToLower().StartsWith($iOU.gpoOUStart))
{
#Retrieve the GPOs Linked on the GPO Source OU
$srcGPOS = Get-GPInheritance -target $objOU.DistinguishedName.ToString()
#Loop Through All Linked GPOs
foreach($gp in $srcGPOS.GpoLinks)
{
#Convert the GpoId to a GUID
$guidGPO = [Guid]$gp.GpoId
#Link the GPO to the New OU
New-GPLink -guid $guidGPO -target $iOU.newOUFullPath -LinkEnabled Yes -domain "childdomain.mycollege.edu"
}#End Foreach GpoLinks
}#End OU DN StartsWith Check
}#End Foreach on PS Object Array
}#End Foreach OU in GPO Source OU

No comments: