Reputation: 9266
Suppose I have the following files I'd like to remove from multiple directories.
PS d:\path> $files = gci -path . -Recurse -File
PS d:\path> $files
d:\path\foo.txt
d:\path\sub\bar.txt
I use foreach
to call Remove-Item
.
PS d:\path> $files | foreach { Remove-Item -Path $_ -WhatIf }
What if: Performing the operation "Remove File" on target "D:\path\foo.txt".
Remove-Item : Cannot find path 'D:\path\bar.txt' because it does not exist.
At line:1 char:19
+ $files | foreach { Remove-Item -Path $_ -WhatIf }
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (D:\path\bar.txt:String) [Remove-Item], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.RemoveItemCommand
It would seem that when passed a recursive list of files, Remove-Item
always tries to remove a file from the current directory. It can remove d:\path\foo.txt just fine. But it throws an error trying to remove d:\path\bar.txt, because there is no such file. The file it should be deleting is located in d:\path\sub\bar.txt.
Note that the following code works fine, presumably because the Get-ChildItem
is not recursive.
PS D:\path> del .\sub\bar.txt -WhatIf
What if: Performing the operation "Remove File" on target "D:\path\sub\bar.txt".
PS D:\path> gci .\sub\bar.txt | % { del $_ -WhatIf }
What if: Performing the operation "Remove File" on target "D:\path\sub\bar.txt".
Is this a bug in PowerShell, or am I not using it right? Is there a different prescribed way to delete files recursively, subject to pipeline filtering?
Other notes:
-WhatIf
parameter doesn't affect the issue here; it just forces Remove-Item
to print output instead of deleting my test files.-Recurse
to Remove-Item
because in my actual code I'm doing non-trivial filtering on the pipeline to choose which files to delete.Upvotes: 4
Views: 2363
Reputation: 2904
Instead of using foreach-object you can just use:
$files | Remove-Item -WhatIf
$files returns objects of type : System.IO.FileSystemInfo
if you run :
help Remove-Item -Parameter path
you will see that the path parameter accepts an array of strings.
$files[0].gettype()
is not a string so some type conversion has to happen
Upvotes: 4
Reputation: 9392
$files | foreach { Remove-Item -Path $_.FullName -WhatIf }
Upvotes: 1