Skip to content

Instantly share code, notes, and snippets.

@thedavecarroll
Last active October 31, 2019 14:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thedavecarroll/fa0507331a664ac6dfa464b40b2511e1 to your computer and use it in GitHub Desktop.
Save thedavecarroll/fa0507331a664ac6dfa464b40b2511e1 to your computer and use it in GitHub Desktop.
IronScripter Challenge - October 30, 2019 - Raise the Dead
function Get-RecycleBin {
[CmdletBinding()]
param(
[switch]$Usage
)
begin {
if ($PSEdition -eq 'Core' -And !$IsWindows) {
'This function only works on Windows.' | Write-Warning
return
}
$RecycleBinGuid = '{9B174B33-40FF-11D2-A27E-00C04FC30871}'
$DeletionDate = '{0}3' -f $RecycleBinGuid
$DeletionPath = '{0}2' -f $RecycleBinGuid
function Format-FileSize {
param($Size)
switch ($Size) {
{$_ -gt 1TB} { '{0:N2} TB' -f ($_ / 1TB) ; break}
{$_ -gt 1GB} { '{0:N2} GB' -f ($_ / 1GB) ; break}
{$_ -gt 1MB} { '{0:N2} MB' -f ($_ / 1MB) ; break}
{$_ -gt 1KB} { '{0:N2} KB' -f ($_ / 1KB) ; break}
default { '{0:N2} B' -f $_ }
}
}
try {
$Shell = New-Object -ComObject Shell.Application
$RecycleBin = @($Shell.NameSpace(10).Items())
}
catch {
$PSCmdlet.ThrowTerminatingError($_)
}
}
process {
if ($Usage) {
$RecycleBin |
Select-Object -Property *,@{label='Drive';e={$_.Path.Split(':')[0] }} |
Group-Object -Property Drive,IsFolder |
ForEach-Object {
$RecycleBinUsage = $_.Group | Measure-Object -Property Size -Sum
[PsCustomObject]@{
PSTypeName = 'RecycleBinUsage'
DriveLetter = $_.Name.Split(',')[0].Trim()
Type = if ($_.Name -match 'True') { 'Folder' } else { 'File' }
TotalItem = $RecycleBinUsage.Count
TotalSize = Format-FileSize -Size $RecycleBinUsage.Sum
}
}
} else {
$RecycleBin | ForEach-Object {
$DeletionTimeUtc = $_.ExtendedProperty($DeletionDate)
$OriginalLocation = [IO.DirectoryInfo]($_.ExtendedProperty($DeletionPath))
$DeletionTime = $DeletionTimeUtc.ToLocalTime()
$Age = New-TimeSpan -Start $DeletionTime -End (Get-Date)
$OriginalFullName = Join-Path -Path $OriginalLocation -ChildPath $_.Name
[PsCustomObject]@{
PSTypeName = 'RecycleBinItem'
Name = $_.Name
Path = $_.Path
Size = $_.Size
Type = $_.Type
LastModified = $_.ModifyDate
LastModifiedUtc = $_.ModifyDate.ToUniversalTime()
DeletionTime = $DeletionTime
DeletionTimeUtc = $DeletionTimeUtc
Age = $Age
OriginalLocation = $OriginalLocation
OriginalFullName = $OriginalFullName
RecycleBinItem = $_
}
}
}
}
<#
.SYNOPSIS
Display Recycle Bin Items
.DESCRIPTION
Display Recycle Bin Items or, alternately, display the totals for files and folders per volume.
.PARAMETER Usage
Display the total count and size for Items and Folders per Volume.
.EXAMPLE
PS C:\> Get-RecycleBin -Usage
DriveLetter Type TotalItem TotalSize
----------- ---- --------- ---------
C File 41 1.10 MB
C Folder 8 0.00 B
D File 188 834.45 MB
D Folder 64 109.88 MB
Shows the total number of items and their total size by drive letter.
.EXAMPLE
PS C:\> Get-RecycleBin
Name : Sysinternalsdsdfdsssdf
Path : D:\$RECYCLE.BIN\S-1-5-21-2079521294-2043916049-1234567890-1006\$R6WNJAI
Size : 0
Type : File folder
LastModified : 9/3/2018 8:34:49 PM
LastModifiedUtc : 9/4/2018 1:34:49 AM
DeletionTime : 9/3/2018 8:34:52 PM
DeletionTimeUtc : 9/4/2018 1:34:52 AM
Age : 422.11:57:21.6441189
OriginalLocation : D:\Tools
OriginalFullName : D:\Tools\Sysinternalsdsdfdsssdf
RecycleBinItem : System.__ComObject
Name : LICENSE.bak
Path : C:\$Recycle.Bin\S-1-5-21-2079521294-2043916049-1234567890-1006\$R82WA8P.bak
Size : 1090
Type : BAK File
LastModified : 8/31/2018 6:07:43 PM
LastModifiedUtc : 8/31/2018 11:07:43 PM
DeletionTime : 11/21/2018 9:34:56 AM
DeletionTimeUtc : 11/21/2018 3:34:56 PM
Age : 343.22:58:49.4215961
OriginalLocation : C:\PowerShell\GitHub\PoShDynDnsApi
OriginalFullName : C:\PowerShell\GitHub\PoShDynDnsApi\LICENSE.bak
RecycleBinItem : System.__ComObject
Shows all of the Recycle Bin items.
.INPUTS
None
.OUTPUTS
RecycleBinUsage
RecycleBinItem
.NOTES
This function satifies the first part of the "Raise the Dead" IronScripter Challenge.
.LINK
https://gist.github.com/thedavecarroll/fa0507331a664ac6dfa464b40b2511e1
.LINK
https://ironscripter.us/raise-the-dead-with-this-powershell-challenge/
#>
}
function Restore-RecycleBinItem {
[CmdLetBinding(SupportsShouldProcess,ConfirmImpact='High')]
param(
[Parameter(ValueFromPipeline)]
[Object[]]$RecycleBinItem
)
begin {
if ($PSEdition -eq 'Core' -And !$IsWindows) {
'This function only works on Windows.' | Write-Warning
return
}
if (!(Get-Command -Name Get-RecycleBin -ErrorAction SilentlyContinue)) {
'This function requires the Get-RecycleBin function.' | Write-Warning
return
}
}
process {
foreach ($RecycleItem in $RecycleBinItem) {
if ($RecycleItem.PSTypeNames -contains 'RecycleBinItem') {
if ($PSCmdlet.ShouldProcess($RecycleItem.OriginalFullName,'Restore Recycle Bin Item')) {
if (Test-Path -Path $RecycleItem.Path) {
$RecycleItem.RecycleBinItem.InvokeVerb('Undelete')
} else {
'{0}Recycle bin item {1}{0}with original location of {2}{0}does not exist.' -f [System.Environment]::NewLine,$RecycleItem.Path,$RecycleItem.OriginalFullName | Write-Warning
}
}
}
}
}
<#
.SYNOPSIS
Restores one or more items from the Recycle Bin.
.DESCRIPTION
Restores one or more items from the Recycle Bin.
.PARAMETER RecycleBinItem
One or more RecycleBinItem items produced by the Get-RecycleBin command.
.EXAMPLE
PS C:\> Get-RecycleBin | Restore-RecycleBinItem
Confirm
Are you sure you want to perform this action?
Performing the operation "Restore Recycle Bin Item" on target "D:\SiteTesting".
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Y"): Y
Confirm
Are you sure you want to perform this action?
Performing the operation "Restore Recycle Bin Item" on target "D:\powershell.anovelidea.org\Gemfile.lock.old".
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Y"): Y
.INPUTS
RecycleBinItem
.OUTPUTS
None
.NOTES
This function satifies the second part of the "Raise the Dead" IronScripter Challenge.
.LINK
https://gist.github.com/thedavecarroll/fa0507331a664ac6dfa464b40b2511e1
.LINK
https://ironscripter.us/raise-the-dead-with-this-powershell-challenge/
#>
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment