10

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.

2
  • does unlocker tell you what its doing as in is the problem the same everytime it executes?
    – tony roth
    Feb 11, 2012 at 1:35
  • Unlocked shows that the folder is locked by some application - usually w3wp and allow me to kill the app. Feb 17, 2012 at 22:50

3 Answers 3

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
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? Jun 7, 2016 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, 2020 at 14:35
2

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*' }
}
2
  • You should add -force.
    – Timo
    Jul 30, 2020 at 8: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, 2020 at 8: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?

1
  • Unfortunately, we have many sites on the server, so stop IIS is not an option, but I will check, how to stop/start single pool. Dec 14, 2012 at 11:32

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .