Powershell - пропустить файлы, к которым невозможно получить доступ.

Я пытаюсь рекурсивно удалить все файлы и папки внутри папки с помощью Powershell. Я пытаюсь работать с простым:

Remove-Item "C:\Users\user\Desktop\The_folder\*" -Recurse -Force

Моя проблема в том, что всякий раз, когда я запускаю ее, я получаю:

Cannot remove item C:\Users\user\Desktop\The_folder\Delete: The process cannot access the file 'C:\Users\user\Desktop\The_folder\Delete' because it is being used by another process.

Как пропустить любые файлы, к которым у меня нет доступа (возможно, потому, что они используются)? То же самое, что пользователь сделал бы во всплывающем окне, спрашивая, хочет ли он пропустить все файлы, к которым невозможно получить доступ.

Спасибо!

EDIT: Я пробовал:

Remove-Item "C:\Users\mstjean\Desktop\The_folder\*" -Recurse -Force -ErrorAction Continue

Remove-Item: не удается удалить элемент C:\Users\mstjean\Desktop\The_folder\Delete: процесс не может получить доступ к файлу "C:\Users\mstjean\Desktop\The_folder\Delete", потому что он используется другим процессом. В строке: 1 char: 1 + Remove-Item "C:\Users\mstjean\Desktop\The_folder *" -Recurse -Force -ErrorAction... +

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Категория: ) [Remove-Item], IOException + FullyQualifiedErrorId: RemoveFileSystemItemIOError, Microsoft.PowerShell.Commands.RemoveItemCommand

Но я получил эту ошибку.

Ответ 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 блок действительно плохая идея, так что используйте этот метод с осторожностью!

Вы заметите, что я на самом деле не тестирую, открыт ли файл или заблокирован. Это потому, что это пустая трата времени. Нам все равно, почему файл не может быть удален, просто он не может и когда он не может пропустить его. Легче (и быстрее) попытаться удалить файл и задержать неудачу, чем проверять, заблокирован ли он, использовать условное решение для удаления файла, а затем удалить файл или продолжить.

Ответ 2

Добавление -ea тихо продолжается, все правильно