One of the biggest security issues that organizations face with Windows Server Active Directory is the proliferation of accounts with privileged access to a domain or forest. Microsoft’s own best practices say that access to privileged groups, like Domain Admins, should be limited to just a few accounts and only used when necessary. But it’s common to find many accounts added to Domain Admins, Enterprise Admins, and other privileged groups.
If IT staff are often granted privileged access to AD, sometimes for valid reasons. But permanent access to privileged AD groups is likely to lead to compromise. When Active Directory privileged accounts credentials are used for everyday computing tasks, it’s easy for hackers to take advantage and use them to get access to AD. So, as part of your security checks, it’s a good idea to make sure that privileged AD groups stay as empty as possible.
Before you can run the code in this article, you need to install the PowerShell module for Windows Server Active Directory. The Active Directory PowerShell module is installed on domain controllers (DC) by default. But it is best practice to perform everyday administration tasks from a domain-joined Windows 10 PC.
The AD PowerShell module is part of the Remote Server Administration Tools (RSAT) for Active Directory Domain Services. To install the RSAT AD tools, open a PowerShell prompt with local administrator privileges and run the following command:
Add-WindowsCapability -Name Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0 –Online
Once the tools have installed, you can close the elevated PowerShell window. To run the rest of the commands in this article, you need only be logged in to Windows 10 with an account that’s a member of the Active Directory ‘Domain Users’ group.
For more information on installing RSAT in Windows 10, see How to Install the Remote Server Administration Tools in Windows 10 on Petri.
Let’s start by defining an array ($groups) that contains the Active Directory privileged accounts we want to list. In this example, I want to see the membership of the Domain Admins and Enterprise Admins groups. Note that the group names are surrounded by single quotes because they both contain a space.
$groups = 'Domain Admins','Enterprise Admins'
Next, we’re going to create an empty array called $members, which will store the members of each group in the $groups array.
$members =@()
Using a ForEach loop, we can iterate through each $group in $groups using Get-ADGroupMember. The Get-ADGroupMember cmdlet includes the -Recursive parameter, which returns all members of the group hierarchy.
foreach ($group in $groups) { $members = Get-ADGroupMember -Identity $group -Recursive | Select-Object distinguishedName, samaccountname, name, @{Label='Group Name';Expression={$group}} $members }
Now that we have an object returned from the Get-ADGroupMember cmdlet, let’s create a new object by piping the results of Get-ADGroupMember to Select-Object. Get-ADGroupMember outputs 6 properties by default. But we only need 3 of them, and an additional property that we’ll create ourselves as part of the new object. As you can see in the code, we’ll use the distinguishedName, samaccountname, and name properties directly from the Get-ADGroupMember object.
The fourth property we’ll calculate using @{Label=’Group Name’;Expression={$group}}. @ indicates a calculated property that must have a label and calculated value (expression). Our calculated property is called ‘Group Name’ and it shows the name of the current group ($group).
Now if you run the code, you will see the output listing the members of each group listed in the $groups array as shown in the figure above.
Unmonitored Active Directory privileged accounts can lead to data breaches, insider threats, and lateral movement within the network. Hackers can exploit dormant privileged accounts to gain unauthorized access to critical systems and potentially compromise the entire domain infrastructure.
Active Directory privileged accounts should have their passwords changed every 30-60 days, with some organizations requiring changes every 30 days for highly sensitive accounts. Implementing a Privileged Access Management (PAM) solution can automate this process.
Regular auditing of Active Directory privileged accounts should include monitoring login patterns, reviewing access times, tracking failed login attempts, and documenting all privilege escalations. Additionally, implementing just-in-time access can significantly reduce security risks.
Organizations can prevent misuse by implementing role-based access control (RBAC), using dedicated admin workstations, enabling multi-factor authentication, and maintaining detailed logs of all privileged account activities. Regular security training for staff with privileged access is also crucial.
Organizations should maintain secure offline backups of Active Directory privileged accounts credentials, implement emergency access procedures, and regularly test disaster recovery scenarios. Having a break-glass procedure for critical privileged accounts is essential for business continuity.