Saturday, March 7, 2009

Using PowerShell and S.DS.AD to create Sites and Service objects

System.DirectoryServices.ActiveDirectory (S.DS.AD) is a .NET namespace available for performing common tasks related to Active Directory Domain Services. S.DS.AD differs from S.DS in that it is a pure .NET interface which allows us to extend deeper into DS development. See S.DS.AD Scenarios here.

With PowerShell (PSH), we can leverage the classes in this namespace for common manual tasks that can be scripted. For example, in a migration scenario, managing AD sites and services can be time consuming to set up. Here are some functions I wrote which allow you to automate these process using PSH.

To do bulk creations of site objects, you would store your configuration in a CSV file and use them as parameters to each PSH function.

Say we need to 1. Create Sites, 2. Create Subnets, 3. Create SiteLinks, and 4. Configure our SiteLinks. Using Excel, you can create 4 CSV source files for each task, then use the Import-CSV and ForEach-Object cmdlets to call each function for each record.

For example:

Import-Csv C:\importFile.csv ForEach-Object {Create-Site $_.SiteName}
Import-Csv C:\importSubnets.txt ForEach-Object {Create-SubNet $_.SubNet $_.SiteName}
Import-Csv C:\importSiteLinks.txt ForEach-Object {Create-SiteLink $_.SiteLinkName $_.Site $_.Cost $_.Interval}

Here are the PSH functions:

Creating AD Sites

Function Create-Site{Param ($siteName)
$forest = [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest()
$type = [System.DirectoryServices.ActiveDirectory.DirectoryContextType]"forest"
$contextType = New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext($type,$forest)
$site = New-Object System.DirectoryServices.ActiveDirectory.ActiveDirectorySite($contextType,$siteName)
$site.Options = [System.DirectoryServices.ActiveDirectory.ActiveDirectorySiteOptions]::GroupMembershipCachingEnabled
$site.Save()
Write-Host "Creating site object $siteName..." }

Creating AD Subnets

Function Create-SubNet{Param($subNetName,$siteName)
$forest = [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest()
$type = [System.DirectoryServices.ActiveDirectory.DirectoryContextType]"forest"
$contextType = New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext($type,$forest)
$site = [System.DirectoryServices.ActiveDirectory.ActiveDirectorySite]::FindByName($contextType, $siteName)
$subnet = New-Object System.DirectoryServices.ActiveDirectory.ActiveDirectorySubnet($contextType,$subNetName,$site)
$subnet.Save()
Write-Host "Creating subnet object $subNetName..." }

Creating AD SiteLinks

Function Create-SiteLink{Param($siteLinkName,$siteName,$siteCost,$repInterval)
$forest = [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest()
$type = [System.DirectoryServices.ActiveDirectory.DirectoryContextType]"forest"
$contextType = New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext($type,$forest)
$trans = [System.DirectoryServices.ActiveDirectory.ActiveDirectoryTransportType]::Rpc
$site = [System.DirectoryServices.ActiveDirectory.ActiveDirectorySite]::FindByName($contextType,$siteName)
$link = New-Object System.DirectoryServices.ActiveDirectory.ActiveDirectorySiteLink($contextType,$siteLinkName,$trans)
$link.Cost = $siteCost
$link.ReplicationInterval = $repInterval
$d = $link.Sites.Add($site)
$link.Save()
Write-Host "Creating siteLink object $siteLinkName..." }

Adding Sites to a SiteLink

Function Add-SitetoSiteLink{Param($siteName,$siteLinkName)
$forest = [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest()
$type = [System.DirectoryServices.ActiveDirectory.DirectoryContextType]"forest"
$contextType = New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext($type,$forest)
$site = [System.DirectoryServices.ActiveDirectory.ActiveDirectorySite]::FindByName($contextType,$siteName)
$link = [System.DirectoryServices.ActiveDirectory.ActiveDirectorySiteLink]::FindByName($contextTye,$siteLinkName)
$link.Sites.Add($site)
$link.Save() }