Is it possible to display any sort of a progress indicator for the following (or similar) command?
$dir = 'C:\$Recycle.Bin\S-1-5-18\'
(Get-ChildItem -LiteralPath $dir -File -Recurse -Force -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum).Sum / 1GB
(piping its output to something like %{Write-Output processing item: $_.fullname; $_}
suggested in one of the answers to "Powershell Get-ChildItem progress question" - doesn't seem to work. For instance,
$dir = 'C:\$Recycle.Bin\S-1-5-18\'
(Get-ChildItem -LiteralPath $dir -File -Force -ErrorAction SilentlyContinue | %{Write-Output processing item: $_.fullname; $_} | Measure-Object -Property Length -Sum).Sum / 1GB
... produces no output at all other than the final result (size in GB).
On a number of our servers, C:\$Recycle.Bin\S-1-5-18\
(recycle bin directory for the "system" account) contains millions of files, hundreds or thousands of sub-directories (which may also contain a large number of files), and keeps filling up at a rate of 1-3GB/day.
The culprit is a misbehaving "line of business" application on these servers that seems to write a lot of temporary files to the recycle bin. At the moment, it is not an option to stop it or to change its behavior.
My priorities are these:
NukeOnDelete
, NeedToPurge
and MaxCapacity
), or a GPO that mandates permanent file deletion.The 1st part, clearing the files from the recycle bin using Powershell, seems to require to first get a list of items to delete via Get-ChildItem
- which takes a long, long time on large directories residing on fairly slow disks.
Is there a way to get an indicator that Get-ChildItem
is doing something when piped to a Measure-Object
or a similar command (e.g. number of items it was able to collect so far)?
P.S. The reason I think it might be possible is because Get-ChildItem
on its own (without a pipe to Measure-Object
) begins output right away. Utilities like TreeSize seem to be able to show progress while they're "walking" the directory tree and collecting data. dir /a/s C:\$Recycle.Bin\S-1-5-18\
also begins output right away, even if it takes a long time to complete. Any chance we could get a progress indicator when we pipe it to a Measure-Object
or a similar command?
This is a common problem. A simplified version of what you are doing is:
Get-ChildItem -Recurse | Measure-Object -Property Length -Sum
In the above, you lose visibility to the output of Get-ChildItem because you are sending the output into the pipeline, but you can easily mitigate that by adding to any part of the pipeline a section where you Write-Host
and then simply put the object back onto the pipeline to have it continue:
Get-ChildItem -Recurse | % { Write-Host $_; $_ } | Measure-Object -Property Length -Sum
or written another way:
Get-ChildItem -Recurse | % { Write-Host $_; Write-Output $_ } | Measure-Object -Property Length -Sum
Of course, you do not just have to just Write-Host the $_, you can get fancier and do things like accumulate and report on totals and etc.
I see you are attempting to take this approach already, but looks like you accidentally used Write-Output
instead of Write-Host
, which ends up also sending your status text into the pipeline and the number of characters of your status text gets added to the sum of the length of the files you are measuring. LoL. Of course you can fix your code by just fixing that:
$dir = 'C:\$Recycle.Bin\S-1-5-18\'
(Get-ChildItem -LiteralPath $dir -File -Force -ErrorAction SilentlyContinue | %{Write-Host processing item: $_.fullname; $_} | Measure-Object -Property Length -Sum).Sum / 1GB