2

Sorry it's probably a dumb question: what is the difference between

Remove-Item -recurse -Force -Verbose and Remove-Item -Force -Verbose

it seems if we use -recurse for a folder and subfolders powershell delete file one by one inside the folder. and if we remove the -recurse powershell simply delete the main folder without checking inside the folder. technically isn't script will run faster without -recurse?

Shahpari
  • 115
  • 2
  • 8
  • 1
    if you DO NOT use `-Recurse` in that situation, you usually get a confirmation request ... well, it has every time that i have tired it. – Lee_Dailey Nov 24 '21 at 05:38
  • @Lee_Dailey you should make that an answer as it is correct using default PowerShell settings on Windows 10 (at least). If a directory does contain data you will get a prompt to ask if you're sure. – Seth Nov 24 '21 at 06:54
  • @Seth - i am unsure of when something reaches Answer quality ... but i will take your recommendation and go with that. thank you! [*grin*] – Lee_Dailey Nov 24 '21 at 08:12
  • 1
    The command has to recursively delete all files and sub folders before being able to delete the specified directory in any case, even if you don't specify `-recurse`. Only empty directories can actually be deleted (at the [WinAPI](https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-removedirectoryw) level). – zett42 Nov 24 '21 at 10:33

2 Answers2

4

tl;dr

Pass both -Recurse and -Force to Remove-Item in order to (more) predictably delete (remove) a given folder, which - barring any permission and timing problems - deletes the folder and any contents it may have.

Caveat: This instantly deletes any contents inside the target folder, and, given that deleted items are not placed in the operating system's recycle bin, can only be recovered, potentially, with specialty software.


it seems if we use -recurse for a folder and subfolders powershell delete file one by one inside the folder.

More accurately, it deletes the target folder's subtree, i.e. it recursively deletes all files and subfolders located in the target folder, including their files and subfolders, recursively, before deleting the target folder itself. In effect, it deletes the target folder and all of its contents, if any, but note the caveats:

  • re "protected" items, which additionally require -Force, discussed below.
  • re intermittent failures due to the file-system APIs being asynchronous in older Windows versions, discussed in the bottom section.

In fact, deleting all the contents of a folder before deleting the folder itself is the only way to delete a nonempty folder, technically: the file-system APIs do not offer deletion of a nonempty folder as a single operation.

Because inadvertently deleting an entire subfolder tree can have disastrous consequences, as a safety mechanism PowerShell requires you to signal the intent to delete a nonempty folder explicitly - by passing -Recurse.

  • If you neglect to pass -Recurse and the target folder is nonempty, you get an interactive confirmation prompt - irrespective of whether -Force is specified or not. Choose [A] Yes to All (type a) to delete the folder and all its contents - but see the situational additional need for -Force below.

That said, you do also need -Force in order to (more) predictably remove a nonempty target folder, because -Force makes PowerShell also delete "protected" files and folders, which are hidden files and folders and files that have the ReadOnly and/or System attributes set (on Windows).

  • If you neglect to pass -Force when you use -Recurse or interactively choose [A] Yes to All in response to the confirmation prompt, the presence of at least one protected item will prevent removal of the target folder as a whole, though unprotected items inside the subtree will get deleted right away.

  • Each protected item will cause a non-terminating error to be emitted, concluded by a non-terminating error that the target folder cannot be removed, because it isn't empty (yet). Perhaps confusingly, in Windows PowerShell the per-protected-item error messages only talks about "[in]sufficient access rights", even though the real problem in this case isn't one of permissions; the error message has been amended in _PowerShell (Core) 7+ to explicitly mention hidden, system, and readonly items.

if we remove the -recurse powershell simply delete the main folder without checking inside the folder.

No: It follows from the above that you cannot delete a given nonempty folder unless you delete its contents first.

If you attempt that without -Recurse, you'll invariably get the confirmation prompt (or, in non-interactive scenarios, the call will fail outright).

technically isn't script will run faster without -recurse?

It also follows from the above that only an empty folder can be removed without -Recurse without triggering the confirmation prompt.

If you do also specify -Recurse when targeting an empty folder, hypothetically unnecessary work of testing whether child items exist could be performed. In practice, Remove-Item's implementation always performs this test, whether or not you pass -Recurse.


Even with both -Recurse and -Force specified, overall removal may fail:

  • ... due to insufficient file-system permission held by the current user relative to the target folder and its contents.

  • ... intermittently, due to running on Windows versions older than Windows 10 20H2 (I don't know that Windows Server version that corresponds to), because file-system item deletion there was inherently asynchronous(!), resulting in intermittent failure to fully delete a given target folder, namely if deletion of an item inside the folder hadn't completed yet by the time deletion of the folder itself was attempted: see this answer for details and a workaround.

mklement0
  • 382,024
  • 64
  • 607
  • 775
3

when you use Remove-Item on a dir tree that holds files ... and do NOT use -Recurse, you will get the standard confirmation prompt. so using that parameter makes it run without the delay from the "do you really want to do this?" prompt.

this is one of the reasons that some folks prefer to pipe the output of Get-ChildItem -Recurse to Remove-Item.

Lee_Dailey
  • 7,292
  • 2
  • 22
  • 26
  • Could you elaborate on possible advantages of using `Get-ChildItem | Remove-Item` over `Remove-Item -Recurse`? – zett42 Nov 24 '21 at 10:42
  • Here is a link to a Scripting guy article of about twelve years ago, illustrating the use of Get-childItem -recurse in conjunction with Remove-Item. https://devblogs.microsoft.com/scripting/hey-scripting-guy-can-i-delete-all-files-from-nested-folders-and-subfolders/ – Walter Mitty Nov 24 '21 at 11:25
  • 2
    `Get-ChildItem | Remove-Item` per se doesn't necessarily help, if you don't use `-Recurse`: If `Get-ChildItem`'s output is / includes a nonempty _directory_, you'll get the confirmation prompt too. If the intent is to delete _files_ only, `Get-ChildItem -File | Remove-Item` does help, however, in cases where `Remove-Item *` or `Remove-Item *.foo` could unintentionally match _directories_ too (`Remove-Item` has _no_ `-File` (or `-Directory`) switch, which is arguably a shortcoming). /cc @zett42 – mklement0 Nov 24 '21 at 16:59
  • @mklement0 - good point ... i made that a tad clearer by adding `-Recurse` to the `G-CI` call. – Lee_Dailey Nov 24 '21 at 22:35
  • @zett42 - the purpose of piping `G-CI` to `R-I` is that [when you include `-Recurse` on the `G-CI` call] you are _explicitly_ dealing with individual items. that is a somewhat more direct representation of how some of us think about the operation. **_that "concept to code" match up makes for easier coding & easier debugging & easier maintenance._** – Lee_Dailey Nov 24 '21 at 22:39
  • 1
    Adding `-Recurse` to `Get-ChildItem` doesn't help, however, because without `-File` it can still potentially include _nonempty directories_, which - without `-Recurse` applied to `Remove-Item` - again triggers the confirmation prompt. – mklement0 Nov 24 '21 at 22:41
  • 1
    @mklement0 - ah! i have never run into that situation. thank you for the info! [*grin*] – Lee_Dailey Nov 24 '21 at 22:45