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