How to Create and Manage AD Users and Groups with PowerShell on Windows Server 2025

Managing Active Directory users and groups from the graphical Active Directory Users and Computers console works fine for occasional tasks, but it quickly becomes impractical when you need to onboard dozens of employees, enforce consistent account configurations, or audit group memberships across the organization. PowerShell’s ActiveDirectory module — included with the Remote Server Administration Tools on Windows Server 2025 — gives you the precision and repeatability that GUI tools cannot match. This tutorial covers the full lifecycle of user and group management: creating, modifying, querying, and removing objects, plus bulk operations from CSV and proper organizational unit management.

Prerequisites

  • A Windows Server 2025 domain controller or member server with RSAT installed
  • The ActiveDirectory PowerShell module: Import-Module ActiveDirectory
  • Domain Admin credentials (or delegated permissions for the target OUs)
  • An established Active Directory domain and organizational unit structure
# Verify the module is available and import it
Get-Module -ListAvailable ActiveDirectory
Import-Module ActiveDirectory

# Confirm connectivity to the domain
Get-ADDomain | Select-Object DNSRoot, NetBIOSName, DomainMode

Step 1: Create a New AD User

The New-ADUser cmdlet creates a user object in Active Directory. The most important parameters are -SamAccountName (the logon name used for legacy systems), -UserPrincipalName (the UPN used for modern authentication and Microsoft 365), and -AccountPassword which must be a SecureString. Setting -Enabled $true activates the account immediately — accounts are disabled by default if this flag is omitted.

# Create a single user account
$Password = Read-Host -Prompt "Enter initial password" -AsSecureString

New-ADUser `
    -Name "Jane Smith" `
    -GivenName "Jane" `
    -Surname "Smith" `
    -SamAccountName "jsmith" `
    -UserPrincipalName "[email protected]" `
    -EmailAddress "[email protected]" `
    -Department "Finance" `
    -Title "Senior Analyst" `
    -Office "London" `
    -AccountPassword $Password `
    -ChangePasswordAtLogon $true `
    -Enabled $true `
    -Path "OU=Finance,OU=Users,DC=corp,DC=example,DC=com"

# Verify the account was created
Get-ADUser -Identity "jsmith" -Properties *

Step 2: Modify an Existing User with Set-ADUser

User attributes change over time — promotions, department transfers, phone number updates. Set-ADUser performs partial updates without touching other attributes. You can pipeline Get-ADUser into Set-ADUser for concise one-liners, or call it by identity for targeted changes.

# Update a single user's department and title
Set-ADUser `
    -Identity "jsmith" `
    -Department "Corporate Finance" `
    -Title "Finance Manager" `
    -Office "New York" `
    -Replace @{ telephoneNumber = "+1-212-555-0100" }

# Force a password reset on next logon
Set-ADUser -Identity "jsmith" -ChangePasswordAtLogon $true

# Disable an account (e.g., during a leave of absence)
Disable-ADAccount -Identity "jsmith"

# Re-enable it
Enable-ADAccount -Identity "jsmith"

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

Step 3: Query Users with Get-ADUser

The -Filter parameter accepts an AD query language expression, while -LDAPFilter accepts raw LDAP syntax. Always specify -Properties when you need attributes beyond the default set (Name, SamAccountName, Enabled, etc.), because AD returns only a minimal subset by default.

# Find all users in the Finance department
Get-ADUser -Filter { Department -eq "Finance" } `
    -Properties Department, Title, EmailAddress |
    Select-Object Name, SamAccountName, Department, Title, EmailAddress

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

# Find accounts that have never logged on
Get-ADUser -Filter { LastLogonDate -notlike "*" } `
    -Properties LastLogonDate |
    Select-Object Name, SamAccountName, LastLogonDate

# Find accounts with passwords that expired more than 90 days ago
$CutOff = (Get-Date).AddDays(-90)
Get-ADUser -Filter { PasswordLastSet -lt $CutOff -and PasswordNeverExpires -eq $false } `
    -Properties PasswordLastSet |
    Select-Object Name, SamAccountName, PasswordLastSet |
    Sort-Object PasswordLastSet

Step 4: Remove a User

# Remove a user account permanently (use with care)
Remove-ADUser -Identity "jsmith" -Confirm:$false

# Best practice: disable and move to a "Disabled Accounts" OU first
Disable-ADAccount -Identity "jdoe"
Move-ADObject `
    -Identity (Get-ADUser "jdoe").DistinguishedName `
    -TargetPath "OU=DisabledAccounts,DC=corp,DC=example,DC=com"

Step 5: Bulk User Creation from CSV

Onboarding multiple employees is most efficiently done by preparing a CSV file with the required attributes and piping it through a ForEach-Object loop. This approach is repeatable, auditable, and far less error-prone than creating accounts manually.

First, create the CSV file (new_users.csv):

FirstName,LastName,SamAccount,UPN,Department,Title,OU
Alice,Johnson,ajohnson,[email protected],Engineering,Developer,"OU=Engineering,OU=Users,DC=corp,DC=example,DC=com"
Bob,Williams,bwilliams,[email protected],HR,HR Specialist,"OU=HR,OU=Users,DC=corp,DC=example,DC=com"
Carol,Davis,cdavis,[email protected],Finance,Accountant,"OU=Finance,OU=Users,DC=corp,DC=example,DC=com"

Then run the import script:

$DefaultPassword = Read-Host -Prompt "Enter default password for all new accounts" -AsSecureString

Import-Csv -Path "C:Scriptsnew_users.csv" | ForEach-Object {
    $FullName = "$($_.FirstName) $($_.LastName)"

    try {
        New-ADUser `
            -Name $FullName `
            -GivenName $_.FirstName `
            -Surname $_.LastName `
            -SamAccountName $_.SamAccount `
            -UserPrincipalName $_.UPN `
            -Department $_.Department `
            -Title $_.Title `
            -AccountPassword $DefaultPassword `
            -ChangePasswordAtLogon $true `
            -Enabled $true `
            -Path $_.OU `
            -ErrorAction Stop

        Write-Host "Created: $FullName ($($_.SamAccount))" -ForegroundColor Green
    }
    catch {
        Write-Host "FAILED: $FullName — $_" -ForegroundColor Red
    }
}

Step 6: Create and Manage AD Groups

AD groups have two dimensions: scope (Global, DomainLocal, Universal) and category (Security, Distribution). Security groups are used for resource permissions and GPO filtering; distribution groups are for email. The scope determines which objects can be members and where the group can be used to grant access.

# Create a Global Security group (typical for grouping users)
New-ADGroup `
    -Name "GRP-Finance-ReadOnly" `
    -SamAccountName "GRP-Finance-ReadOnly" `
    -GroupCategory Security `
    -GroupScope Global `
    -Description "Read-only access to Finance file share" `
    -Path "OU=Groups,DC=corp,DC=example,DC=com"

# Create a DomainLocal group for resource access (AGDLP model)
New-ADGroup `
    -Name "ACL-FileShare-Finance-R" `
    -SamAccountName "ACL-FileShare-Finance-R" `
    -GroupCategory Security `
    -GroupScope DomainLocal `
    -Description "Resource group: Finance share read access" `
    -Path "OU=Groups,DC=corp,DC=example,DC=com"

# Create a Universal Distribution group (e.g., for email)
New-ADGroup `
    -Name "DL-AllCompanyAnnouncements" `
    -SamAccountName "DL-AllCompanyAnnouncements" `
    -GroupCategory Distribution `
    -GroupScope Universal `
    -Description "Company-wide announcement distribution list" `
    -Path "OU=Groups,DC=corp,DC=example,DC=com"

Step 7: Manage Group Membership

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

# Add multiple users at once
Add-ADGroupMember `
    -Identity "GRP-Finance-ReadOnly" `
    -Members "ajohnson", "cdavis", "bwilliams"

# Add an entire group as a member of another (nested groups)
Add-ADGroupMember `
    -Identity "ACL-FileShare-Finance-R" `
    -Members "GRP-Finance-ReadOnly"

# List all members of a group (recursive to include nested groups)
Get-ADGroupMember -Identity "GRP-Finance-ReadOnly" -Recursive |
    Select-Object Name, SamAccountName, objectClass

# Remove a member from a group
Remove-ADGroupMember -Identity "GRP-Finance-ReadOnly" -Members "bwilliams" -Confirm:$false

Step 8: Manage Organizational Units

Organizational Units (OUs) provide the container structure for users, groups, and computers. They are the targets for Group Policy Object links and serve as the primary delegation boundary for administrative rights.

# Create a top-level OU structure
New-ADOrganizationalUnit `
    -Name "CorpUsers" `
    -Path "DC=corp,DC=example,DC=com" `
    -Description "All corporate user accounts" `
    -ProtectedFromAccidentalDeletion $true

# Create sub-OUs by department
$Departments = "Engineering", "Finance", "HR", "Marketing", "IT"
foreach ($Dept in $Departments) {
    New-ADOrganizationalUnit `
        -Name $Dept `
        -Path "OU=CorpUsers,DC=corp,DC=example,DC=com" `
        -ProtectedFromAccidentalDeletion $true
    Write-Host "Created OU: $Dept"
}

# Move a user to a different OU
Move-ADObject `
    -Identity (Get-ADUser "jsmith").DistinguishedName `
    -TargetPath "OU=Finance,OU=CorpUsers,DC=corp,DC=example,DC=com"

# Remove accidental deletion protection before deleting an OU
Set-ADOrganizationalUnit `
    -Identity "OU=OldDept,OU=CorpUsers,DC=corp,DC=example,DC=com" `
    -ProtectedFromAccidentalDeletion $false
Remove-ADOrganizationalUnit `
    -Identity "OU=OldDept,OU=CorpUsers,DC=corp,DC=example,DC=com" `
    -Confirm:$false

Conclusion

PowerShell gives you complete control over the Active Directory user and group lifecycle on Windows Server 2025. You can now create individual user accounts with the full complement of attributes, modify them over time, query the directory with targeted filters, perform bulk onboarding from CSV files, and structure your directory with properly scoped groups and a clean OU hierarchy. Building on these skills, your next step is to link Group Policy Objects to these OUs to enforce security baselines, software deployment, and desktop configuration — a task covered in the Group Policy tutorial in this series.