Most Useful PowerShell Cmdlets for Managing and Securing Active Directory

powershell hero img scaled

In this article, I show you how to manage and secure Active Directory using PowerShell. I’ll look at the most useful PowerShell cmdlets and give examples of how to use them.

🎬 Watch This Week in IT.


Create New Active Directory Users

The New-ADUser cmdlet is for creating new AD users. You can optionally specify where to create new users with the -Path parameter. In the example below, the new user will be created in the Accounts Organizational Unit (OU). The -Server parameter is also optional. It is used to determine on which domain controller (DC) the new user will be created. Note that you cannot specify a password in plaintext in the -AccountPassword parameter. You must convert it to a secure string using the ConvertTo-SecureString cmdlet.

New-ADUser -DisplayName:"Russell Smith" -GivenName:"Russell" -Name:"Russell Smith" -Path:"OU=Accounts,DC=ad,DC=contoso,DC=com" -SamAccountName:"russellsmith" -Server:"dc1.ad.contoso.com" -Surname:"Smith" -Type:"user" -AccountPassword (ConvertTo-SecureString Pas$W0rd!!11 -AsPlainText -Force) -Enabled $true

Create Active Directory Groups

Adding groups to AD is easy with the New-ADGroup cmdlet. -Server and -Path parameters are both optional.

New-ADGroup -GroupCategory:"Security" -GroupScope:"Global" -Name:"Netwrix" -Path:"OU=Accounts,DC=ad,DC=contoso,DC=com" -SamAccountName:"Netwrix" -Server:"dc1.ad.contoso.com"

Add Users to Groups

Once you have some users and groups in your domain, you can add users to groups with the Add-ADGroupMember cmdlet.

Add-ADGroupMember -Identity Netwrix -Members russellsmith,bob.trent

Create New Organizational Units

Use the New-ADOrganizationalUnit cmdlet to create new Organizational Units (OU) in AD. Note that the -ProtectedFromAccidentalDeletion flag is optional. When set to $true, you can’t delete the OU without first changing the status of the flag to $false.

New-ADOrganizationalUnit -Name:"Sensitive" -Path:"OU=Accounts,DC=ad,DC=contoso,DC=com" -ProtectedFromAccidentalDeletion:$true -Server:"dc1.ad.contoso.com"

Deleting Active Directory Objects

The ‘Remove’ verb is used in AD cmdlets to delete objects. Remove-ADUser and Remove-ADGroup are used respectively to delete users and groups.

Remove-ADUser -Identity russellsmith
Remove-ADGroup -Identity Netwrix

Before you can delete an OU, you need to set the accidental deletion flag to false using Set-ADObject.

Set-ADObject -Identity:"OU=Sensitive,OU=Accounts,DC=ad,DC=contoso,DC=com" -ProtectedFromAccidentalDeletion:$false -Server:"dc1.ad.contoso.com"

Remove-ADOrganizationalUnit -Identity "OU=Sensitive,OU=Accounts,DC=ad,DC=contoso,DC=com"

Import Users from a CSV File

PowerShell makes it easy to automate tasks. In the script below, I use a comma-delimited (CSV) text file to create two users with the Import-Csv and New-ADUser cmdlets. The only trickery involved is splitting the first field of each entry in the text file so that I can separate the first and surnames for the -GiveName and -Surname parameters of the New-ADUser cmdlet.

Import-Csv -Path c:tempusers.csv | ForEach-Object {

    $givenName = $_.name.split()[0]

    $surname = $_.name.split()[1]

    New-ADUser -Name $_.name -Enabled $true –GivenName $givenName –Surname $surname -Accountpassword (ConvertTo-SecureString $_.password -AsPlainText -Force) -ChangePasswordAtLogon $true -SamAccountName $_.samaccountname –UserPrincipalName ($_.samaccountname+”@ad.contoso.com”) -City $_.city -Department $_.department

}

The first line of the text file contains the field names. You can add as many users as you want.

Name,samAccountName,Password,City,Department
Russell Smith,smithrussell,PassW0rd!!11,London,IT
David Jones,jonesdavid,4SHH$$#AAAHh,New York,Accounts

Move AD Objects

The Move-ADObject cmdlet is for moving AD objects. In the example below, I move a user account from the Accounts OU to the Users container.

Move-ADObject -Identity "CN=Russell Smith,OU=Accounts,DC=ad,DC=contoso,DC=com" -TargetPath "CN=Users,DC=ad,DC=contoso,DC=com"

Link a Group Policy Object

While PowerShell can’t be used to create Group Policy Objects (GPO), it can be used to perform other tasks related to Group Policy. The New-GPLink cmdlet is used to link existing GPOs to OUs. In the example below, I link a GPO called Firewall Settings to the Accounts OU.

New-GPLink -Name "Firewall Settings" -Target "OU=Accounts,DC=ad,DC=contoso,DC=com" -LinkEnabled Yes -Enforced Yes

Active Directory Reporting

The Get-ADObject cmdlet can be used in Active Directory reporting to filter the directory and display information about objects. In the example below, I use a filter to find the Accounts OU and then pipe the results to the Get-GPInheritence cmdlet. Select-Object is then used to extract information about the GPOs linked to the OU.

Get-ADObject -Filter {name -like "Accounts*"} | Get-GPInheritance | Select-Object -Expand gpolinks | ForEach-Object {Get-GPO -Guid $_.gpoid}

One of the most useful cmdlets for AD admins is the Search-ADAccount cmdlet. In the example below, I search the domain for locked out user accounts and automatically unlock them using Unlock-ADAccount.

Search-ADAccount –LockedOut | Unlock-ADAccount

Get-ADObject can be used with complex filters. Here I list all objects created after the specified date ($Date).

$Date = [Datetime]"02/07/2019"
Get-ADObject -Filter 'WhenCreated -GT $Date'

Filters can get quite complex. In the next command, I list all deleted objects where the change attribute is later than the specified date, and that can be restored, excluding the Deleted Objects container.

Get-ADObject -Filter 'whenChanged -gt $Date -and isDeleted -eq $True -and name -ne "Deleted Objects"' -IncludeDeletedObjects

Finally, I use Get-EventLog to search the event logs on each DC for login event ID 4624. Note the use of Get-ADDomainController to return all the DCs in the domain. Once I’ve retrieved the necessary information, I use Write-Host to write the output to the terminal window, with information separated by tabs to make it easier to read.

$DCs = Get-ADDomainController -Filter *
 
$startDate = (get-date).AddDays(-1)
 
foreach ($DC in $DCs){
$slogonevents = Get-Eventlog -LogName Security -ComputerName $DC.Hostname -after $startDate | Where-Object {$_.eventID -eq 4624 }}
 
 foreach ($e in $slogonevents){

 if (($e.EventID -eq 4624 ) -and ($e.ReplacementStrings[8] -eq 2)){
 write-host "Type: Local Logon`tDate: "$e.TimeGenerated "`tStatus: Success`tUser: "$e.ReplacementStrings[5] "`tWorkstation: "$e.ReplacementStrings[11]
 }

 if (($e.EventID -eq 4624 ) -and ($e.ReplacementStrings[8] -eq 10)){
 write-host "Type: Remote Logon`tDate: "$e.TimeGenerated "`tStatus: Success`tUser: "$e.ReplacementStrings[5] "`tWorkstation: "$e.ReplacementStrings[11] "`tIP Address: "$e.ReplacementStrings[18]
 }}

Related Article:

  • How to Install Active Directory PowerShell Module