Using PowerShell to disable and move user and computer accounts

Here are two PowerShell scripts that I wrote and use to disable old Active Directory user or computer accounts.

Typically I use the Microsoft Assessment and Planning Toolkit to have it identify “Days Since Last Activity” for both Active Directory Users and Devices. I then copy the list of Users or Devices I wish to target, save them to a .txt file, and use these scripts to disable the object and move it to an OU for safe keeping.

On thing I like about these scripts is that I export via Export-Csv a .csv file the before and after settings of the Active Directory objects I’m modifying. This gives me the ability to undo my changes if needed.

Disable and Move AD User Accounts from a File

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# This script will disable and move Active Directory User Accounts
# A list of usernames must be provided to the script as a plain text file
# An AD OU must also be created to be the target when your want the user accounts moved to
# Created by Jason Pearce, 2016 February
 
# ####################
# BEGIN Variables
# ####################
 
# Path to a .txt file containing a list of usernames you wish to disable
$FileListOfUsers = "\\server\Scripts\ActiveDirectory\list-of-users-to-disable-from-2015.txt"
 
# Active Directory OU (unique name) that users will move to
$MoveToOU = "LastActiveUsers2015"
 
# Logs Path: The path to write logs
$LogPath = "\\server\Scripts\ActiveDirectory\Logs"
 
# ####################
# END Variables
# ####################
 
# Import Module: Import the Powershell Active Directory module
Import-Module ActiveDirectory
 
# TimeStamp: Create a timestamp for use as part of a directory or file name
$TimeStampBefore = Get-Date -Format s | foreach {$_ -replace ":", "-"}
 
# Log Folder: Create a log folder IF it does not already exist
IF ( -Not (Test-Path -Path $LogPath)) {New-Item -Path $LogPath -ItemType Directory}
 
# Load Users: Load list of users into a variable
$ListOfUsers = Get-Content $FileListOfUsers
 
# Document Before: Document user settings before making changes
$CsvBeforePath = $LogPath+'\DisableUsers-'+$MoveToOU+'-'+$TimeStampBefore+'-before.csv'
$ListOfUsers | Get-ADUser | Export-Csv -Path $CsvBeforePath
 
# Disable Users: Disable these Active Directory user accounts (remove -WhatIf)
$ListOfUsers | Get-ADUser | Disable-ADAccount -WhatIf
 
# Pause: Pause 30 seconds for Active Directory to replicate changes
Start-Sleep -s 30
 
# Move Users: Move these Active Directory user accounts (remove -WhatIf)
$ListOfUsers | Get-ADUser | Move-ADObject -TargetPath (Get-ADOrganizationalUnit -Filter 'Name -eq $MoveToOU') -WhatIf
 
# Pause: Pause 30 seconds for Active Directory to replicate changes
Start-Sleep -s 30
 
# TimeStamp: Create a timestamp for use as part of a directory or file name
$TimeStampAfter = Get-Date -Format s | foreach {$_ -replace ":", "-"}
 
# Document users after making changes
$CsvAfterPath = $LogPath+'\DisableUsers-'+$MoveToOU+'-'+$TimeStampAfter+'-after.csv'
$ListOfUsers | Get-ADUser | Export-Csv -Path $CsvAfterPath

Disable and Move AD Computer Accounts from a File

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# This script will disable and move Active Directory Computer Accounts
# A list of computernames must be provided to the script as a plain text file
# An AD OU must also be created to be the target when your want the computer accounts moved to
# Created by Jason Pearce, 2016 February
 
# ####################
# BEGIN Variables
# ####################
 
# Path to a .txt file containing a list of usernames you wish to disable
$FileListOfComputers = "\\server\Scripts\ActiveDirectory\list-of-computers-to-disable-from-2015.txt"
 
# Active Directory OU (unique name) that users will move to
$MoveToOU = "LastActiveComputers2015"
 
# Logs Path: The path to write logs
$LogPath = "\\server\Scripts\ActiveDirectory\Logs"
 
# ####################
# END Variables
# ####################
 
# Import Module: Import the Powershell Active Directory module
Import-Module ActiveDirectory
 
# TimeStamp: Create a timestamp for use as part of a directory or file name
$TimeStampBefore = Get-Date -Format s | foreach {$_ -replace ":", "-"}
 
# Log Folder: Create a log folder IF it does not already exist
IF ( -Not (Test-Path -Path $LogPath)) {New-Item -Path $LogPath -ItemType Directory}
 
# Load Computers: Load list of computers into a variable
$ListOfComputers = Get-Content $FileListOfComputers
 
# Document Before: Document computers settings before making changes
$CsvBeforePath = $LogPath+'\DisableComputers-'+$MoveToOU+'-'+$TimeStampBefore+'-before.csv'
$ListOfComputers | Get-ADComputer | Export-Csv -Path $CsvBeforePath
 
# Disable Computers: Disable these Active Directory computer accounts (remove -WhatIf)
$ListOfComputers | Get-ADComputer | Disable-ADAccount -WhatIf
 
# Pause: Pause 30 seconds for Active Directory to replicate changes
Start-Sleep -s 30
 
# Move Users: Move these Active Directory computer accounts (remove -WhatIf)
$ListOfComputers | Get-ADComputer | Move-ADObject -TargetPath (Get-ADOrganizationalUnit -Filter 'Name -eq $MoveToOU') -WhatIf
 
# Pause: Pause 30 seconds for Active Directory to replicate changes
Start-Sleep -s 30
 
# TimeStamp: Create a timestamp for use as part of a directory or file name
$TimeStampAfter = Get-Date -Format s | foreach {$_ -replace ":", "-"}
 
# Document computers after making changes
$CsvAfterPath = $LogPath+'\DisableComputers-'+$MoveToOU+'-'+$TimeStampAfter+'-after.csv'
$ListOfComputers | Get-ADComputer | Export-Csv -Path $CsvAfterPath

6 Comments


  1. How would you create the reverse script if needed to reverse the disable and move?


  2. Shane,

    The quickest and easiest option is to change $MoveToOU to be the name of the previous OU, then run the script using the same $FileListOfComputers.

    The other option would be to use the .csv file that you created via the $CsvBeforePath variable. For Users, that file will contain the DistinguishedName of the user account (e.g. DistinguishedName : CN=Last\,First,CN=Users,DC=example,DC=local), which will show you the name and patch of the previous OU.

    You’ll then import that file into a variable (say $Users) and you’ll be able to reference each column heading using dot notation (e.g. $Users.DistinguishedName, $Users.SamAccountName, or $Users.SID). Create a foreach loop to then move them back to the former OU by referencing the DistinguishedName.


  3. Hi,

    This script works well. But I would like to know if you have been able to make the same script remove all the user groups apart from Domain Users. I have been trying to make use of the M$ line “Get-ADPrincipalGroupMembership | % {Remove-ADPrincipalGroupMembership -Identity $ListOfUsers -MemberOf $_ -Confirm:$False}” but not having much luck.

    Any Ideas?

    Thanks


  4. Casey,

    This should provide a table of all AD Group Members for an account except for Domain Users (filtered about by -ne, Not Equal):

    Get-Aduser pearcetest | Get-ADPrincipalGroupMembership | Where-Object {$_.SamAccountName -ne "Domain Users"} | Format-Table -AutoSize

    Remove the Format-Table and instead pipe to Remove-ADPrincipalGroupMembership and you should be good to go. Maybe add -WhatIf at first to test.


  5. I looked at many different scripts and yours was on the money. Thank you for posting! I tweaked your script a little to help me change the description and hide from the GAL. For anyone interested this is what worked for me:

    Variable

    Text to enter into the description field

    $DisabledUserDescription = “Remote Coder disabled for inactivity exceeding 6 months. Disabled 8/10/16 by MOB”

    Edit Account Discription (remove -WhatIf)

    $ListOfUsers | Set-ADUser -Description $DisabledUserDescription -WhatIf

    If use has mailbox, hide from GAL (remove -WhatIf)

    $ListOfUsers | Set-ADUser -Replace @{msExchHideFromAddressLists=”TRUE”} -WhatIf

    Thanks again for posting!

Comments are closed.