List Sites and Subnets in Active Directory using PowerShell

How to list sites and subnets in Active Directory using Powershell.  This script determines the path to the configuration partition in your Active Directory, enumerates the site objects and retrieves the name and description of each.  It then enumerates the subnets, identifies which site the subnet belongs to, then outputs the sorted results to the screen.

The script serves as an example of how to use ldap://RootDSE/ to connect to your AD without hard-coding domain names, and how to enumerate children of [adsi] objects.

$siteDescription=@{}
$siteSubnets=@{}
$subnetDescription=@{}
$sitesDN="LDAP://CN=Sites," + $([adsi] "LDAP://RootDSE").Get("ConfigurationNamingContext")
$subnetsDN="LDAP://CN=Subnets,CN=Sites," + $([adsi] "LDAP://RootDSE").Get("ConfigurationNamingContext")
#get the site names and descriptions
foreach ($site in $([adsi] $sitesDN).psbase.children){
 if($site.objectClass -eq "site"){
  $siteName=([string]$site.cn).toUpper()
  $siteDescription[$siteName]=$site.description[0]
  $siteSubnets[$siteName]=@()
 }
}
#get the subnets and associate them with the sites
foreach ($subnet in $([adsi] $subnetsDN).psbase.children){
 $subnetDescription[[string]$subnet.cn]=$subnet.description[0]
 $site=[adsi] "LDAP://$($subnet.siteObject)"
 if($site.cn -ne $null){
  $siteName=([string]$site.cn).toUpper()
  $siteSubnets[$siteName] += $subnet.cn
 }else{
  $siteDescription["Orphaned"]="Subnets not associated with any site"
  if($siteSubnets["Orphaned"] -eq $null){ $siteSubnets["Orphaned"] = @() }
  $siteSubnets["Orphaned"] += $subnet.cn
 }
}
#write output to screen
foreach ($siteName in $siteDescription.keys | sort){
 "$siteName  $($siteDescription[$siteName])"
 foreach ($subnet in $siteSubnets[$siteName]){
  "`t$subnet $($subnetDescription[$subnet])"
 }
}

The syntax above is intentionally verbose, so that you can see what's going on in the code.  However, if you're one of those people that prefer a fluent pipeline, here you go.

$siteDescription=@{}
$siteSubnets=@{}
$subnetDescription=@{}
$sitesDN = "LDAP://CN=Sites," + $([adsi] "LDAP://RootDSE").Get("ConfigurationNamingContext")
$subnetsDN = "LDAP://CN=Subnets,CN=Sites," + $([adsi] "LDAP://RootDSE").Get("ConfigurationNamingContext")
([adsi] $sitesDN).children | ?{$_.objectClass -eq "site"} | %{ $siteName = ([string]$_.cn).toUpper(); $siteDescription[$siteName] = $_.description[0]; }
([adsi] $subnetsDN).children | %{ $siteSubnets[[string](([adsi] "LDAP://$($_.siteObject)").cn)] += $_.cn; $subnetDescription[[string]$_.cn]=$_.description[0] }
$siteDescription.keys | sort | %{ "$_  $($siteDescription[$_])"; $siteSubnets[$_] | %{"`t$_ $($subnetDescription[$_])"} }

4 comments:

Anonymous said...

Not sure if this will get a response as this was originally posted in 2011 but when I tried running script:

At line:7 char:28
+ ([adsi] $sitesDN).children ¦ ?{$_.objectClass -eq "site"} ¦ %{ $siteName = ([str ...
+ ~
Unexpected token '¦' in expression or statement.
At line:8 char:30
+ ([adsi] $subnetsDN).children ¦ %{ $siteSubnets[[string](([adsi] "LDAP://$($_.sit ...
+ ~
Unexpected token '¦' in expression or statement.
At line:9 char:23
+ $siteDescription.keys ¦ sort ¦ %{ "$_ $($siteDescription[$_])"; $siteSubnets[$_ ...
+ ~
Unexpected token '¦' in expression or statement.
At line:9 char:83
+ ... iteSubnets[$_] ¦ %{"`t$_"} }
+ ~
Unexpected token '¦' in expression or statement.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : UnexpectedToken

Brian said...

Darn, thought I fixed that years ago! Fixed now, it was the pipe symbols got replaced in the html editor. Give it another shot.

Unknown said...

Will it be possible to modify the script to just read the subnets and it descriptions?

Brian said...

I just updated the script to display the descriptions. Enjoy.

Post a Comment

Related Posts Plugin for WordPress, Blogger...