top of page

Securing Active Directory: Performing an Active Directory Security Review

Updated: Feb 13

During the Trimarc Webcast on June 17, 2020, Sean Metcalf covered a number of Active Directory (AD) components and areas that should be reviewed for potential security issues. The presentation included PowerShell code in the presentation and that code is incorporated in the PowerShell script Trimarc released for free that can be used to perform an AD security scan. This script is called Invoke-TrimarcADChecks.ps1 and only needs AD user rights to be run.

Download the Invoke-TrimarcADChecks,ps1 by visiting the Trimarc Github Page. Last updated: 02-13-2024

The Invoke-TrimarcADChecks.ps1 PowerShell script is designed to gather data from a single domain AD forest based on our similar checks performed during Trimarc’s Active Directory Security Assessment (ADSA) engagement. It can be run against each domain in a multi-domain environment, but there is no guarantee that it captures the type of cross-domain (or cross-forest) data elements that may be involved. This script is meant to enable smaller organizations to more quickly identify potential issues. For larger, more complex AD environments, please contact Trimarc to talk about your concerns.

This script is designed for a single AD forest and is not designed to capture all data for a multiple domain forest. If this script is used for a single domain in a multi-domain AD forest, not all elements may be captured.

The Invoke-TrimarcADChecks.ps1 PowerShell script requires the following:

  • PowerShell 5.0 (minimum)

  • Windows 10 or Windows Server 2016 (or newer)

  • Active Directory PowerShell Module

  • Group Policy PowerShell Module

If the above requirements are not met, results will be inconsistent.

This script is licensed under BSD 3-Clause License and is provided as-is, without support.

The PowerShell script gathers domain data using the Active Directory PowerShell & Group Policy modules and displays some results on the screen. The data shown on the screen is also saved to a transcript log file and all captured data is also saved to csv/text files in c:\temp\Trimarc-ADReports (report folder is created upon script execution and this folder location can be changed).

This article covers the key AD security areas in which the Invoke-TrimarcADChecks.ps1 PowerShell script gathers data.

The Invoke-TrimarcADChecks PowerShell script gathers data for key AD security items in a domain:

  • User Account Issues

  • Domain Password Policy

  • Tombstone Lifetime & AD Backup Dates

  • Trusts

  • Duplicate SPNs

  • Group Policy Preference Passwords

  • AD Administration & Privileged Accounts

  • KRBTGT Account

  • Kerberos Delegation

  • Group Policy Object Owners

User Account Issues

There are several potential issues that Active Directory domain user accounts may have. Trimarc scans for these (and others) during our Active Directory Security Assessment (ADSA) engagement.

  • Inactive accounts – these are accounts that have not changed their password or logged on in a while (we typically focus on accounts with a combination of Password Age & User Logon Age over 90 to 180 days old)

  • Reversible Encryption – accounts configured with reversible encryption are stored in the AD database in a reversible format (which effectively means a clear-text version of the password is available).

  • Password Not Required – accounts created programmatically may have this set which means that technically a password is not required for the account to authenticate.

  • Password Never Expires – accounts with a password that is not subject to password expiration requirements. These accounts typically have very old passwords.

  • DES Kerberos Encryption Enabled – accounts enabled for Kerberos DES encryption.

  • Do not require Kerberos Pre-Authentication – accounts that don’t require Kerberos pre-authentication. There are known attacks against accounts with this configuration.

  • SID History – accounts with SID History configured

Trimarc Recommendation:

  • Disable and eventually delete inactive accounts

  • Remove the following from accounts:

    • Reversible Encryption

    • Password Not Required

    • Password Never Expires

    • DES Kerberos Encryption Enabled

    • Do not require Kerberos Pre-Authentication

      • Review accounts configured with SID History and clean up SIDs in SID History for accounts from domains that no longer have trusts configured with them.

Sample PowerShell Code & Results:

Domain Password Policy

The Domain Password policy determines how passwords are created and how often they need to be changed, etc. The AD default password minimum is 7 characters. Most AD environments we see have this set to between 8 and 10. Some are set to 0 or 3 or 5.

Password Spray attacks are effective against Active Directory due to bad passwords (often with short minimum requirements).Increasing password length can limit Password Spray effectiveness. Fine-Grained Password Policies (FGPP) provide additional flexibility, especially for admin and service accounts.

Trimarc Recommendation: Trimarc recommends that the Domain Password Policy be set to 12 characters (preferably 14 to 16 characters).

Sample PowerShell Code & Results:

The Active Directory module cmdlet “Get-ADPasswordPolicy” can easily capture the domain password policy.

Tombstone Lifetime

The AD Tombstone Lifetime determines how long deleted items exist in AD before they are purged. The default value was originally 60 days, but this was increased to 180 days starting with new AD forests created with Windows 2003 SP1. While the tombstone lifetime directly affects deleted items, it also has an impact on Domain Controllers. If a DC hasn’t replicated within the tombstone lifetime with another DC, it is effectively orphaned from the domain. Additionally, DC backups are only useful for restoring AD data within this tombstone lifetime – a backup that is 181 days old is no longer useful when the tombstone lifetime is 180 days.

Trimarc Recommendation: Trimarc recommends configuring the Tombstone Lifetime to 180 days (or more if needed).

Active Directory Backups

Microsoft supported backups update a partition attribute to identify the last backup date for that partition. Not all systems that backup Active Directory set this attribute since they are likely not using a Microsoft supported method. In most scenarios, System State Backups on a Domain Controller are required to properly backup AD. We can easily check last Microsoft supported AD backup date/time by querying an attribute on each partition. Trimarc also identified that events like “Install From Media” creation on a DC can update AD backup date/time attribute.

Trimarc Recommendation:

Ensure you run a System State Backup on at least the FSMO role holders in the AD forest at least once a month and keep for at least 6 months.

Sample PowerShell Code & Results:


An Active Directory forest is the security boundary for AD. When a trust is configured, that extends the security boundary in include the system included in the trust since the trust extends the authentication boundary.

Trimarc Recommendation:

  • Review trust configuration & ensure that trusts are appropriate. Trusts should be reviewed at least annually to ensure they are still required

  • Bidirectional trusts should be scrutinized to ensure they need to be two-way trusts and still required.

  • Trusts with DMZ environments should be removed (if possible).

  • If a trust is required, look to shift to Selective Authentication which changes from Allow All to only those explicitly allowed to connect across the trust.

Selective Authentication changes the default behavior from allow any user across the trust to see everything to users require explicit approval to access resources otherwise they can’t view or access anything across the trust

Sample PowerShell Code & Results:

Active Directory Duplicate Service Principal Names (SPNs)

The Kerberos Service Principal Name (SPN) is effectively a signpost that connects a service on a server supporting Kerberos authentication with the service account. When there are duplicate SPNs, Kerberos authentication breaks since a Domain Controller can’t identify a single account associated with the SPN. Authentication will need to fallback to NTLM authentication. Duplication of the Krbtgt config is normal in a multiple domains in an AD forest.

Trimarc Recommendation:

Ensure there aren’t any duplicate SPNs (other than krbtgt).

Sample Code & Results:

Using SetSPN.exe we can discover any duplicate SPNs in the forest using the following command:

SetSPN -X -F

Any identified duplicate SPNs should be resolved since duplicate SPNs break Kerberos authentication which forces NTLM for authentication.

Group Policy Preference Passwords

Group Policy Preferences was released in the 2008 time-frame and included capability to provide and update credentials. These credentials were encrypted using AES256 which sounds good until you realize that a static key is used to encrypt them. The cpassword value in the GPP xml files is the encrypted password. Using a PowerShell function from PowerSploit, we can reverse this encryption and get the plain-text value. Since authenticated users have read access to Group Policies in the SYSVOL share on all DCs, anyone can view this information and get the passwords stored in GPP xml files, even across trusts. This is less of an issue now that Microsoft released a patch preventing the use of Group Policy Preference passwords. Old GPOs with these credentials remain though and Trimarc has identified a few in the past year during AD security assessments that would lead to either full AD compromise or compromising sensitive server data.

GPP capability with credentials:

  • Map drives (Drives.xml)

  • Create Local Users

  • Data Sources (DataSources.xml)

  • Printer configuration (Printers.xml)

  • Create/Update Services (Services.xml)

  • Scheduled Tasks (ScheduledTasks.xml)

  • Change local Administrator passwords

Trimarc Recommendation:

  • Ensure there are no Group Policy Preference passwords in SYSVOL.

Sample Code & Results:

The fast way to identify passwords in Group Policy Preferences is by using the findstr.exe command:

Findstr /S /I cpassword [SYSVOL_PATH]

A more comprehensive method is the Microsoft scanner provided here.

Active Directory Admin Account Checks

During Trimarc’s standard Active Directory Security Assessment, we focus on identifying “AD Admins” which includes members of the domain Administrators group, Domain Admins, Enterprise Admins, etc. These accounts have full AD rights and require careful protection.

The fastest way to identify AD admins is to run the following command which leverages the AD PowerShell module:

Get-ADGroupMember ‘Administrators’ -Recursive

Trimarc Recommendation:

  • Ensure passwords change regularly (every year)

  • Disable inactive account

  • Remove disabled accounts

  • Ensure no SPNs on accounts associated with people

  • Remove any computer accounts

  • Scrutinize Service Accounts

    • What do they do?

    • Where do they run?

    • What computers do they authenticate to?

    • What rights are actually required?

PowerShell Sample Code & Results:

First, we get the recursive membership of the domain Administrators group (which includes all the members of member groups).

Then, loop through them and get more detail from each member.

AD Admin Accounts Not Member of Protected Users

Protected Users is a new group created when the domain PDC Emulator is running Windows Server 2012 R2. Full Domain protection is only available when the domain functional level is 2012 R2.

Protected Users group provides additional protections:

  • Kerberos AES authentication only (No Kerberos DSE/RC4 or NTLM)

  • No Kerberos delegation (constrained or unconstrained)

  • Kerberos TGT set to 4 hours

  • Credential delegation (CredSSP) will not cache the user's plain text credentials

  • NTLM will not cache the user's plain text credentials or NT one-way function

  • Offline sign-in is not supported

Trimarc Recommendation:

  • All AD Admin accounts should be added to the “Protected Users” group

PowerShell Sample Code & Results:

Compare AD Admins group membership output with the results of the following command:

Get-ADGroupMember ‘Protected Users’

AD Admins with Old Passwords

AD Admin accounts with old passwords, especially those older than 5 years, are vulnerable to password spraying (and password guessing).

Trimarc Recommendation:

  • Ensure privileged account passwords change annually.

  • Older passwords are typically poor and easier to guess.

  • Password Spraying & Kerberoasting are popular attack methods for compromising accounts lacking strong passwords.

PowerShell Sample Code & Results: Note that this check leverages the AD Admin array data collected earlier.

Using the information from PowerShell, we can build a table in Excel.

This is an adjusted version similar to what we find in customer environments during AD security assessments

AD Admins with Kerberos Service Principal Names (SPNs)

Kerberos Service Principal Name or SPN is effectively the signpost that points to the service account for a service on a server that supports Kerberos authentication. When the client needs to connect to a service, it must request a Kerberos service ticket from a DC and in order to do this it needs to provide a SPN for that service. The DC looks up the account in the AD forest that has that SPN, identifies the account, and uses the account’s password data to encrypt the ticket. Once the service ticket is delivered to the service, it attempts to open the service ticket and if it can, it can assume the DC provided it, so it validates access for the user.

Kerberoasting, developed by Tim Medin in 2014, requests service tickets (usually RC4 encrypted) for target service accounts and saves them to attempt offline brute password forcing – once the attacker can open a service ticket, they have successfully guessed the account password. This is a big deal and I have been talking about the importance of ensuring AD admin accounts don’t have SPNs and service accounts needing long passwords since Tim released his Kerberoast tool at DerbyCon 2014.

Attackers can “Kerberoast” accounts with Kerberos Service Principal Names (SPNs). This shifted attacking service accounts with old passwords from hypothetical to practical and many attackers use this method now. Trimarc published Kerberoast detection with 100% accuracy, no false positives as while back on the Trimarc website.

Kerberoast in a nutshell:

  1. Request Kerberos service ticket for SPN (RC4 encrypted which uses the NT password hash for the ticket encryption key).

  2. Move the service ticket to a password cracking system and perform hybrid password guessing

  3. Guess the password correctly and the service ticket opens.

Trimarc Recommendation:

  • Ensure that no AD Admin accounts associated with people have SPNs.

  • Limit service account membership in privileged Active Directory groups and ensure these service account passwords are longer than 25 characters (to mitigate Kerberoasting).

PowerShell Sample Code & Results:

Here we simply filter the AD Admins list by only displaying the accounts with SPNs. Note that this check leverages the AD Admin array data collected earlier.

Check Default Domain Administrator Account for Issues

The default domain administrator account should only be used when the other AD admin accounts are inaccessible. It should not be logged on to so set loud alerting for when it does. This account should never have a SPN since that means it is being used as a service account for a service on a server on the network. This means that compromise of that server would compromise Active Directory. Or Kerberoast the domain Administrator account and get that password to compromise AD.

If this account is disabled, GREAT! Are you monitoring for it being re-enabled?

Trimarc Recommendation:

  • The account password should change at least annually (and when an AD Admin leaves the organization).

  • Ensure the account has no SPNs.

  • Account should be reserved as an emergency account (aka “break glass).

  • The account can be enabled or disabled.

PowerShell Sample Code & Results:

Review AD Default/Built-In Group Membership

Reviewing the default privileged groups in Active Directory is important to identify accounts with high-level privileges.

Trimarc Recommendation:

  • Ensure that only accounts that require full AD rights are members of these groups.

PowerShell Sample Code & Results:

We can create an array of the default/builtin common groups that have privileged in AD and loop through these to get the group membership

Here’s the looping code which gets the group membership and counts members. Note this membership enumeration is NOT recursive, so any groups listed in these groups need to be enumerated separately (add to the Array above to include them).

The following screenshots show output. The PowerShell script will show an error if it can’t enumerate the group which is usually because it doesn’t exist (or is inaccessible).

Default AD Groups: Administrators

Default Rights:

  • Active Directory admin rights (for the domain)

  • Domain Controller admin rights (for the domain)

PowerShell Sample Code & Results:

Get-ADGroupMember ‘Administrators’


Default AD Groups: Domain Admins

Default Rights:

  • Membership in the domain Administrators group which provides most rights.

  • Active Directory admin rights (for the domain)

  • Domain Controller admin rights (for the domain)

  • Default rights on all domain Group Policies

  • Default local Administrator on all domain-joined computers

PowerShell Sample Code & Results:

Get-ADGroupMember ‘Domain Admins’


Default AD Groups: Enterprise Admins

Default Rights:

  • Membership in every domain Administrators group which provides most rights.

  • Active Directory admin rights (in every forest domain)

  • Domain Controller admin rights (in every forest domain)

  • Default rights on all domain Group Policies

  • This group should remain empty in a single domain forest and membership very limited in a multi-domain forest.

PowerShell Sample Code & Results:

Get-ADGroupMember ‘Enterprise Admins’


Default AD Groups: Server Operators

This group is effectively “Domain Controller Admins” and members of this group should be scrutinized at a similar level to Domain Admins. This group has no default members. Default Rights:

  • Default rights on Domain Controllers:

    • Log on locally

    • create and delete shared resources

    • start and stop some services

    • backup and restore files

    • format the hard disk

    • shut down the computer

PowerShell Sample Code & Results:

Get-ADGroupMember ‘Server Operators’


Default AD Groups: Account Operators

This group has no default members. This group should remain empty.

Default Rights:

  • Has rights to most objects in the domain (users, groups, computers, etc).

Microsoft recommends this group remain empty.

PowerShell Sample Code & Results:

Get-ADGroupMember ‘Account Operators’

Privileged Group: VMWare Admins

Trimarc sees “VMWare Admins” in most environments. The VMWare Admins AD group is granted full VMWare Admin rights. This means that if an attacker can compromise an account that is a member of the VMWare Admins group, they can compromise VMWare. In an environment with virtual Domain Controllers hosting in VMWare, this would result in AD compromise.

Trimarc Recommendation:

  • Ensure that “admin” groups only contain admin accounts.

  • Ensure that VMWare Admins follow privileged account best practices:

    • Use separate admin accounts

    • Use admin workstations

    • Passwords change about once a year

PowerShell Sample Code & Results:

Get-ADGroupMember ‘VMWare Admins’

Krbtgt Password Not Changed Recently

The krbtgt account is the domain service account. This account is disabled but used for Kerberos Tickets. The password set when created & practically never changes. DC/AD backups contains the KRBTGT account password. If an attacker gains knowledge of this password, they can create Golden Tickets!

Trimarc Recommendation:

  • Change this password 2x every year (DoD STIG requirement)

  • Change after AD admins leave

PowerShell Sample Code & Results:


Kerberos Delegation

Kerberos “Double Hop” Issue

The double hop issue occurs when you have a user connecting to a web server which then connects to a back-end database server. The web server updates records on the back-end database on behalf of the user. The problem is that the TGS Service ticket the user provides to the web server is only good for the web server. The web server can’t authenticate to the database server as the user to make the updates *as* the user. Enter delegation. Kerberos Delegation enables the web server to impersonate the user to the database server in order to perform the updates the user requested.

Kerberos Delegation Types:

  • Unconstrained: Impersonate users connecting to service to ANY Kerberos service.

  • Constrained: Impersonate authenticated users connecting to service to SPECIFIC Kerberos services on servers.

  • Constrained with Protocol Transition: Impersonate any user to SPECIFIC Kerberos services on servers. (aka “Kerberos Magic”)

  • Resource-based Constrained Delegation: Enables delegation configured on the resource instead of the account.

Trimarc Recommendation:

  • Set all AD Admin accounts to: “Account is sensitive and cannot be delegated”

  • Add all AD Admin accounts to the “Protected Users” group (Windows 2012 R2 DCs).

  • Ensure service accounts with Kerberos delegation have long, complex passwords (preferably group Managed Service Accounts).

  • Remove delegation from accounts that don’t require it.

  • Don’t use Domain Controller SPNs when delegating.

  • Work to shift accounts with unconstrained delegation to constrained.

  • Restrict & monitor who has the ability to configure Kerberos delegation.

PowerShell Sample Code & Results:

GPO Permissions: Review Owners

Group Policy Objects (GPO) have owners which are able to change permisisons. Typically when an account creates a GPO, the account that created it is delegate modify rights and I confiugred as the owner.

Trimarc Recommendation:

  • Ensure all GPO owners are set to Domain Admins or Enterprise Admins, especially GPOs linked to the domain root and Domain Controllers OU.

PowerShell Sample Code & Results:

Review Domain Permissions

Domain permissions should be reviewed to ensure that configuration is appropriate. Security of the domain often depends on proper domain permissions.

Trimarc Recommendation:

  • Review domain root permissions with special attention paid to the following:Any non-default admin groups (Domain Admins, domain Administrators, Enterprise Admins, etc) with GenericAll (Full Control), WriteDACL (change permissions), write property (modify), and ExtendedRights.

  • Ensure that the domain root owner is configured to Domain Admins or Enterprise Admins.

PowerShell Sample Code & Results:

The PowerShell script outputs to a CSV file which Excel can open. Use the Data, Filter feature to filter known grouprs from the IdentityReference column (Administrators, Domain Admins, Enterprise Admins, etc). This screenshot shows a sample environment with some IdentityReference filtering.

The following screenshot identify some potentially concerning permissions, including the DS-Replication-Get-Changes & DS-Replication-Get-Changes ExtendedRights.

The following screenshot identifies that the Domain Computers group has GenericAll (Full Control) rights on All objects.

Domain Controllers Running Old Versions

Domain Controllers must be running Microsoft supported Windows versions. You can run all Windows Server 2012 R2 DCs even with older Windows Server versions in the domain (note that some testing to ensure Windows 2003/XP works with the new DCs, especially for SMB shares).

All DCs should be running a minimum of Windows Server 2012 R2, preferably 2016/2019. If all DCs are not running 2012 R2 with 2012R2 DFL, Protected Users group doesn’t have full domain protection.

Trimarc Recommendation:

  • All DCs should be running a minimum of Windows Server 2012 R2, preferably 2016/2019.

PowerShell Sample Code & Results:

AD Forest Functional Level / Domain Functional Level Older than Domain Controller Operating System

The Domain Functional Level (DFL) provides additional AD security features up to Windows Server 2016. Forest & Domain Functional Levels have less emphasis in recent versions. All AD Forests should match the DC version (after all DCs in the AD forest are running the same version). This can be configured after the DCs are updated to a recent OS and have had time to “bake in” over time.

Trimarc Recommendation:

  • Ensure all Domain Controllers are updated to Windwos Server 2012 R2 (or newer) and set DFL/FFL to 2012 R2 (or newer).

PowerShell Sample Code & Results:

Tools for Reviewing AD Note that Trimarc provides these as references and does not necessarily endorse any tool listed

Ping Castle


Trimarc provides leading expertise in security solutions including security reviews, strategy, architecture, and implementation. Our methodology leverages our internal research and custom tooling which better discovers multiple security issues attackers could exploit to compromise the environment. Trimarc security services fit between traditional compliance/audit reviews and standard penetration testing/red teaming engagements, providing deep understanding of Microsoft and Virtualization technologies, typical security issues and misconfigurations, and provide recommendations based on our own best practices custom-tailored to balance operational and security challenges.

49,906 views0 comments

Recent Posts

See All

Video: Protecting Users with “Protected Users”

Despite being around for 9 years, organizations are unaware that the Protected Users AD group exists let alone its benefits. In this talk, you'll learn the What, Why, and How of utilizing this group i


bottom of page