A Useful PowerShell Script to Document Your Active Directory Environment

As you probably know by now, documenting your Active Directory environment is a crucial aspect of keeping your AD in good health. It’s also important in preparing for disaster recovery scenarios. Although some tools exist that can help you with some tedious aspects of documentation, most tools still leave much to be desired.

Many AD settings, configurations and options are not easily viewed from the graphical user interface, where many require extra digging in the layers of menus and commands. There’s also several configurations that you might not be aware of and are only known to you once something bad happens and you are forced to hire an AD expert that will try to dig out the remains for you.

Using PowerShell to Document your Active Directory Forest

Other settings and configurations can be seen from the GUI, but are not easy to document. Considering that the AD environment is one that changes, you’re left with the task of keeping it up to date every few months.
Here’s where PowerShell and its AD cmdlets come to the rescue. PowerShellp helps reduce the time required to obtain information about Active Directory forest and domain(s) configurations. Because most Active Directory environments has at least one Windows Server 2008 R2 or higher domain controller that’s running Active Directory Web Services, you can utilize PowerShell 2.0 to get most required information.

Krzysztof Pytko’s ADReport PowerShell Script

In my quest to create a presentation for a Microsoft event that I was invited to speak at, I came across this nifty PowerShell script written by Krzysztof Pytko, an Active Directory expert from Poland. He is working in a big international company as Subject Matter Expert for Active Directory where he is able to develop his Active Directory skills.
After playing around with the script I asked his permission to write about it and also asked him to add several additions to it in order to make it more complete.

(If you need direct help, you can find him on Microsoft Technet and Experts Exchange forums or send him an e-mail.)

So here it is.

After downloading, extract it to a folder of your choice, and read on.
Script requirements:

  • You must have at least one accessible Windows Server 2008 R2 or higher domain controller in the domain.
  • Active Directory Web Services is required to execute the script successfully.
  • Either run the script on the Windows Server 2008 R2 domain controller or have at least one more Windows Server 2008 R2 or higher domain member or Windows 7 or higher workstation with RSAT tools installed to load Active Directory module for PowerShell.
  • A regular domain user account is allowed to execute the script if no custom privileges delegation control is implemented.

The script is read-only, and it makes no changes to the AD database or environment.
You can simply run it within PowerShell console without any parameters, and it will start scanning the currently logged-on forest with all its domains. When you specify a parameter, it must be DNS forest name, where the scan is performed for the specified forest.
Note: The output color in red is related to scanned data and does not refer to an error. This color only emphasizes the setting that you should pay attention to.
PowerShell cmdlets used in the script:

  • Import-Module ActiveDirectory (loads PowerShell module for Active Directory)
  • Get-ADForest (get forest DNS name, create list of domains, get forest-wide FSMO roles, get FFL, check additional UPN suffixes, check AD schema version, check Exchange version and its organization name, check Lync version, check tombstone lifetime)
  • Get-ADDomain (get Domain DNS and NetBIOS name, get each domain’s SID, read Distinguished Name, get domain-wide FSMO roles, get DFL, list of RODC, users and computers default creation place)
  • Get-ADDomainController (get information about domain controllers)
  • Get-ADDefaultDomainPasswordPolicy (check default password policy configuration)
  • Get-ADFineGrainedPasswordPolicy (count additional password policies, if they are available)
  • Get-ADUser (get total number of domain users, information about total number of active/inactive/locked out users, information about password never expires or it’s not required for users)
  • Get-ADGroup (get total number of local, global and universal groups)
  • Get-ADGroupMember (count Enterprise Administrators, Schema Administrators and Domain Administrators groups members, )
  • Get-ADComputer (get total number of computers in a domain, get total number of computers with particular Windows OS version)
  • Get-ADOrganizationalUnit (get total numbers or organizational units)
  • Get-ADObject (receive additional attributes not available through built-in cmdlets)
  • Get-ADOptionalFeature (check AD Recycle Bin feature)

Objects queried:

  • Schema partition (to determine current schema level)
  • Configuration partition (to get Sites, Site Links, Subnets, Global Catalog DCs,
  • Domain partition (to query domain specific objects: users, groups, computers, OUs, password policy, FGPP (PSO)
  • Schema partition (for versions)
  • Configuration partition (for forest, trusts, sites configuration)
  • SYSVOL share amd SYSVOL replication method
  • Lost and Found to get information about orphaned objects
  • Objects with *ACNF:* identifier to enumarate lingering or conflict replication objects
  • Default Domain and Default Domain Controller GPO objects if they exist


List of attributes used:

  • To determine Schme version objectVersion attribute is checked
  • For Domain Controllers, their computer object is queried for: operatingSystem, operatingSystemServicePack attributes
  • Built-in domain administrator account and its user object is queried for: Name, LastLogonDate, PasswordLastSet, PasswordNeverExpires, whenCreated, Enabled attributes
  • Enterprise, Schema and Domain Administrators groups are queried for: Members attribute
  • Site object is queried for siteObjectBL attribute to get list of Subnets
  • SiteLink object is queried for name, cost, replInterval attributes