Detecting AD Site options using PowerShell
How can I use PowerShell to find AD site options like +IS_INTER_SITE_AUTO_TOPOLOGY_DISABLED
in PowerShell? I've been playing around with the following command, but can't get it to spit out anything useful.
Get-ADObject -Filter 'objectClass -eq "site"' -Searchbase (Get-ADRootDSE).ConfigurationNamingContext` -Properties options
Edit #3: Updating reference documentation.
Edit #2: Editing one more time because I wrote something in PS to do exactly what you are trying to do. It's at the bottom.
I'm going to go ahead and assert that there's no Powershell Friendly (tm) way of doing it at present. But of course you could still use Powershell to make the LDAP query necessary to see these options if you really wanted to. Check out the options
attribute of the NTDS Settings
object of each server that is associated to an AD site:
That is the exact attribute, which is a bitmask, that repadmin.exe works on. Repadmin.exe contains a friendly bitmask translator in its code. As does the ADSIEdit MMC snap-in. However, you would need to recreate that bitmask translator in Powershell.
For instance, Repadmin /options <DC> [{+|-} IS_GC]
is a valid command, and now we know exactly which bit on which it operates.
Here is the relatively crappy MSDN documentation on the options
attribute.
Better MSDN documentation on the options
attribute.
Options Attribute
A bitfield, where the meaning of the bits varies from objectClass to objectClass. Can occur on Inter-Site-Transport, NTDS-Connection, NTDS-DSA, NTDS-Site-Settings, and Site-Link objects.
And here is an example of searching for options using old-school matching rule operators:
(&(objectCategory=nTDSDSA)(options:1.2.840.113556.1.4.803:=1))
This filter uses the LDAP_MATCHING_RULE_BIT_AND matching rule operator (1.2.840.113556.1.4.803) to find nTDSDSA objects that have the low-order bit set in the bitmask of the options attribute. The low-order bit, which corresponds to the NTDSDSA_OPT_IS_GC constant defined in Ntdsapi.h, identifies the nTDSDSA object of a Global Catalog server. For more information about matching rules, see Search Filter Syntax.
Oh boy does that sound fun!
Some other values for the bitmask:
So with that you should have enough information to roll your own Get-ADSiteOptions
Cmdlet... if you want me to write one for you I will, for a very modest fee... ;)
Edit: Here is the Microsoft link, Repadmin for Experts, which details the difference between the options
and siteoptions
subcommands of repadmin:
By using the siteoptions subcommand, we could change the options attribute stored on the NTDS Site Settings Object.
As for that bitmap? Is it even documented? Not sure. If you can tell me what You're such a showoff, MDMarra. ;)FORCE_KCC_WHISTLER_BEHAVIOR
means in an interview, I will hire you on the spot.
So just to sum up, the options
attribute on the CN=NTDS Settings
object for each domain controller corresponds to the DC-specific options, i.e., repadmin <DC> /options
, whereas the options
attribute on the CN=NTDS Site Settings
object under each site corresponds to repadmin /siteoptions
.
So, to finally answer your question. Getting specifically site options, not DC options:
ForEach($Site In (Get-ADObject -Filter 'objectClass -eq "site"' -Searchbase (Get-ADRootDSE).ConfigurationNamingContext))
{
Get-ADObject "CN=NTDS Site Settings,$($Site.DistinguishedName)" -Properties Options
}
If there are no site options set, Powershell won't return them. You could probably simplify the above code a little but that's using the parlance you started with. After way too much searching, I finally found the documentation on the site options bitmask:
So for IS_INTER_SITE_AUTO_TOPOLOGY_DISABLED
that you gave as an example, you'd be looking for a value of 0x00000010
for the options
attribute.
And from running the Powershell snippet:
Edit #2: I wrote you something today:
#Require -Version 3
#Require -Module ActiveDirectory
Function Get-ADSiteOptions
{
<#
.SYNOPSIS
This Cmdlet gets Active Directory Site Options.
.DESCRIPTION
This Cmdlet gets Active Directory Site Options.
We can fill out the rest of this comment-based help later.
.LINK
http://myotherpcisacloud.com
.NOTES
Written by Ryan Ries, October 2013. [email protected].
#>
[CmdletBinding()]
Param()
BEGIN
{
Set-StrictMode -Version Latest
# This enum comes from NtDsAPI.h in the Windows SDK.
# Also thanks to Jason Scott for pointing it out to me. http://serverfault.com/users/23067/jscott
Add-Type -TypeDefinition @"
[System.Flags]
public enum nTDSSiteSettingsFlags {
NTDSSETTINGS_OPT_IS_AUTO_TOPOLOGY_DISABLED = 0x00000001,
NTDSSETTINGS_OPT_IS_TOPL_CLEANUP_DISABLED = 0x00000002,
NTDSSETTINGS_OPT_IS_TOPL_MIN_HOPS_DISABLED = 0x00000004,
NTDSSETTINGS_OPT_IS_TOPL_DETECT_STALE_DISABLED = 0x00000008,
NTDSSETTINGS_OPT_IS_INTER_SITE_AUTO_TOPOLOGY_DISABLED = 0x00000010,
NTDSSETTINGS_OPT_IS_GROUP_CACHING_ENABLED = 0x00000020,
NTDSSETTINGS_OPT_FORCE_KCC_WHISTLER_BEHAVIOR = 0x00000040,
NTDSSETTINGS_OPT_FORCE_KCC_W2K_ELECTION = 0x00000080,
NTDSSETTINGS_OPT_IS_RAND_BH_SELECTION_DISABLED = 0x00000100,
NTDSSETTINGS_OPT_IS_SCHEDULE_HASHING_ENABLED = 0x00000200,
NTDSSETTINGS_OPT_IS_REDUNDANT_SERVER_TOPOLOGY_ENABLED = 0x00000400,
NTDSSETTINGS_OPT_W2K3_IGNORE_SCHEDULES = 0x00000800,
NTDSSETTINGS_OPT_W2K3_BRIDGES_REQUIRED = 0x00001000 }
"@
ForEach($Site In (Get-ADObject -Filter 'objectClass -eq "site"' -Searchbase (Get-ADRootDSE).ConfigurationNamingContext))
{
$SiteSettings = Get-ADObject "CN=NTDS Site Settings,$($Site.DistinguishedName)" -Properties Options
If(!$SiteSettings.PSObject.Properties.Match('Options').Count -OR $SiteSettings.Options -EQ 0)
{
# I went with '(none)' here to give it a more classic repadmin.exe feel.
# You could also go with $Null, or omit the property altogether for a more modern, Powershell feel.
[PSCustomObject]@{SiteName=$Site.Name; DistinguishedName=$Site.DistinguishedName; SiteOptions='(none)'}
}
Else
{
[PSCustomObject]@{SiteName=$Site.Name; DistinguishedName=$Site.DistinguishedName; SiteOptions=[Enum]::Parse('nTDSSiteSettingsFlags', $SiteSettings.Options)}
}
}
}
}
And here it is in action:
The documentation mentioned by Ryan omits 2 NTDSettings Options necessary to support all combinations. Please find below those values found in ntdsapi.h
:
Add-Type -TypeDefinition @"
[System.Flags]
public enum nTDSSiteSettingsFlags {
NTDSSETTINGS_OPT_IS_AUTO_TOPOLOGY_DISABLED = 0x00000001,
NTDSSETTINGS_OPT_IS_TOPL_CLEANUP_DISABLED = 0x00000002,
NTDSSETTINGS_OPT_IS_TOPL_MIN_HOPS_DISABLED = 0x00000004,
NTDSSETTINGS_OPT_IS_TOPL_DETECT_STALE_DISABLED = 0x00000008,
NTDSSETTINGS_OPT_IS_INTER_SITE_AUTO_TOPOLOGY_DISABLED = 0x00000010,
NTDSSETTINGS_OPT_IS_GROUP_CACHING_ENABLED = 0x00000020,
NTDSSETTINGS_OPT_FORCE_KCC_WHISTLER_BEHAVIOR = 0x00000040,
NTDSSETTINGS_OPT_FORCE_KCC_W2K_ELECTIONn = 0x00000080,
NTDSSETTINGS_OPT_IS_RAND_BH_SELECTION_DISABLED = 0x00000100,
NTDSSETTINGS_OPT_IS_SCHEDULE_HASHING_ENABLED = 0x00000200,
NTDSSETTINGS_OPT_IS_REDUNDANT_SERVER_TOPOLOGY_ENABLED = 0x00000400,
NTDSSETTINGS_OPT_W2K3_IGNORE_SCHEDULES = 0x00000800,
NTDSSETTINGS_OPT_W2K3_BRIDGES_REQUIRED = 0x00001000
}
"@
And
SiteOptions=[Enum]::Parse('nTDSSiteSettingsFlags', $SiteSettings.Options)
can be simplified by
SiteOptions=[nTDSSiteSettingsFlags]$SiteSettings.Options