Ответ 1
Если вы хотите подавить сообщение об ошибке и продолжить выполнение, вам нужно использовать -ErrorAction Ignore
или -ErrorAction SilentlyContinue
.
См. Get-Help about_CommonParameters
:
-ErrorAction[:{Continue | Ignore | Inquire | SilentlyContinue | Stop | Suspend }] Alias: ea Determines how the cmdlet responds to a non-terminating error from the command. This parameter works only when the command generates a non-terminating error, such as those from the Write-Error cmdlet. The ErrorAction parameter overrides the value of the $ErrorActionPreference variable for the current command. Because the default value of the $ErrorActionPreference variable is Continue, error messages are displayed and execution continues unless you use the ErrorAction parameter. The ErrorAction parameter has no effect on terminating errors (such as missing data, parameters that are not valid, or insufficient permissions) that prevent a command from completing successfully. Valid values: Continue. Displays the error message and continues executing the command. "Continue" is the default value. Ignore. Suppresses the error message and continues executing the command. Unlike SilentlyContinue, Ignore does not add the error message to the $Error automatic variable. The Ignore value is introduced in Windows PowerShell 3.0. Inquire. Displays the error message and prompts you for confirmation before continuing execution. This value is rarely used. SilentlyContinue. Suppresses the error message and continues executing the command. Stop. Displays the error message and stops executing the command. Suspend. This value is only available in Windows PowerShell workflows. When a workflow runs into terminating error, this action preference automatically suspends the job to allow for further investigation. After investigation, the workflow can be resumed.
Если у вас заканчиваются ошибки, которые -ErrorAction
не улавливает, то вы должны ловить их самим с помощью try/catch.
Вот наивный пример:
Get-ChildItem "C:\Users\user\Desktop\The_folder\*" -Recurse -Force '
| Sort-Object -Property FullName -Descending '
| ForEach-Object {
try {
Remove-Item -Path $_.FullName -Force -ErrorAction Stop;
}
catch { }
}
Здесь я использую -ErrorAction Stop
чтобы превратить все ошибки без прерывания в завершающие ошибки. Try
поймать любую завершающую ошибку. Однако блок catch
пуст, поэтому вы заманиваете в ловушку все, а затем не выполняете обработку ошибок. Сценарий будет продолжаться молча. Это в основном эквивалентно VBScript On Error Resume Next
. Однако вам придется проходить через файлы, в противном случае Remove-Item
остановится при первой ошибке.
Обратите внимание, что у меня есть Sort-Object
. Таким образом, элементы, идущие по трубопроводу, находятся в обратном порядке. Таким образом, файлы и подкаталоги будут удалены перед каталогами, которые их содержат. Я не уверен на 100%, если этот метод совершенен, но я думаю, что он должен работать. Альтернатива действительно беспорядочна.
Очевидно, что нет способа сказать из вывода, когда возникает ошибка или что не было удалено. Мы задерживаем все ошибки и отбрасываем их. Обычно пустой catch
блок действительно плохая идея, так что используйте этот метод с осторожностью!
Вы заметите, что я на самом деле не тестирую, открыт ли файл или заблокирован. Это потому, что это пустая трата времени. Нам все равно, почему файл не может быть удален, просто он не может и когда он не может пропустить его. Легче (и быстрее) попытаться удалить файл и задержать неудачу, чем проверять, заблокирован ли он, использовать условное решение для удаления файла, а затем удалить файл или продолжить.