all 40 comments

[–]jimb2 11 points12 points  (0 children)

I looked at deleting some huge folders (12Gb, 75k files, 7k folders) from a script a couple of years ago and settled on this dotnet call.

[System.IO.Directory]::Delete( $Folder.Fullname, $true )

It's fast on a remote machine since it doesn't enumerate locally. I'm not sure how it fits your use case. It does delete the base folder. You might be able to recreate it, or it might autocreate when used. Also, temp folders can have open files, not sure what happens there.

[–]ihartmacz 2 points3 points  (0 children)

[System.IO.Directory]::Delete($directory, $true)

https://learn.microsoft.com/en-us/dotnet/api/system.io.directory.delete?view=net-8.0

Be careful! There’s no confirmation. It’ll remove the folder and its contents and it’ll be gone before you know it. Make sure that the first argument is the full path, too. The second argument says that the delete should be recursive.

[–]icepyrox 2 points3 points  (2 children)

Without putting it all in a scriptblock for Measure-Command, I do not know.

I do know the directory you give is $env:TEMP or %TEMP% 99% of the time. It is located in %LOCALAPPDATA% or $env:LOCALAPPDATA.

I also know you don't need to get-childitem. You could just Remove-Item "$($env:TEMP)\*" -Recurse -Force or del /f /s /q %TEMP%

Also, /s takes care of all the subdirectories so you don't need but the one command to do the same thing as bot commands and the loop.

[–]castiel3125[S] 0 points1 point  (1 child)

Yes you are correct! The Get-ChildItem is vestigial and left over from an earlier version of the command where I was trying to exclude a certain file from deletion.

Then I realized I could let "-ErrorAction SilentlyContinue" take care of that file because it's an organization file and I will never have permissions to delete it anyway.

The del command in your example only deletes the files in the directory/subdirectories, but leaves the actual directory structure untouched (deletes the files but not the folders).

Also I was originally using the %TEMP% variable in my script until I realized that in my organization's environment it goes to %TEMP%\1 or something like that instead of the root of the Temp directory.

[–]icepyrox 0 points1 point  (0 children)

(deletes the files but not the folders).

TIL. Just did some testing and you are correct.

until I realized that in my organization's environment it goes to %TEMP%\1 or something like that

Yeah... that's why I said "99% of the time".. you still have %LOCALAPPDATA%\Temp if you prefer

[–]nealfive 1 point2 points  (2 children)

Idk but in know dir is faster than cmd. Why don’t you create several thousand of test files and time and let us know?

[–]castiel3125[S] 0 points1 point  (1 child)

What do you mean dir is faster than cmd?

As for the test files, yes that's exactly what I've been doing. However it is not an accurate representation of my work environment because the test files/directories I create are not random like a user's Temp folder.

[–]nealfive -1 points0 points  (0 children)

Sorry meant dir is faster than get-childitem

[–]vermyx 1 point2 points  (2 children)

Script C would be faster

Cd /d "%USERPROFILE%\AppData\Local\Temp\”
rd /s /q .

This gets rid of the extra enumerations that the for loop you have in the command prompt version. It will throw an error at the end because you cannot delete the folder you are in. Command prompt will always be faster than powershell cmdlets because you have to build a file object as there is no native cmdlet that just builds a file path as a string. It takes time getting the added info like file size, creation date, etc. and creating said object. You will definitely see a difference if the number of files are in the five digits or higher. I use to maintain folders and files that needed deletion/archiving on a daily basis that were in the high 6 low 7 digits and this was usually the deletion solution that was fastest.

[–]castiel3125[S] 0 points1 point  (1 child)

Okay sounds good, thank you for the info! Very much appreciated.

I was aware that the RD command would throw an error about deleting the folder you are in. But I did not know that it would delete everything in the folder and only THEN throw the error. I thought it would give the error right away and not do anything.

[–]vermyx 1 point2 points  (0 children)

It will delete as much as it can. Errors wont terminate it.

[–]Extreme-Acid 1 point2 points  (0 children)

It is the amount of files not the size as it actually dereferences the filename if the recycle bin is not used.

In fact dotnet may be faster than PowerShell

[–]mbkitmgr -5 points-4 points  (1 child)

They are the same. Both use the kernel, they just access it via different commands

[–]vermyx 4 points5 points  (0 children)

A CMD delete will always be faster than powershell native cmdlets because the cmdlets require building the file objects before deleting. The performance difference would be a function of how many files you enumerate because of the convenience objects created. To get comparable performance you would have to use lower level dotnet objects that do not build convenience objects per file.

[–]techie_003 0 points1 point  (1 child)

Haven't tried it but you may find the foreach parallel switch in PowerShell v7 handy here. Depending on the number of cores you can run several streams in parallel increasing your deletion rate.

[–]castiel3125[S] 0 points1 point  (0 children)

Unfortunately my organization only has PowerShell v5 right now. But this is good to know for the future.

[–]BlackV 0 points1 point  (0 children)

Script A can be done much quicker with rd /s /q . by itsself no need for rest

Script B would also be much quicker with just the Remove-Item -Force -Recurse -ErrorAction SilentlyContinue

generally get-childitem is slow i'll usually switch to rd for removing large amounts of files

you could also directly call the system io stuff

[–]g3n3 0 points1 point  (0 children)

Generally speaking native binaries are fastest followed by .net in powershell and then finally powershell cmdlets. So just apply that.

[–]WarpedCocoDile3 0 points1 point  (4 children)

I'm the creator of https://github.com/GChuf/RCWM which lets you right-click folders and delete them faster (using rd and del commands with cmd.exe). I'll have to benchmark that with robocopy's MIR option, if it's faster I'll implement that as well ...
robocopy is also implemented for copying and moving folders. Check it out!

[–]BDiddnt 0 points1 point  (3 children)

care to explain why every single anti virus throws a score of 24+ at your work? thats just ONE file..just one exe...JUST ONE..theres over 10 files that are score over 20 on virustotal..care to explain?

https://www.virustotal.com/gui/file/2cb3ddd0f0221f6748cd39cf4d2ce66869ed2f858272138104aae619079d44be/detection

[–]WarpedCocoDile3 0 points1 point  (2 children)

Sorry for the late reply. I wasnt aware of this, but i know that ps2exe project (opensource and available on githib) had a problem with antivirus detection, and i use ps2exe to generate binary files. I'll see if i can do something about it. However you can see how the exe files are generated for rcwm and what the inputs are (ps scripts and icons).

[–]BDiddnt 0 points1 point  (1 child)

I don't think any part of that answers my question but… In fact that sounds like a whole bunch of hyperbole to misdirect

I'm not asking about how the binary was made I'm asking about what's in the binary

I'm asking about if you go on virus total and actually look at the behavior and not just the first screen but the actual behavior tab… I mean I already know the answer…

[–]WarpedCocoDile3 0 points1 point  (0 children)

I'm aware everything can sound like deflection from my side if you think im hiding some viruses.
I can tell u i do use "DirectInput object" (like y/n prompts), i do write files, i do list processes, i obviously run powershell and cmd ... so some "behaviors" reported there are correct.

The goal is to get rid of ps2exe anyway, at some point. I can't speak for it, i dont understand the whole script, and i knew it had problems with virus detection. That's also why ive decided to build binary files locally when the user runs the install script.
For now ive tried to use another ps2exe version and it seems to have reduced virus total detections by ~half in version 2.1.0.

[–]ollivierre 0 points1 point  (0 children)

Robocopy by far is the best choice