我们正在使用部署工具以及 PowerShell 脚本,用于在部署新版本之前删除使用的文件夹Remove-Item
。有时 PS 脚本会失败并显示以下错误:
Remove-Item:无法删除项目 Services\bin:该过程无法访问文件 Services\bin',因为另一个过程正在使用该文件 Get-ChildItem -Path $Destination -Recurse | Remove-Item <<<< -force -recurse + CategoryInfo:WriteError:(C:\Program File..\Services\bin:DirectoryInfo)[Remove-Item],IOException FullyQualifiedErrorId:RemoveFileSystemItemIOError,Microsoft.PowerShell.Commands.RemoveItemCommand
我尝试遵循回答(从:PowerShell 中的强制删除文件和目录有时会失败,但并非总是如此) 以 管道Get-ChildItem -Recurse
输送Remove-Item
.
Get-ChildItem * -Include *.csv -Recurse | Remove-Item
但错误仍然会定期发生。我们正在使用解锁器手动终止锁定应用程序(通常是 w3wp),但我更喜欢找到自动化解决方案。
另一个(不太理想的)选择是抑制 powershell 错误
Get-ChildItem -Recurse -Force -ErrorAction SilentlyContinue
欢迎任何建议。
答案1
晚了,但有人可能会觉得这很有用。
在自动化脚本中,我递归执行进程来查找任何使用我想要删除的目录路径的进程,然后终止它们。
有时其他应用程序可能会锁定文件,因此我使用进程资源管理器来查找句柄/dll。如果可以终止该应用程序,我会将终止操作添加到脚本中。
然后删除该目录。
get-process | foreach{
$pName = $_
if ( $pName.Path -like ( $INSTALL_PATH + '*') ) {
Stop-Process $pName.id -Force -ErrorAction SilentlyContinue
}
}
Remove-Item -Force -Recurse $INSTALL_PATH
答案2
您可以检查 cmdlet 给出的错误Remove-Item
。使用ErrorVariable
参数 onRemove-Item
将其错误存储在变量中,然后循环遍历它,仅显示您想要的错误,如下所示:
Get-ChildItem * -Include *.csv -recurse | ForEach-Object {
$removeErrors = @()
$_ | Remove-Item -ErrorAction SilentlyContinue -ErrorVariable removeErrors
$removeErrors | where-object { $_.Exception.Message -notlike '*it is being used by another process*' }
}
答案3
嗯,因为它是一个锁定文件的 Web 应用程序,为什么不在iisreset /stop
删除该项目之前再执行一次,然后iisreset /start
再执行一次呢?