I NEED A SCRIPT IN POWERSHELL TO MOVE INACTIVE COMPUTERS TO ANOTHER OU

I'm trying to complete an AD cleanup. I have already the list of all inactive computers and users that should be moved to another OU, let's call it "DISABLED COMPUTERS" and "DISABLED USERS". This can't be done using GPO and I have no previous experience in scripting, so I will greatly appreciate if anyone of you can provide me a script or the steps to create one that can achieve that purpose. In summary this is what I need:

1. Check for the destination OU if not present create it.
2. Check for the users who meet the criteria if found move to that OU.
3. Check users in the destination OU and if more than x days then delete.
Hunter24Office 365 Support EngineerAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

RantCanSr. Systems AdministratorCommented:
I know you asked for powershell, but I have had good luck with Solarwinds Free Stale AD Users/Computers tool.

http://www.solarwinds.com/products/freetools/ad_admin_tools.aspx

This does what you request of the PSS.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
becraigCommented:
I have one question here, what is the qualifier you plan to use for inactive accounts ?

We can either check for where accounts have the disabled flag or for accounts (user and computer) which either have not "logged on for x days".

Once you let me know which route you plan to take, I can proceed to complete the script today for testing.
0
Hunter24Office 365 Support EngineerAuthor Commented:
becraig:

I'll be using the "not logged on for X days" qualifier. I have more than 80 machines that are inactive but not being flagged at all.  All inactive users are now disabled but I'll need to move them to an OU and after a year of these accounts become inactive proceed to delete them.  Just let me know what else is needed. Thank you.
0
Creating Active Directory Users from a Text File

If your organization has a need to mass-create AD user accounts, watch this video to see how its done without the need for scripting or other unnecessary complexities.

becraigCommented:
#Import AD Module
Import-Module ActiveDirectory

#define the time window --- we specify 90 days plus the official windows lag of 14 days
$time = (Get-Date).Adddays(-104)

#Check for existence of OU and create if not present
[string] $Path = 'OU=OUName,DC=domain,DC=com'
try
{
	if (!([adsi]::Exists("LDAP://$Path")))
	{
		#Create OU since it does not yet exist
		NEW-ADOrganizationalUnit “StaleComputers” –path “OU=SomeOU, DC=domain, DC=com”
	}
	else { Write-Debug "OU Already Exists:  $Path" }
}
catch [Exception]    {
	return $_.Exception.Message
}


#now we proceed to check for computers
Get-ADComputer -Filter { LastLogonTimeStamp -lt $time } | Move-ADObject -TargetPath $Path -WhatIf

#Now we check for inactive computers that are inactive
Search-ADAccount -accountinactive -ComputersOnly | ? { $_.lastlogondate -lt $time } | Move-ADObject -TargetPath $Path -WhatIf

Open in new window



I need to take a look at creating a time-stamp in one of the extended fields for the AD object so we can determine when to delete as you indicate above, I probably think also adding a piece to remove group memberships as well would be a good plugin.

I will look at it when I get home this evening.
0
Hunter24Office 365 Support EngineerAuthor Commented:
becraig:

Ok. thank you so much.  As soon as you have completed it I'll check it.
0
Hunter24Office 365 Support EngineerAuthor Commented:
RantCan:

Thank you for your posting.  I downloaded and tested this Solarwinds tool. The interface is very simple and the query was completed very quickly; it showed me exactly the same results that I got using AD Tidy. However, the only option available is just to remove the inactive computers, I rather prefer to have these objects disabled in another OU and after a certain amount of time delete them. Is there any other free tool that does that and that you recommend?
0
Hunter24Office 365 Support EngineerAuthor Commented:
Hi becraig:

Do you have the final script so I can test it?
0
becraigCommented:
I will have it in a bit, sorry was out for the weekend.
0
RantCanSr. Systems AdministratorCommented:
I did some work with AD Tidy; it does indeed have the ability to add a task sequence to move a found entity to a specified OU, which the Solarwinds tool does not.
1
Hunter24Office 365 Support EngineerAuthor Commented:
RantCan:

I see what you mean, I need to customize the actions to be executed.  That for sure will help me a lot, specially for inactive computers; all inactive user accounts are disabled and they are not as much as computers accounts. However, I still need to find the way to exclude some service accounts that were included in the report. I'll also need to test this in a virtual environment before doing the real thing in a prod environment. Thanks a lot, any other comment or idea is always welcome!
0
becraigCommented:
Ok so before I complete this I think one of the other solutions might be less heavy lifting.

The first thing you would have to do is to create a custom attribute in AD so we could place the timestamp there when we disable a user or computer account.
That would involve schema modification, but would make it easier to do your periodic check for deletion.

Here is some info, let me know if you still want to try that route.
https://www.youtube.com/watch?v=EBkQlTUsXww

We would create the custom field disableddate in the AD then once updated we can edit the script to set that value once the user account or computer account is disabled then simply delete after X days.
0
becraigCommented:
On second thought I just realized I could probably update one of the other already present fields and then simply query that value.

I will make a quick test today.
0
becraigCommented:
So here is a quick look at something that should work (I am updating the upn of the user and computer account with the date for deletion later):


#Import AD Module
Import-Module ActiveDirectory
#Define Arrays
$Computers = @()
$users = @()
$ddate = "Disabled@" + (Get-Date -format yyyyMMdd)

#define the time window --- we specify 90 days plus the official windows lag of 14 days
$time = (Get-Date).Adddays(-104)

#Check for existence of OU and create if not present
[string] $Path = 'OU=OUName,DC=domain,DC=com'
try
{
	if (!([adsi]::Exists("LDAP://$Path")))
	{
		#Create OU since it does not yet exist
		NEW-ADOrganizationalUnit “StaleComputers” –path “OU=SomeOU, DC=domain, DC=com”
	}
	else { Write-Debug "OU Already Exists:  $Path" }
}
catch [Exception]    {
	return $_.Exception.Message
}


#now we proceed to check for computers
$computers += Get-ADComputer -Filter { LastLogonTimeStamp -lt $time } | select distinguishedname, samaccountname, userprincipalname
$users += Get-ADUser -Filter { LastLogonTimeStamp -lt $time } | select distinguishedname, samaccountname, userprincipalname

#Now we check for inactive computers that are inactive
$computers += Search-ADAccount -accountinactive -ComputersOnly | ? { $_.lastlogondate -lt $time } | select distinguishedname, samaccountname, userprincipalname
$users += Search-ADAccount -accountinactive -UsersOnly | ? { $_.lastlogondate -lt $time } | select distinguishedname, samaccountname, userprincipalname


$computers | % 
{
#Move the object in AD
Move-ADObject -Identity $_.distinguishedname -TargetPath $path -WhatIf
#Change the upn to the disabled date
Set-ADComputer -Identity $_.distinguishedname -userprincipalname $ddate -WhatIf
#Disable the account
Disable-ADAccount -Identity $_.distinguishedname -WhatIf
}

$users | %  {
#Move the object in AD
Move-ADObject -Identity $_.distinguishedname -TargetPath $path -WhatIf
#Change the upn to the disabled date
Set-ADUser -Identity $_.distinguishedname -userprincipalname $ddate -WhatIf
#Disable the account
Disable-ADAccount -Identity $_.distinguishedname -WhatIf
}

#now we check for computers in the AD in our OU that meet the date criteria
Get-ADComputer –Filter “Name –like ‘*’”–SearchBase $Path | %  {
$timer = ($_.userprincipalname).split("@")[1]
if ($timer -gt (Get-date).AddDays(-100)) {Remove-ADObject -Identity $_.distinguishedname }
}

Open in new window

0
Hunter24Office 365 Support EngineerAuthor Commented:
becraig:

Thanks for your support on this, I'll like to test this script when it is completed. I'm using the AD Tidy app for the cleanup because I need to complete this task next week, after the month closing. However, once this is done I prefer to test this script and put in the the prod environment so that the task is automated. I'll be waiting your feedback.
0
becraigCommented:
I will let you know once I complete a quick test of it, from first run it works as expected but I need to ensure there are no glitches.

I will probably have some time on the plane tonight so I might go ahead and clean it up and post an update.
0
Hunter24Office 365 Support EngineerAuthor Commented:
Thank you all again!
0
Hunter24Office 365 Support EngineerAuthor Commented:
Thank you all, becraig did a great job with the script but I prefered to use a simpler solution as the one recommended by  RantCan
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Active Directory

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.