Repository navigation
Closed
Labels
Issue-Enhancementthe issue is more of a feature request than a bugthe issue is more of a feature request than a bugResolution-By DesignThe reported behavior is by design.The reported behavior is by design.WG-Cmdletsgeneral cmdlet issuesgeneral cmdlet issues
Description
Summary of the new feature / enhancement
Current Situation
Currently, trying to recursively delete files with a particular file extension also deletes all sub directories in a call like this:
Remove-Item * -Recurse -Filter '*.java'Example
PS C:\Temp\Test> Get-ChildItem * -Recurse -Name -Filter '*.java'
trunk\MyProject\File1.java
trunk\MyProject\File2.java
trunk\MyProject\MyFolder\File1.java
trunk\MyProject\MyFolder\File2.java
PS C:\Temp\Test> Remove-Item * -Recurse -Verbose -Filter '*.java'
VERBOSE: Performing the operation "Remove Directory" on target "C:\Temp\Test\Something".
VERBOSE: Performing the operation "Remove Directory" on target "C:\Temp\Test\Something\trunk".
VERBOSE: Performing the operation "Remove Directory" on target "C:\Temp\Test\Something\trunk\MyProject".
VERBOSE: Performing the operation "Remove Directory" on target "C:\Temp\Test\Something\trunk\MyProject\MyFolder".
VERBOSE: Performing the operation "Remove File" on target "C:\Temp\Test\Something\trunk\MyProject\MyFolder\File1.java".
VERBOSE: Performing the operation "Remove File" on target "C:\Temp\Test\Something\trunk\MyProject\MyFolder\File2.java".
VERBOSE: Performing the operation "Remove File" on target "C:\Temp\Test\Something\trunk\MyProject\File1.java".
VERBOSE: Performing the operation "Remove File" on target "C:\Temp\Test\Something\trunk\MyProject\File2.java".
PS C:\Temp\Test> Get-ChildItem
PS C:\Temp\Test>Desired Situation
(a) Directories not matching the filter should not be deleted.
(b) Add a -File parameter, providing the same functionality as the Get-ChildItem -File parameter.
Version
PS C:\Temp\Test> $psversiontable
Name Value
---- -----
PSVersion 7.3.9
PSEdition Core
GitCommitId 7.3.9
OS Microsoft Windows 10.0.19045
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
Proposed technical implementation details (optional)
See above.
Metadata
Metadata
Assignees
Labels
Issue-Enhancementthe issue is more of a feature request than a bugthe issue is more of a feature request than a bugResolution-By DesignThe reported behavior is by design.The reported behavior is by design.WG-Cmdletsgeneral cmdlet issuesgeneral cmdlet issues
Activity
SteveL-MSFT commentedon Nov 6, 2023
Workaround is to use
Get-ChildItem -File | Remove-Itemmklement0 commentedon Nov 6, 2023
While I understand the desire to enhance
Remove-Item, I think what Steve Lee (@SteveL-MSFT) is showing is more than just a workaround:Given that all provider cmdlets (
Get-Command *-Item*) other thanGet-ChildItem(as well asSelect-String) lack advanced filtering capabilities, it makes sense to confine those toGet-ChildItem, and require use of the latter to provide the list of input objects via the pipeline.SetTrend commentedon Nov 7, 2023
I comprehend the tendency for not touching a running system. Yet, the current implementation adds serious hazard by deleting more items than stated in the command as unwanted side effect, and there is no way of avoiding that other than having another command do the job.
mklement0 commentedon Nov 7, 2023
My fundamental concern is that adding additional switches to only one other provider cmdlet introduces an awkward inconsistency - why don't the others have them?
Get-ChildItemis the provider cmdlet to use for advanced filtering capabilities, and using its output as pipeline input to the others, if needed, is a conceptually straightforward solution that avoids either inconsistencies or a lot of duplication of functionality.I hear you re the risks of inadvertent deletion of items with
Remove-Item, but the problem goes deeper - see below.-WhatIfpreviews what items would be targeted for deletion by a given call.Taking a closer look at your specific
Remove-Itemcommand:A conceptual problem is that
-Recursemostly does not work the way it does inGet-ChildItem; its purpose is to be an opt-in to quietly remove any directories among the targeted items.-Recursenever made much sense as an override-a-confirmation-prompt switch (there is-Force, but it already combines two behaviors: including hidden items and, on Windows, overriding aReadOnlyattribute).A bug is that that adding
-Recursecauses the-Filterargument to be ignored.In other words: your command targets all items - both files and subdirs. - in the current directory, and quietly removes them.
Remove-Item: adding-Recursewhen-Filteris also used ignores the filter, targets *all* items. #20651Curiously:
If you use
-Includerather than-Filter,-Recursedoes also recurse into subdirs. and the filtering works as intended (but still wouldn't protect you from matching subdirs. too).As an aside:
Remove-Itemworked likeGet-ChildItem,Remove-Item *.java -Recurse -WhatIfshould work the same, but doesn't:-Recursethen again only acts as the confirmation-prompt override switch.Get-ChildItembehavior in this case is itself highly problematic, especially if the-Pathargument doesn't contain wildcard characters: it is still treated as a name to search for in the entire subtree - see Get-ChildItem -Recurse treats literals passed to -Path like wildcard expressions #5699The above isn't the only problem; there's a number of open
Remove-Itembugs as of this writing:mklement0 commentedon Nov 9, 2023
Axel D. (@SetTrend), to me the tl;dr is (keep in mind that I'm just a fellow user):
I don't think what you're suggesting should be added to
Remove-Item.Remove-Itemdoes need changing, however:-Recurseswitch (primarily from the documentation), in one of two ways:-Force(while exceptionally tolerating the presence of both-Forceand-Recurse), meaning that the existing semantics of-Forcewould be overloaded (technically, a breaking change, though arguably one that falls into bucket 3).-Recursean alias of it; however, it's hard to come up with a good name;-WithContent?jdhitsolutions commentedon Mar 6, 2024
The WG has reviewed this and considers this to be more of a documentation issue. The PowerShell paradigm is to get a group of things and then perform some action. The get cmdlet provides the filtering which is what is asked for here. The Remove-Item cmdlet is working as designed.
microsoft-github-policy-service commentedon Mar 7, 2024
This issue has been marked as by-design and has not had any activity for 1 day. It has been closed for housekeeping purposes.
microsoft-github-policy-service commentedon Mar 7, 2024
📣 Hey Axel D. (@SetTrend), how did we do? We would love to hear your feedback with the link below! 🗣️
🔗 https://aka.ms/PSRepoFeedback