Can anyone please help me understand why "Remove-Item" cmdlet behaves weirdly when using -Filter option for removing specific list of files? Same if I passed in other cmdlets its working fine, but if use the -Filter option within the remove-item cmdlet it is not working. Please help me undersand this behavior? Thanks in advance.
get-childitem -path '.\mydir\*.txt' | remove-item # working fine and able to understand
get-childitem -path '.\mydir' -Filter "*.txt" | remove-item # working fine and able to understand
remove-item -Path '.\mydir' -Filter '*.txt' # Trying to give warnng message to delete all contents within mydir folder, unable to understand, why?
Perhaps surprisingly, Remove-Item
invariably tries to remove a targeted directory itself as well, irrespective of the presence of a -Filter
argument.
Thus, if the target directory is non-empty, you'll get the usual "The item at c:\path\to\dir has children and the Recurse parameter was not specified." confirmation prompt.
However, adding -Recurse
is best avoided, because you'll get an error message if, after removing the filter-matching files, the directory is still non-empty; conversely, if it is (then) empty, it will be removed as a whole.
Solutions:
Make the filter part of the -Path
argument:
Remove-Item -Path '.\mydir\*.txt'
-Filter
it is the platform file-system APIs that handle the wildcard matching, not PowerShell; PowerShell's wildcard patterns are more powerful than the former, while not exhibiting certain legacy quirks.-Path
or -Include
/ -Exclude
) is slower than using -Filter
, which is applied at the source; for that reason, use of -Filter
is preferable when performance matters.Or, as already shown in your question, use Get-ChildItem
to select the files of interest, and pipe to Remove-Item
:
Get-ChildItem -Path '.\mydir' -Filter "*.txt" | Remove-Item
While slower than direct Remove-Item
use, this gives you better control over what is to be deleted.
You can add the -WhatIf
common parameter to Remove-Item
to preview what files will be deleted.
Generally (not necessary in this case), you may have to add -Recurse
to Remove-Item
, should there be (by design) subdirectories among the items output by Get-ChildItem
.