Inactive computer objects can bloat your Active Directory over time. In this post, I will explain how to use PowerShell to find inactive computers in Active Directory and move them to a designated Organization Unit (OU) for further processing.

We can determine how old a computer object is, by looking at the PwdLastSet property of the computer account. This property holds the date and time that the password for this account was last changed in active directory. By default, a computer account updates its password in active directory every 30 days. That means, if a computer object’s last password update time is older than 30 days, then we can determine that the computer is inactive or not in use.

This may not be true if you have computers that don’t frequently connect to your corporate network and talk to active directory (ex: laptops), or computers that were shutdown intentionally for long time (lab systems/training lab systems). If any of those computers comes online after long time, they can still update their password. For more information please refer to this blog post.

In my script, I am using the PwdLastSet property to determine how old a computer object is. This script will query all computers in active directory, calculate the age of the computers objects, filter the computers that are older than a given number of days, and then move them to separate specified Organization Unit (OU). This script takes two arguments as described below.

Script inputs

  1. OlderThan: This argument indicates the inactivity period of computers that you want to query. For example, if you want to determine any computer that didn’t contact active directory for 60 days and treat it as inactive computer, then enter a value of 60 to this argument.
  2. TargetOU: This argument takes DN value of an Organization Unit in active directory to which you want to move old computers.

The script has Parameter validation enabled for TargetOU parameter so that it determines if the given OU exists or not before processing any computers.

param(
	[int] $OlderThan = 20,
	[ValidateScript({[ADSI]::Exists("LDAP://$_")})] 
	[string]$TargetOU
)

The ActiveDirectory module is used to query active directory computers and move them to designated OU. This module comes by default when you install Active Directory Services on Windows Serve 2008 R2 or Windows Server 2012. You can also manually install this module on Windows Server 2008 R2 and Windows 7 Computers by installing Remote Server Administration Tools feature. Since this feature is not available on Windows Server 2003, Windows XP computers, you cannot use this script from aforementioned Operating Systems. Please refer to TechNet for more details on how to install Active Directory Modules.

Use cases

The below command will help you to get the list of computers older than 30 days. Since it has a -WhatIf parameter, it doesn’t actually move the computer but will specify the operation that it is intended to perform.

.\Move-OldComputers.ps1 -OlderThan 30 -TargetOU "OU=OldComps,DC=TechiBee,DC=Com" -WhatIf

Get list of computers older than 30 days and move to TargetOU, use below command. It will prompt for your confirmation before moving computers to given OU.

.\Move-OldComputers.ps1 -OlderThan 30 -TargetOU "OU=OldComps,DC=TechiBee,DC=Com"

If you don't want to have confirmation message for each computer move, then first use -Whatif to review the list of computers that will get moved and then use below command to perform actual option without confirmation prompts.

.\Move-OldComputers.ps1 -OlderThan 30 -TargetOU "OU=OldComps,DC=TechiBee,DC=Com" -Confirm:$false

The reason I am moving old computers to an OU is that, you will have an option to review the old computers list in the target OU and perform bulk actions like disable or delete in a single click by selecting them all from Active Directory Users and Computers.

Subscribe to 4sysops newsletter!

PowerShell script

param(
	[int] $OlderThan = 20,
	[ValidateScript({[ADSI]::Exists("LDAP://$_")})] 
	[string]$TargetOU
)

try {
	Import-Module ActiveDirectory -ErrorAction Stop -Verbose:$false
} catch {
	Write-Error "Active Directory module failed to Import. Terminating the script. More details : $_"
	exit(1)
}

try {
	#Get domain name
	$DomainDN = (Get-ADDomain -ErrorAction Stop).DistinguishedName
	#Get Computers in Domain
	$Computers = Get-ADComputer -Filter * -Properties PasswordLastSet -SearchBase $DomainDN -ErrorAction Stop
} catch {
	Write-Error "Failed to query active Directory for computers. Exiting the script. More details : $_"
	exit(1)
}
$now = Get-Date
$agedate = (Get-Date).AddDays(-$OlderThan)

foreach($Computer in $Computers) {
	$ComputerName = $computer.Name
	Write-Verbose "Working on $ComputerName"

	$Computerpwdsetdate = $Computer.PasswordLastSet
	#Ignore if the computer is already in the given TargetOU
	if(([ADSI]"LDAP://$($computer.DistinguishedName)").Parent -eq "LDAP://$TargetOU") {	Continue}

	#$Computerpwdsetdate
	if($Computerpwdsetdate -lt $agedate) {
		if($pscmdlet.ShouldProcess("$ComputerName", "Move computer account to $TargetOU")) {
			try {
				Move-ADObject -Identity $Computer.DistinguishedName -TargetPath $TargetOU -ErrorAction Stop
				Write-Host "Successfully Moved $ComputerName to $TargetOU"
			} catch {
				Write-Warning "Failed to move $computername to $targetOU . More details : $_"
				Continue
			}

		}
	}

}

Note: I would request everyone to try this PowerShell script in your test environment before using in production.

4 Comments
  1. Tommy 6 years ago

    Saved the script as written here. Then ran as such – .\Move-StaleComputers.ps1 -OlderThan 180 -TargetOU “OU=StaleComputers,DC=utm,DC=edu” -WhatIf

    It resulted in this error over and over:

    You cannot call a method on a null-valued expression.
    At scriptpath.ps1:36 char:12
    + if($pscmdlet.ShouldProcess(“$ComputerName”, “Move computer ac …

    Any idea why?

  2. Tommy 6 years ago

    Nevermind: you have to include the [CmdletBinding(SupportsShouldProcess=$true)] attribute at the beginning.

  3. Hi 4 years ago

    if I only want to move old desktop os,what I need do? Thanks

  4. Lewallen 2 years ago

    Sorry, but this script is incomplete. Fix and reupload.

Leave a reply

Your email address will not be published.

*

© 4sysops 2006 - 2023

CONTACT US

Please ask IT administration questions in the forums. Any other messages are welcome.

Sending

Log in with your credentials

or    

Forgot your details?

Create Account