In this opportunity I am going to provide a solution to manage sites in your Active Directory (AD) forest by extending Active Directory PowerShell by implementing functions that allow creation, retrieval, update (moving to a site link, renaming) and deletion of sites.

First of all we need to understand what an AD site is made of. We can say that an AD site is represented by three directory objects and a reference in an attribute in a different object (i.e. the Site Link object). In detail an AD site is a compound of:

1. The site object (objectClass=site) which is an object under the sites object in the configuration naming context.

2. The NTDS site settings object (objectClass=nTDSSiteSettings) a child object under the site object

3. The servers containers object (objectClass=serversContainer) a child object under the site object

4. A value in the multi-valued attribute siteList in the site link object.

In the first place we need to know the sites container distinguished name (DN). This object has a relative distinguished name (RDN) with value Sites RDN under the configuration naming context. The following shows how to build the DN string for the sites container:

      $configNCDN = (Get-ADRootDSE).ConfigurationNamingContext

      $sitesContainerDN = ("CN=Sites," + $configNCDN)

The new site object will be an object under the sites container object:

      $newSiteDN = ("CN=" + $newSiteName +"," + $sitesContainerDN)

We can use the New-ADObject cmdlet to create the Site, NTDS Site Settings and Servers container objects under the Sites container object:

      New-ADObject -Name $newSiteName -Path $sitesContainerDN -Type site

      New-ADObject -Name "NTDS Site Settings" -Path $newSiteDN -Type nTDSSiteSettings

      New-ADObject -Name "Servers" -Path $newSiteDN -Type serversContainer

Now to add the site to the site link we will need a reference to the site link object. The site link objects are located under the given inter-site transport object (IP or SMTP). For example for DEFAULTIPSITELINK the site link container location will be:

      $siteLinkContainer = ("CN=DEFAULTIPSITELINK,CN=IP,CN=Inter-Site Transports,CN=Sites," + $configNCDN)

The last step is to add the site to the site link by including the site name in the siteList attribute in the respective site link object. To modify the siteList attribute in the site link object we will need to get the site link object first with the siteList attribute using using the Get-ADObject cmdlet to create an instance and then modify it using the Set-ADObject cmdlet:

      $siteLink = Get-ADObject $siteLinkContainer -Properties siteList


      Set-ADObject -Instance $siteLink

And that will be it.

I have created the function below called New-XADSite which receives the site name and the site link name (IP based, you can do a small modification to add SMTP based site links). Also it contains special cases validations which provide you a more reliable experience if you want to use the function in your AD forests. In future posts I will show you how to extend AD PowerShell to include functions to get the site names of the forest, moving a site to a different site link, renaming a site and removing a site in the forest. Notice that the script uses the function Test-XADObject which is implemented in a previous posting.

   1:  function New-XADSite() {
   2:     [CmdletBinding(ConfirmImpact="Low")]
   3:     Param (
   4:        [Parameter(Mandatory=$true,
   5:                   Position=0,
   6:                   ValueFromPipeline=$true,
   7:                   HelpMessage="Identity of the site to be created. Name is the only supported identity for this version of the script."
   8:                  )]
   9:        [Object] $Identity,
  10:        [Parameter(Mandatory=$false,
  11:                   Position=1,
  12:                   ValueFromPipeline=$false,
  13:                   HelpMessage="Site link name to which the site will belong."
  14:                  )]
  15:        [Object] $SiteLinkName
  16:     )
  18:     BEGIN {
  20:     }
  22:     PROCESS {
  24:        # In this version of the script the only identity supported is the site name
  25:        # Replace the line below to support other identities
  26:        $newSiteName = $Identity
  28:        if ([String]::IsNullOrEmpty($newSiteName)) {
  29:           throw New-Object System.Management.Automation.PSArgumentException("Site name cannot be an empty string, please try again.")
  30:        }
  32:        if ($SiteLinkName -eq $null) {
  33:           $SiteLinkName = "DEFAULTIPSITELINK"
  34:        }
  36:        # Get the configuration partition DN, the sites container and build the new site DN
  37:        $configNCDN = (Get-ADRootDSE).ConfigurationNamingContext
  38:        $sitesContainerDN = ("CN=Sites," + $configNCDN)
  39:        $newSiteDN = ("CN=" + $newSiteName +"," + $sitesContainerDN)
  41:        $siteLinkContainerDN = ("CN=" + $SiteLinkName + ",CN=IP,CN=Inter-Site Transports,CN=Sites," + $configNCDN)
  42:        # Verify if the site link exists
  43:        $siteLinkExists = Test-XADObject -Identity $siteLinkContainerDN
  44:        if ($siteLinkExists -eq $false) {
  45:           throw New-Object System.Management.Automation.RuntimeException("The site link you provided does not exist. Please check the name and try again.")
  46:        }
  48:        # Verify if the site already exists
  49:        $siteExists = Test-XADObject -Identity $newSiteDN
  50:        if ($siteExists) {
  51:           throw New-Object System.Management.Automation.RuntimeException("Site already exists. Please check the name and try again.")
  52:        }
  53:        else {
  54:           $siteObjectCreated = $false
  56:           trap [Exception] {
  57:              # Output the error to the pipeline
  58:              Write-Host $_
  60:              # Remove any objects created for consistency
  61:              if ($siteObjectCreated -eq $true) {
  62:                 Remove-ADObject -Identity $newSiteDN -Recursive -Confirm:$false
  63:              }
  65:              # Throw a new exception with the trapped exception as inner exception
  66:              throw New-Object System.Management.Automation.RuntimeException("An exception occurred when creating the site. See inner exceptions for more details.", $_.Exception)
  67:           }
  69:           # Create Site, NTDS Site Settings and Server objects
  70:           New-ADObject -Name $newSiteName -Path $sitesContainerDN -Type site
  71:           $siteObjectCreated = $true
  72:           New-ADObject -Name "NTDS Site Settings" -Path $newSiteDN -Type nTDSSiteSettings
  73:           New-ADObject -Name "Servers" -Path $newSiteDN -Type serversContainer
  75:           $siteLink = Get-ADObject $siteLinkContainerDN -Properties siteList
  76:           $numberOfSitesInSiteLink = $siteLink.siteList.Add($newSiteDN)
  77:           Set-ADObject -Instance $siteLink
  79:           # Return the directory objects that make the AD site
  80:           Get-ADObject -Identity $newSiteDN
  81:           Get-ADObject -Identity ("CN=NTDS Site Settings," + $newSiteDN)
  82:           Get-ADObject -Identity ("CN=Servers," + $newSiteDN)
  83:        }
  85:      }
  87:      END {
  89:      }
  90:  }


Jairo Cadena

Active Directory

Comments (7)

  1. says:

    The Active Directory Powershell idea is very exciting – but very frustrating!  Apparently it is only available with Server 2008 R2 – and Server 2008 R2 isn’t out until the end of the year or early 2010.

    Now some may have the luxury of enough spare time to experiment with it on ordinary Server 2008, and others may not mind the risk of installing a Beta O/S for their live Active Directory – but I have not.  Indeed, I suspect my boss won’t approve R2 until it has been around for a while – at least a few months.

    Is there no way to get AD Powershell running NOW on my present Server 2008 forest?

  2. In this opportunity I am going to provide a solution to manage sites in your Active Directory (AD) forest

  3. Rasmus Dronninglund Jensen says:

    I totaly agree with jjen009.

    I like all that you are doing – I cannot wait for the final tools to be released.

    But you need to make the ADPowerShell cmdlets available for all OS that are able to run PowerShell, now a very limited selection that only has its base in the furure. We (the SA) need tools NOW, not x years into the future.

    You (MS) have always made your administrative tools available for all OS (with MMC), so why are you turning the boat now?

    PowerShell is praised to the skyes, but if our tools are dependant on OS then I see big problems in the future.

    I know that ADPowerShell isn’t (final) released yet, so I am hoping you just haven’t come to the other OS yet.

    It would be pritty narrow to only focus on Win2008 R2 and Win7 – I mean what about WinXP, Win2003, Win2008 or even Vista?

    I know you have to draw a line somewhere, but Win2008 R2 and Win7 is just the wrong place to put it.

    Please post some feedback.

  4. swaminathan1 says:

    @jjen009, @Rasmus

    Active Directory Module for Windows Powershell is available only on Windows Server 2008 R2 and Windows 7 (For Windows 7: you need to install RSAT update. Check out:

    Regarding whether AD Powershell will work with Windows Server 2003/2008:  Currently, we only support targeting Windows Server 2008 R2 DCs. In the future (I don’t have an exact date) there will be an OOB (Out of Band) release for down-level DCs, after which AD Powershell will be able to target down-level DCs.

    Please let us know if you have further questions.



    Swaminathan Pattabiraman

    Developer – Active Directory Powershell Team

  5. says:

    Thanks, Swami.  Well, we are all panting for it.  I think it is likely to be at least another year before our AD will have 2008 R2 DCs – I mean the RTM is only expected for the end of the year.  We certainly are not going to put up DCs for our live AD that are not supported.  And then my boss is almost certainly going to say ‘wait a few months after RTM before jumping in the water.’

    In the meantime I have to administer my AD NOW.  Of course I use powershell and ADSI and LDAP and such and have developed a few clumsy tools to make it easier for me – but I really really think an OOB release is a pressing need.

  6. mm says:

    is there a link to download script?

Skip to main content