In an environment where Roaming Profiles are used and/or where User Profile folders (like My Documents, Desktop, Application Data, etc.) are redirected to a network share the Recycle Bin for those locations also resides on the network. Meaning that if users delete a lot in these locations and never empty their Recycle Bin valueable network storage is wasted.
I didn't want to disable the Recycle Bin feature in it's whole but rather delete stuff that has been deleted longer than x days ago.
In order to do so you will have to communicate with the Recycle Bin application by creating an instance to the Shell.application object and connect to the Recycle Bin Special Folder by using the NameSpace method.
$Shell = New-Object -ComObject Shell.Application
$Global:Recycler = $Shell.NameSpace(0xa)
You can then retrieve the content of this special folder by using the Items method.
$Recycler.Items()
I wrote a little function to Get the Recycle Bin's content older than x days (7 by default) and, if the DeleteItems parameter is provided, deletes this content. (I can't get the formatting right in both Iexplore and Chrome... Internet Explorer displays colors but alligns left and Chrome doesn't display colors on editing this page in Blogger :-/ )
function Get-recyclebin
{
[CmdletBinding()]
Param($RetentionTime = "7",
[Switch]$DeleteItems
)
$User = $env:USERNAME
$Computer = $env:COMPUTERNAME
$DateRun = Get-Date
foreach($item in $Recycler.Items())
{
$DeletedDate = $Recycler.GetDetailsOf($item,2) -replace "\u200f|\u200e","" #Invisible Unicode Characters
$DeletedDate_datetime = get-date $DeletedDate
[Int]$DeletedDays = (New-TimeSpan -Start $DeletedDate_datetime -End $(Get-Date)).Days
If($DeletedDays -ge $RetentionTime)
{
$Size = $Recycler.GetDetailsOf($item,3)
$SizeArray = $Size -split " "
$Decimal = $SizeArray[0] -replace ",","."
If ($SizeArray[1] -contains "bytes") { $Size = [int]$Decimal /1024 }
If ($SizeArray[1] -contains "KB") { $Size = [int]$Decimal }
If ($SizeArray[1] -contains "MB") { $Size = [int]$Decimal * 1024 }
If ($SizeArray[1] -contains "GB") { $Size = [int]$Decimal *1024 *1024 }
$Object = New-Object Psobject -Property @{
Computer= $computer
User = $User
DateRun = $DateRun
Name = $item.Name
Type = $item.Type
SizeKb = $size
Path = $item.path
"Deleted Date" = $DeletedDate_datetime
"Deleted Days" = $DeletedDays }
$Object
If ($DeleteItems)
{
Remove-Item -Path $item.Path -Confirm:$false -Force -Recurse
if ($?)
{
$Global:Collection += @($object)
}
else
{Add-Content -Path $LogFailed -Value $error[0]
}
}#EndIf $DeleteItems
}#EndIf($DeletedDays -ge $RetentionTime)
}#EndForeach item
}#EndFunction
A few things to notice...
$Recycler.GetDetailsOf($item,2) retrieves the "Date Deleted" in a string format but apparantly there are invisible Unicode characters in the string so you will have to remove them... otherwise the conversion to [DateTime] fails.
$DeletedDate = $Recycler.GetDetailsOf($item,2) -replace "\u200f|\u200e",""
$Recycler.GetDetailsOf($item,3) retrieves the size... also in a string format. e.g. "12.8 Kb". So if you want to do calculation later on you will have to convert them to integers. Doing so rounds the numbers... 12.8 becomes 12
In the script, when the DeleteItems parameter is used with the function reporting is done also.
if (@($collection).count -gt "0")
{
$Collection = $Collection | Select-Object "Computer","User","DateRun","Name","Type","Path","SizeKb","Deleted Days","Deleted Date"
$CsvData = $Collection | ConvertTo-Csv -NoTypeInformation
$Null, $Data = $CsvData
Add-Content -Path $csvfile -Value $Data
}
One thing to notice here is that in Powershell V2 no -Append parameter is available for the Export-Csv parameter. I have V3 installed but user workstations haven't. So I had to use a workaround... use ConverTo-Csv, assign the first line to $Null and use Add-Content to append to the Csv file.
Complete script:
# -----------------------------------------------------------------------
#
# Author : Baldwin D.
# Description : Empty Recycle Bin with Retention (Logoff Script)
#
# -----------------------------------------------------------------------
$Global:Collection = @()
$Shell = New-Object -ComObject Shell.Application
$Global:Recycler = $Shell.NameSpace(0xa)
$csvfile = "\\YourNetworkShare\RecycleBin.txt"
$LogFailed = "\\YourNetworkShare\RecycleBinFailed.txt"
function Get-recyclebin
{
[CmdletBinding()]
Param
(
$RetentionTime = "7",
[Switch]$DeleteItems
)
$User = $env:USERNAME
$Computer = $env:COMPUTERNAME
$DateRun = Get-Date
foreach($item in $Recycler.Items())
{
$DeletedDate = $Recycler.GetDetailsOf($item,2) -replace "\u200f|\u200e","" #Invisible Unicode Characters
$DeletedDate_datetime = get-date $DeletedDate
[Int]$DeletedDays = (New-TimeSpan -Start $DeletedDate_datetime -End $(Get-Date)).Days
If($DeletedDays -ge $RetentionTime)
{
$Size = $Recycler.GetDetailsOf($item,3)
$SizeArray = $Size -split " "
$Decimal = $SizeArray[0] -replace ",","."
If ($SizeArray[1] -contains "bytes") { $Size = [int]$Decimal /1024 }
If ($SizeArray[1] -contains "KB") { $Size = [int]$Decimal }
If ($SizeArray[1] -contains "MB") { $Size = [int]$Decimal * 1024 }
If ($SizeArray[1] -contains "GB") { $Size = [int]$Decimal *1024 *1024 }
$Object = New-Object Psobject -Property @{
Computer = $computer
User = $User
DateRun = $DateRun
Name = $item.Name
Type = $item.Type
SizeKb = $Size
Path = $item.path
"Deleted Date" = $DeletedDate_datetime
"Deleted Days" = $DeletedDays }
$Object
If ($DeleteItems)
{
Remove-Item -Path $item.Path -Confirm:$false -Force -Recurse
if ($?)
{
$Global:Collection += @($object)
}
else
{
Add-Content -Path $LogFailed -Value $error[0]
}
}#EndIf $DeleteItems
}#EndIf($DeletedDays -ge $RetentionTime)
}#EndForeach item
}#EndFunction
Get-recyclebin -RetentionTime 7 #-DeleteItems #Remove the comment if you wish to actually delete the content
if (@($collection).count -gt "0")
{
$Collection = $Collection | Select-Object "Computer","User","DateRun","Name","Type","Path","SizeKb","Deleted Days","Deleted Date"
$CsvData = $Collection | ConvertTo-Csv -NoTypeInformation
$Null, $Data = $CsvData
Add-Content -Path $csvfile -Value $Data
}
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($shell)
#ScriptEnd
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($shell) releases the COM object.
You will have to create the 2 log files defined in $Csvfile and $LogFailed on a network share that is accessible to all your users and add the Logoff script in a GPO (User Configuration)
You can then easily parse the logfile to find out what has been deleted from the network and what has been deleted on local drives.
Grts!
Introducing PSReminderLite
2 months ago
I want a script which delete files from the recycle bin for all users,
ReplyDeleteWhen user log off from the machine , the files in the recycle bin must be deleted, these are the location which i wanted to do ( Desktop ,My Documents ,Downloads,My Music ,My Pictures ,My Videos )
Please help me how to do this ?
Great Article
ReplyDeleteMachine Learning Projects for Students
Final Year Project Centers in Chennai
Can this be used on Windows 10 computers with Server 2016?
ReplyDeleteOther students asked that I give more details or explain a subject that interested them but was not included in the course. machine learning and artificial intelligence courses in hyderabad
ReplyDeleteWhat does this line do (in the last if-statement)?
ReplyDelete$Null, $Data = $CsvData
clear-recyclebin
ReplyDeleteMMORPG
ReplyDeleteinstagram takipçi satın al
tiktok jeton hilesi
tiktok jeton hilesi
antalya saç ekimi
referans kimliği nedir
instagram takipçi satın al
metin2 pvp serverler
instagram takipçi satın al
Smm Panel
ReplyDeleteSmm panel
iş ilanları
instagram takipçi satın al
hirdavatci burada
beyazesyateknikservisi.com.tr
Servis
tiktok jeton hilesi
Good content. You write beautiful things.
ReplyDeletesportsbet
korsan taksi
sportsbet
vbet
hacklink
vbet
hacklink
taksi
mrbahis
maraş
ReplyDeletebursa
tokat
uşak
samsun
P13
عازل رطوبة للجدران
ReplyDeleteرطوبه