Managing AD Users and Groups with PowerShell

PowerShell’s ActiveDirectory module provides a comprehensive set of cmdlets for creating, modifying, querying, and removing user and group objects in Active Directory. While the graphical ADUC console works well for one-off tasks, scripting with PowerShell is essential for bulk operations, consistent provisioning, and automation. On Windows Server 2022, the ActiveDirectory module is available as part of the RSAT tools installed with the AD DS role or via the RSAT feature set.

Import the module before running any AD cmdlets:

Import-Module ActiveDirectory

Creating a New AD User with New-ADUser

New-ADUser creates a user account in Active Directory. By default, the account is created in a disabled state — you must explicitly enable it or use -Enabled $true during creation. The following example creates a user with a comprehensive set of attributes:

New-ADUser `
  -Name "John Smith" `
  -GivenName "John" `
  -Surname "Smith" `
  -SamAccountName "jsmith" `
  -UserPrincipalName "[email protected]" `
  -DisplayName "John Smith" `
  -Description "Finance Department" `
  -Department "Finance" `
  -Title "Senior Analyst" `
  -Company "Example Corp" `
  -Office "New York" `
  -OfficePhone "212-555-0101" `
  -EmailAddress "[email protected]" `
  -Path "OU=Finance,OU=Users,DC=corp,DC=example,DC=com" `
  -AccountPassword (ConvertTo-SecureString "InitialP@ss2024!" -AsPlainText -Force) `
  -ChangePasswordAtLogon $true `
  -Enabled $true `
  -PasswordNeverExpires $false `
  -CannotChangePassword $false

The -Path parameter specifies the OU where the user will be created using its Distinguished Name (DN). If the OU does not exist, the cmdlet will fail. The -ChangePasswordAtLogon $true flag forces the user to set a new password at their first logon, which is a security best practice for initial account creation.

Modifying Users with Set-ADUser

Set-ADUser updates properties on existing user objects. You can pipe a user object from Get-ADUser or reference the user by SamAccountName, DistinguishedName, or GUID:

# Update title and department
Set-ADUser -Identity "jsmith" -Title "Finance Manager" -Department "Finance Leadership"

# Update manager attribute (must be DN or SamAccountName of the manager)
Set-ADUser -Identity "jsmith" -Manager "mjohnson"

# Set multiple attributes including extensionAttribute for custom data
Set-ADUser -Identity "jsmith" -Add @{extensionAttribute1="EMP-00142"}

# Replace an existing multi-value attribute
Set-ADUser -Identity "jsmith" -Replace @{proxyAddresses="smtp:[email protected]","SMTP:[email protected]"}

# Clear an attribute
Set-ADUser -Identity "jsmith" -Clear description

The -Add, -Replace, -Remove, and -Clear parameters give fine-grained control over multi-value LDAP attributes. Use -Replace when you want to overwrite the entire attribute value, -Add to append to it, and -Remove to delete a specific value from the attribute.

Querying Users with Get-ADUser

Get-ADUser retrieves one or more users from AD. Without a filter it requires -Identity for a single user, or -Filter for a search. The -Properties parameter specifies which attributes to retrieve — by default only a subset of common attributes is returned:

# Get a single user with all properties
Get-ADUser -Identity "jsmith" -Properties *

# Get all users in the Finance department
Get-ADUser -Filter {Department -eq "Finance"} -Properties Department, Title, Manager

# Get all disabled accounts
Get-ADUser -Filter {Enabled -eq $false} -Properties LastLogonDate | Select-Object Name, SamAccountName, LastLogonDate

# Get users who have not logged on in 90 days
$90days = (Get-Date).AddDays(-90)
Get-ADUser -Filter {LastLogonDate -lt $90days -and Enabled -eq $true} -Properties LastLogonDate

# Search by OU (SearchBase restricts scope)
Get-ADUser -Filter * -SearchBase "OU=Finance,OU=Users,DC=corp,DC=example,DC=com" -Properties EmailAddress

For complex queries, use -LDAPFilter which accepts standard LDAP filter syntax. This is more flexible for attribute comparisons that the PowerShell filter syntax does not handle cleanly:

# Find all users where the description attribute is set (not null)
Get-ADUser -LDAPFilter "(description=*)" -Properties description

# Find users with a specific email domain
Get-ADUser -LDAPFilter "(mail=*@corp.example.com)" -Properties mail

# Find locked-out accounts
Get-ADUser -LDAPFilter "(lockoutTime>=1)" -Properties LockedOut, LockoutTime

Removing Users and Handling Dependencies

Remove-ADUser deletes a user account permanently. There is no Recycle Bin unless the AD Recycle Bin feature is enabled. Always confirm the correct user before deletion:

# Confirm identity before deleting
Get-ADUser -Identity "jsmith" | Select-Object Name, SamAccountName, DistinguishedName

# Delete the user (prompts for confirmation by default)
Remove-ADUser -Identity "jsmith"

# Delete without confirmation prompt (use in scripts)
Remove-ADUser -Identity "jsmith" -Confirm:$false

Rather than deleting accounts, a better practice is to disable them and move them to a Disabled Users OU for a retention period before deletion:

Disable-ADAccount -Identity "jsmith"
Move-ADObject -Identity "CN=John Smith,OU=Finance,OU=Users,DC=corp,DC=example,DC=com" `
  -TargetPath "OU=Disabled,OU=Users,DC=corp,DC=example,DC=com"

Creating and Managing AD Groups

New-ADGroup creates security or distribution groups. Security groups are used for permission assignments and can also receive email in Exchange environments. Distribution groups are used only for email distribution and cannot be used for access control. Group scope determines where the group can be used: Domain Local (used within its own domain), Global (members from same domain, usable anywhere in forest), and Universal (members from any domain, usable anywhere, replicated to Global Catalog).

# Create a Domain Local security group
New-ADGroup `
  -Name "Finance-Readers" `
  -SamAccountName "Finance-Readers" `
  -GroupCategory Security `
  -GroupScope DomainLocal `
  -Description "Read access to Finance file shares" `
  -Path "OU=Groups,DC=corp,DC=example,DC=com"

# Create a Global security group
New-ADGroup `
  -Name "Finance-Users" `
  -SamAccountName "Finance-Users" `
  -GroupCategory Security `
  -GroupScope Global `
  -Description "All Finance department employees" `
  -Path "OU=Groups,DC=corp,DC=example,DC=com"

# Create a Universal distribution group
New-ADGroup `
  -Name "DL-AllStaff" `
  -SamAccountName "DL-AllStaff" `
  -GroupCategory Distribution `
  -GroupScope Universal `
  -Path "OU=Distribution Lists,DC=corp,DC=example,DC=com"

Adding and Removing Group Members

Add-ADGroupMember adds user accounts, computer accounts, or other groups as members. You can add members individually or in bulk:

# Add a single user to a group
Add-ADGroupMember -Identity "Finance-Users" -Members "jsmith"

# Add multiple users at once
Add-ADGroupMember -Identity "Finance-Users" -Members "jsmith","mjohnson","ablack"

# Add all users from a specific OU to a group
Get-ADUser -Filter * -SearchBase "OU=Finance,OU=Users,DC=corp,DC=example,DC=com" | 
  ForEach-Object { Add-ADGroupMember -Identity "Finance-Users" -Members $_ }

# Add a group as member of another group (nesting)
Add-ADGroupMember -Identity "Finance-Readers" -Members "Finance-Users"

# Remove a member from a group
Remove-ADGroupMember -Identity "Finance-Users" -Members "jsmith" -Confirm:$false

List members of a group:

# Direct members only
Get-ADGroupMember -Identity "Finance-Users"

# Recursive (includes nested group members)
Get-ADGroupMember -Identity "Finance-Users" -Recursive | Select-Object Name, SamAccountName, objectClass

Bulk User Creation from CSV

One of the most common administrative tasks is bulk user creation from a CSV file exported from HR systems. Create a CSV file with headers matching the properties you need:

FirstName,LastName,Department,Title,Email,Manager
Jane,Doe,Finance,Analyst,[email protected],jsmith
Robert,Brown,IT,Engineer,[email protected],it_manager
Sarah,Wilson,HR,Coordinator,[email protected],hr_director

Then import and create users in a loop:

$users = Import-Csv -Path "C:Tempnew_users.csv"

foreach ($user in $users) {
    $sam = ($user.FirstName[0] + $user.LastName).ToLower()
    $upn = "[email protected]"
    $displayName = "$($user.FirstName) $($user.LastName)"
    
    try {
        New-ADUser `
          -Name $displayName `
          -GivenName $user.FirstName `
          -Surname $user.LastName `
          -SamAccountName $sam `
          -UserPrincipalName $upn `
          -DisplayName $displayName `
          -Department $user.Department `
          -Title $user.Title `
          -EmailAddress $user.Email `
          -Manager $user.Manager `
          -Path "OU=$($user.Department),OU=Users,DC=corp,DC=example,DC=com" `
          -AccountPassword (ConvertTo-SecureString "WelcomeP@ss2024!" -AsPlainText -Force) `
          -ChangePasswordAtLogon $true `
          -Enabled $true
        
        Write-Host "Created: $displayName ($sam)" -ForegroundColor Green
    }
    catch {
        Write-Host "ERROR creating $displayName : $_" -ForegroundColor Red
    }
}

Password Management

Set-ADAccountPassword changes a user’s password. This requires the -Reset parameter when called from an admin context (bypassing the requirement to know the old password):

# Reset a password administratively
Set-ADAccountPassword -Identity "jsmith" `
  -Reset `
  -NewPassword (ConvertTo-SecureString "NewP@ssword2024!" -AsPlainText -Force)

# Force password change at next logon after reset
Set-ADUser -Identity "jsmith" -ChangePasswordAtLogon $true

# Unlock a locked-out account
Unlock-ADAccount -Identity "jsmith"

# Check password expiry info for a user
Get-ADUser -Identity "jsmith" -Properties PasswordLastSet, PasswordExpired, PasswordNeverExpires, LockedOut

To enable and disable accounts:

Disable-ADAccount -Identity "jsmith"
Enable-ADAccount -Identity "jsmith"

# Bulk disable stale accounts (not logged in for 180 days)
$staleDate = (Get-Date).AddDays(-180)
Get-ADUser -Filter {LastLogonDate -lt $staleDate -and Enabled -eq $true} -Properties LastLogonDate |
  Disable-ADAccount

These PowerShell techniques cover the full lifecycle of user and group management in Active Directory on Windows Server 2022. Combined with scheduled tasks or automation platforms, they form the backbone of a consistent, auditable identity management process.