9

We are using TfsDeployer and PowerShell script to remove the folders using Remove-Item before deployment of a new version. Sometimes the PS script fails with the error:

Remove-Item : Cannot remove item Services\bin: The process cannot access the file Services\bin' because it is being used by another proc 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

I’ve tried to follow the answer (from: Force-remove files and directories in PowerShell fails sometimes, but not always) to pipe Get-ChildItem -Recurse into Remove-Item.

Get-ChildItem * -Include *.csv -Recurse | Remove-Item

But the error still happens periodically. We are using unlocker to manually kill the locking application, (it’s usually w3wp), but I prefer to find automated solution.

Another (not ideal) option is to-suppress-powershell-errors

 Get-ChildItem -Recurse -Force -ErrorAction SilentlyContinue

Any suggestions are welcome.

Trung0246
  • 103
  • 4
Michael Freidgeim
  • 197
  • 1
  • 1
  • 10

3 Answers3

3

Late, but someone might find this useful.

In an automation script, I recurse through processes to find any that is using the path of the directory I want to delete, and kill them.

Sometimes other apps might be locking a file, so I used process explorer to find handle/dll. If is ok to kill the app, I add the kill to the script.

Then remove the dir.

        get-process | foreach{
          $pName = $_
          if ( $pName.Path -like ( $INSTALL_PATH + '*') ) {
            Stop-Process $pName.id -Force -ErrorAction SilentlyContinue
          }
        }
       Remove-Item  -Force -Recurse $INSTALL_PATH
sysadmin1138
  • 133,124
  • 18
  • 176
  • 300
jessarah
  • 131
  • 2
  • The approach you describe sounds very interesting to me, 'cause that's exactly the kind of functionality I've been dreaming to use for this problem. Still, are you sure there are no side effects? And again, after `Stop-Process`, aren't you worried that you should restart them? – Ifedi Okonkwo Jun 07 '16 at 14:08
  • @jessarah I want to `rm` a `file`, not a `dir`, so I set `$install_path = file1.xls`. It closed nearly all my apps in `windows 10` but the file was not removed. However, I could then remove it. – Timo Aug 25 '20 at 14:35
1

You could inspect the errors given by the Remove-Item cmdlet. Use the ErrorVariable parameter on Remove-Item to store its errors in a variable, then loop through it, only displaying the errors you want, like this:

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*' }
}
Michael Bray
  • 232
  • 3
  • 9
splattered bits
  • 928
  • 3
  • 11
  • 23
  • You should add `-force`. – Timo Jul 30 '20 at 08:37
  • This is simpler, no `foreach`: `Get-ChildItem $ziel -recurse | Remove-Item -ErrorAction SilentlyContinue -ErrorVariable removeErrors -Force;$removeErrors | where-object { $_.Exception.Message -notlike '*it is being used by another process*' }` – Timo Jul 30 '20 at 08:43
0

Well as it's a web application that's locking the file, why don't you do an iisreset /stop before removing the item, and then iisreset /start afterwards?

Dominic Cronin
  • 670
  • 4
  • 21