ashumskiy - Fotolia
Set up users with key PowerShell Active Directory commands
User management in Active Directory doesn't have to fill you with click-induced anxiety. Try these PowerShell tips for a more efficient way to get this work done.
Administrators must perform tasks quickly and efficiently, especially bulk edits. PowerShell is tailor-made for these types of tasks, especially when working with Active Directory.
User administration tends to take up a lion's share of the work handled in the directory service, especially in larger organizations. Trying to stay on top of churning user data takes significant effort if you try to handle it in a GUI tool, but learning to use a few PowerShell Active Directory commands can make this chore less of a pain.
Set up the tools for Active Directory user management
Before you can administer your Active Directory users, you need the right tools. Don't ever work directly on the domain controller. Get the Remote Server Administration Tools (RSAT), including the Active Directory tools, from Microsoft. Find the version that matches your installations. If you use Windows 10 October 2018 update and later, you can install RSAT as an optional feature with the following:
Add-WindowsCapability -Name Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0 -Online
RSAT includes the GUI tools, Active Directory Users and Computers, and the PowerShell module.
If you're running the Windows 10 October 2018 update, Windows Server 1809 or Windows Server 2019, and later and install the Active Directory RSAT as an optional feature, the Active Directory PowerShell module will work in PowerShell Core v6.1.1.
Earlier versions of the OS require Windows PowerShell or PowerShell Core to use the WindowsCompatibility module from the PowerShell Gallery to access the Windows PowerShell 5.1 functionality via implicit remoting. The WindowsCompatibility module requires PowerShell Core 6.1 or later.
How to create user accounts with PowerShell
With the necessary utilities in place, you can manage your Active Directory user accounts through the standard lifecycle: creation, modification and destruction.
In this example, we'll add a user named Bob Smith. There is a minimum amount of information required to create an AD account:
New-ADUser -Name "SMITH Bob" -SamAccountName bobsmith -AccountPassword $secpass `
-Enabled:$true -Path 'OU=UserGroups,DC=Manticore,DC=org' -PassThru
A new user account has several requirements. The password must be a secure string to enable the account. The name must be unique in the organizational unit (OU), and the SamAccountName (login ID) must be unique within the Active Directory forest. If you don't supply an OU (designated by the -Path parameter), the account goes into the default Users container. The final parameter -PassThru shows the account information.
For one account, entering this information involves a lot of typing. The workload increases once you need to make multiple accounts. An easier way to add numerous users is to import the information from a CSV file:
$secpass = Read-Host -Prompt "Password" -AsSecureString
Import-Csv -Path c:\scripts\newusers.csv |
foreach {
New-ADUser -Name $_.Name -SamAccountName $_.samaccountname `
-AccountPassword $secpass -Enabled:$true `
-Path 'OU=UserGroups,DC=Manticore,DC=org'
}
In the script, I've mistakenly created the accounts in 'OU=UserGroups,DC=Manticore,DC=org' when they should have gone into 'OU=UserAccounts,DC=Manticore,DC=org'. To fix this, use the Move-ADObject cmdlet to move the accounts between the OUs.
Get-ADUser -Filter * -SearchBase 'OU=UserGroups,DC=Manticore,DC=org' |
Move-ADObject -TargetPath 'OU=UserAccounts,DC=Manticore,DC=org'
When using Get-ADUser to retrieve accounts in bulk, you always need to supply a filter. This is an annoying design decision, but because it's a mandatory parameter, you will get a prompt that asks for it rather than the command failing. The rationale for this might be to prevent a hang-up when running searches against huge Active Directory databases.
I created user Bob Smith with minimal information with the Get-ADUser cmdlet:
Get-ADUser -Identity bobsmith
The -Identity parameter retrieves the specified user account. The account identifier can be the SamAccountName, distinguished name, global unique identifier or the security identifier (objectSID).
By default, you only get the essential properties displayed with Get-ADUser. If you want to view all properties use:
Get-ADUser -Identity bobsmith -Properties *
Or you can select a set of properties, which also retrieves the default properties:
Get-ADUser -Identity bobsmith -Properties CanonicalName, Created, LockedOut, PasswordExpired, ProtectedFromAccidentalDeletion
When using PowerShell Core 6.1.1 with the Active Directory module, the combination of the -Properties parameter with the ProtectedFromAccidentalDeletion attribute produces an error. Switching to Windows PowerShell 5.1 and the Active Directory cmdlets through the WindowsCompatibility module avoids the problem, which is under investigation by the PowerShell team.
You can manage most of the user's Active Directory attributes through the Set-ADUser cmdlet parameters. This command shows you what's available:
Get-Command Set-ADUser -Syntax
To prevent mistakes, I prefer to get the user object as a test and then repeat and pipe into Set-ADUser:
Get-ADUser -Identity bobsmith | Set-ADUser -UserPrincipalName '[email protected]'
You can set multiple attributes simultaneously:
Get-ADUser -Identity bobsmith | Set-ADUser -GivenName 'Bob' -Surname 'Smith' -PassThru
The -Passthru parameter helps to check on the changes.
There are a few places in Active Directory where you can set other values aside from the primary value, such as the other phone options.
Set-ADUser doesn't have direct parameters for dealing with these attributes, but you can use the Set-ADUser generic parameters:
- Add: Adds one or more values;
- Clear: Removes all values;
- Remove: Removes one value; and
- Replace: Replaces current values with new values.
If you use more than one of these parameters at a time, the order of precedence is Remove, Add, Replace and Clear.
Supply the required data as a hash table:
Get-ADUser -Identity bobsmith | Set-ADUser -Add @{otherHomePhone = '01234 567890', '01234 987654'}
Borrow user information to streamline efforts
Some Active Directory administrators copy information from one user account to another to avoid extra typing and manual errors. To do this, create an object with the required property data from a known user account:
$source = Get-ADUser -Identity bobsmith -Properties OfficePhone, otherHomePhone
Then, use Set-ADUser to set the values on the target account:
Set-ADUser -Identity EmilySmith -Replace @{telephoneNumber = $($source.OfficePhone); otherHomePhone = $($source.otherHomePhone)}
I've used the -Identity parameter to illustrate its use. The generic parameters -- Add, Clear, Remove and Replace -- use the Lightweight Directory Access Protocol (LDAP) name for the Active Directory attribute, not the friendlier version used by the Active Directory cmdlets. For this example, I employ the OfficePhone property, which maps to the telephoneNumber LDAP attribute:
Get-ADUser -Identity emilysmith -Properties * | select *phone*
HomePhone :
MobilePhone :
OfficePhone : 07787 293847
otherHomePhone : {01234 567890, 01234 987654}
telephoneNumber : 07787 293847
OfficePhone is identical to telephoneNumber in value. You manage the mapping with the Active Directory cmdlets. Be sure to work with the true LDAP attribute name in these cases.
Trust, but verify before deleting a user
The last act in the user object lifecycle is destruction:
Remove-ADUser -Identity emilysmith -whatif
What if: Performing the operation "Remove" on target "CN=SMITH Emily,OU=UserAccounts,DC=Manticore,DC=org".
Always test with -WhatIf to ensure you will remove the correct account. Deleting your manager's account by accident doesn't tend to go down very well.
Save time with searches using key parameters
A few handy parameters enable you to perform some of the more difficult searches quickly and easily.
- To find locked out users: Search-ADAccount -LockedOut
- To find users with expired passwords: Search-ADAccount -PasswordExpired
- To find expired accounts: Search-ADAccount -AccountExpired
Search-ADAccount can also check for accounts that are due to expire, disabled, inactive or have passwords that never expire.
Weed out the stragglers
One Active Directory administrative task worth doing is eliminating accounts for users who have left the organization. You can test for users that haven't logged on for a period of time:
$testdate = (Get-Date).AddDays(-90)
Get-ADUser -Filter * -Properties LastLogonDate | where {$_.LastLogonDate -And $_.LastLogonDate -le $testdate}
This code looks for users who haven't logged on for 90 days. Once found, you can move these users to an archive OU and delete them after an additional 90 days or whatever period your organization mandates.