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.

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

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

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*' }
| improve this answer | |

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
| improve this answer | |
  • 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 7 '16 at 14:08

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?

| improve this answer | |
  • 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. – Michael Freidgeim Dec 14 '12 at 11:32

As others mentioned you can prevent IIS from locking the files. This blog post describes how to recycle a single app pool using powershell.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.