Назад | Перейти на главную страницу

Как избежать ошибок PowerShell Remove-Item «процесс не может получить доступ к файлу»?

Мы используем TfsDeployer и сценарий 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

Любые предложения приветствуются.

Поздно, но кому-то это может пригодиться.

В сценарии автоматизации я рекурсивно просматриваю процессы, чтобы найти все, которые используют путь к каталогу, который я хочу удалить, и уничтожить их.

Иногда другие приложения могут блокировать файл, поэтому я использовал проводник процессов, чтобы найти дескриптор / dll. Если можно убить приложение, я добавляю его в сценарий.

Затем удалите каталог dir.

        get-process | foreach{
          $pName = $_
          if ( $pName.Path -like ( $INSTALL_PATH + '*') ) {
            Stop-Process $pName.id -Force -ErrorAction SilentlyContinue
          }
        }
       Remove-Item  -Force -Recurse $INSTALL_PATH

Вы можете проверить ошибки, указанные в Remove-Item командлет. Использовать ErrorVariable параметр на Remote-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*' }
}

Так как это веб-приложение, которое блокирует файл, почему бы вам не сделать iisreset /stop перед удалением предмета, а затем iisreset /start потом?

Как уже упоминалось, вы можете запретить IIS блокировать файлы. это Сообщение блога описывает, как переработать единый пул приложений с помощью PowerShell.