I have following the PowerShell script to delete folders out of my other project:
param([Parameter(Mandatory)][String]$path)
$directories = dir -Path $path -Directory -Recurse
foreach ($directory in $directories){
if ($directory.Name -eq "bin" -or $directory.Name -eq "obj"){
Remove-Item -Path $directory.FullName -Force -Confirm:$false
}
}
And if I use it, there always is a prompt
Confirm
The item at C:\Users\...\bin has children and the
Recurse parameter was not specified. If you continue, all children will be removed with the item. Are you sure you want
to continue?
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Y"):
I know that adding -Recurse
to the Remove-Item
cmdlet should do the thing, but this is redundant and because of it there is a possibility for the code to create exceptions. So how do I suppress that confirmation prompt?
While I agree that -Confirm:$False
should suppress the confirmation prompt even in the absence of -Recurse
, even if it did, the removal would still invariably be recursive.
Your real problem is the use of a foreach
statement, which invariably creates the list of directories up front (even if you used foreach ($dir in Get-ChildItem ...)
, and therefore potentially attempts to access directories that were already removed in a previous iteration, as part of a previously removed directory's subtree.
By contrast, using the pipeline directly with Get-ChildItem -Recurse -Directory
handles the recursive enumeration gracefully by not enumerating subdirs. that a previous iteration has already removed:
param([Parameter(Mandatory)][String]$path)
# Note the use of the pipeline and the ForEach-Object cmdlet.
Get-ChildItem -Path $path -Directory -Recurse | ForEach-Object {
if ($_.Name -eq "bin" -or $_.Name -eq "obj"){
Remove-Item -Recurse -Force -Confirm:$False -LiteralPath $_.FullName
}
}
The above can be simplified to:
Get-ChildItem -Path $path -Directory -Recurse -Include bin, obj |
Remove-Item -Recurse -Force -Confirm:$False