Skip to main content

Using PowerShell to Manage AD DS Recycle Bin

We learned last Tuesday how to turn on the AD DS Recycle Bin using PowerShell. To help manage the recovery process and cut down on you typing, try the script below. It will help you find the objects you are looking to recover. It is provided as is. For easier reading, copy and paste it into Notepad.

# ===========================================================

# Script Name: ADRecycleBin.PS1

# Author: Jason A. Yoder, MCT

# Website: www.MCTExpert.com

# Blog: www.MCTExpert.Blogspot.com

# ===========================================================

# ===========================================================

# Script Purpose:

# This script is designed to make it easier to recover

# objects from the Active Directory Recycle Bin on a

# Windows Server 2008 R2 Domain Controller.

#

# ===========================================================

# ===========================================================

# Script Requirments

# 1. This script must be run on a Windows Server 2008 R2

# Domain Controller

# 2. Active Directory Recycle Bin must be enabled prior

# to deleting objects. All Objects deleted prior

# to enabling Active Directory Recycle Bin will not

# be recoverable.

# 3. Parent containers of any deleted objects must

# first be restored

# ===========================================================

# ===========================================================

# Known Issues:

# Issue 1:

# When selectiong from the list of names to restore, if

# you select the last name of the list, it will not restore.

#

# Workaround 1:

# Create a user object and delete it. Run the script

# again. The object you want to restore will no longer be

# last on the list and will restore.

# ===========================================================

# ===========================================================

# Revision History:

#

# ===========================================================

# ===========================================================

# Global Varibles

#

# $ScriptMode - Script mode will have two options.

# 1. Search for objects by date.

# 2. Search for objects by name.

$ScriptMode = 0

# $DaysBack - The number of days the script should look

# back for deleted objects.

$DaysBack = 0

# $LookUpName - All or part of the object name that the

# script should filter for.

$LookUpName = ""

# $NameArray - Array that holds the names of all the

# returned deleted objects from the recycle bin query.

$NameArray += @(0)

# $RecoveryName - The Name of the object to recover.

$RecoveryName = ""

# == End of Global Variables ================================

# ===========================================================

# Functions

#

# DisplayTitle - Display the welcome screen

Function Display_Title()

{

$Text = "`

===========================================`

== ADRecycleBin.PS1 ==`

== ==`

== Author: Jason A. Yoder, MCT ==`

== ==`

== Disclaimer: ==`

== This script is provided as is with no ==`

== guarantee or support. Test throughly ==`

== before deploying in you environment. ==

==========================================="

Write-Host $Text

} # End of functionL DisplayTitle

# -----------------------------------------------------------

# GetScriptMode - Asks the user Which operation mode the

# script should run in.

Function GetScriptMode()

{

$Text = "`

ADRecycleBin.ps1 allows you to search the AD Recycle bin`

but looking back X number of days or by specifing the`

object name. Please choose how you want to search`

the recycle bin.`

`

1 - By Day.`

2 - By Name.`

"

#Save user's choice in $ScriptMode.

$Script:ScriptMode = Read-Host $Text

} # End of Function: GetScriptMode

# -----------------------------------------------------------

# SearchDays - Asks the user for how many days to look back

# for deleted objects.

Function SearchDays()

{

$Text = "`

Enter in the number of days to look back for deleted`

deleted objects in the AD Recycle Bin."

#Save user's choice in $DaysBack

$Script:DaysBack = Read-Host $Text

} # End of Function: SearchDays

# -----------------------------------------------------------

# SearchName - Asks the user for part of the objects

# name they are looking for.

Function SearchName()

{

$Text = "`

Enter in the number all or part of the objects`

name that you are looking for."

#Save user's choice in $LookUpName

$Script:LookUpName = Read-Host $Text

} # End of Function: SearchName

# -----------------------------------------------------------

# GetDaysObjects - Queires AD for a list of all deleted

# AD Objects over the past $DaysBack and puts the names

# into an array.

Function GetDaysObjects

{

# Get the current date and save it in $CurrentData.

# This is used as the starting point to determin how many

# days to go back.

$CurrentDate = get-date

# Take the number of days selected by the user and

# negate it for DateTime Arythmitic.

$Days = [int]$DaysBack * (-1)

# Find the date minus the users specified number of

# days using the AddDays method.

$NewDate = $CurrentDate.AddDays($Days)

# Create a new date time object that has its date as

# the day specified by the user. Also have the time set

# at 12:01 AM.

$ChangeDate = New-Object DateTime([String]$NewDate.Year,[String]$NewDate.Month,`

[String]$NewDate.Day,0,0,1)

# Extract all objects in the AD Recycle Bin that is deleted

# and is within the users specified range of time.

#Placed the objects in the array $Data.

$Data = Get-ADObject -Filter 'WhenChanged -gt $ChangeDate -and isDeleted -eq $true' -includeDeletedObjects

#Determine the number of records in the array.

$Index = $Data.count

# Because of extra data returned in the 'Name' property

# of the objects, below we will cycle through

# the array and use Regular Expressions to

# extract the first name in the 'Name' property.

For ($X=0; $X -le $Index-1; $X++)

{

$Data[$X].Name -match "\w*"

$Script:NameArray += $Matches.Values

}

CLS

} # End of FunctionL GetDaysObject

# -----------------------------------------------------------

# GetNameObject - Queires AD for a list of all deleted

# AD Objects With a name like $LookUpName and puts the names

# into an array.

Function GetNameObject

{

# Set the script variable $LookUpName to a the local

# variable $Name. This is because the command line

# below does not recognize variable scopes other

# then local.

$Name = $Script:LookUpName

$Data = Get-ADObject -Filter {displayname -like $Name -and isDeleted -eq $true} -includeDeletedObjects

# Because of extra data returned in the 'Name' property

# of the objects, below we will use Regular Expressions

# to extract the first name in the 'Name' property.

$Data.Name -match "\w*"

$Script:NameArray += $Matches.Values

} # End of Function: GetNameObject

# -----------------------------------------------------------

# GetRecoveryOption - Will display and numeric list of the

# names of the objects from the query and ask the user to

# select which one to recover.

Function GetRecoveryOption

{

Write-Host " Please select the number of the object`

that you would like to recover."

Write-Host "Index`t Name"

Write-Host "-----`t ---------------"

# Write out the array of possible objects to

# restore and put and index number in front

# of them.

$Index = $Script:NameArray.Count

For ($X=1; $X -le $Index-1; $X++)

{

Write-Host $X`t $Script:NameArray[[int]$X]

}

# Allow the user to select a number and store it

# in $Option.

$Option = Read-host {"Please Select a number."}

# Set the Script variable with the name of

# the users choice.

$Script:RecoveryName = $Script:NameArray[$Option]

} # End of Function: GetRecoveryOption

# -----------------------------------------------------------

# RecoverObject - Executes the recovery command for the

# object.

Function RecoverObject

{

# Set the script variable $RecoveryName to a the local

# variable $Name. This is because the command line

# below does not recognize variable scopes other

# then local.

$Name = $Script:RecoveryName

Write-Host "Recovering object $Name"

#The command below executes the restore process.

get-adobject -filter {DisplayName -like $Name} -IncludeDeletedObjects | Restore-ADObject

} # End of Function: RecoverObject

# == End of Functions =======================================

# ===========================================================

# Main Code:

cls

Display_Title

GetScriptMode

# From here the script will collect data depending on the

# $ScriptMode variabe

Switch ($ScriptMode)

{

1 {

SearchDays

GetDaysObjects

}

2 {

SearchName

GetNameObject

}

Default {"Error, invaild option"}

}

GetRecoveryOption

RecoverObject

#

# == End of Main Code =======================================

Comments

Popular posts from this blog

Adding a Comment to a GPO with PowerShell

As I'm writing this article, I'm also writing a customization for a PowerShell course I'm teaching next week in Phoenix.  This customization deals with Group Policy and PowerShell.  For those of you who attend my classes may already know this, but I sit their and try to ask the questions to myself that others may ask as I present the material.  I finished up my customization a few hours ago and then I realized that I did not add in how to put a comment on a GPO.  This is a feature that many Group Policy Administrators may not be aware of. This past summer I attended a presentation at TechEd on Group Policy.  One organization in the crowd had over 5,000 Group Policies.  In an environment like that, the comment section can be priceless.  I always like to write in the comment section why I created the policy so I know its purpose next week after I've completed 50 other tasks and can't remember what I did 5 minutes ago. In the Group Policy module for PowerShell V3, th

Return duplicate values from a collection with PowerShell

If you have a collection of objects and you want to remove any duplicate items, it is fairly simple. # Create a collection with duplicate values $Set1 = 1 , 1 , 2 , 2 , 3 , 4 , 5 , 6 , 7 , 1 , 2   # Remove the duplicate values. $Set1 | Select-Object -Unique 1 2 3 4 5 6 7 What if you want only the duplicate values and nothing else? # Create a collection with duplicate values $Set1 = 1 , 1 , 2 , 2 , 3 , 4 , 5 , 6 , 7 , 1 , 2   #Create a second collection with duplicate values removed. $Set2 = $Set1 | Select-Object -Unique   # Return only the duplicate values. ( Compare-Object -ReferenceObject $Set2 -DifferenceObject $Set1 ) . InputObject | Select-Object – Unique 1 2 This works with objects as well as numbers.  The first command creates a collection with 2 duplicates of both 1 and 2.   The second command creates another collection with the duplicates filtered out.  The Compare-Object cmdlet will first find items that are diffe

How to list all the AD LDS instances on a server

AD LDS allows you to provide directory services to applications that are free of the confines of Active Directory.  To list all the AD LDS instances on a server, follow this procedure: Log into the server in question Open a command prompt. Type dsdbutil and press Enter Type List Instances and press Enter . You will receive a list of the instance name, both the LDAP and SSL port numbers, the location of the database, and its status.