24 February 2014

How to solve problem with ItemNotFoundException in Powershell?

STORY:

It is strange to say,but ...Powershell is amazing command-line tool...something,which cmd always should be.It get worse,because Microsoft creates amazing documentation for Powershell. I feel weird to say so many good things about Microsoft,but it is true. Powershell is a great tool.

 I am writing script to to take control over the world. My script dealing with files like delete them ,It can happen that folder that I want delete was deleted already,so then I will see:
PS C:\Users\Poomaker C:\Data\projects\example.ps1Cannot find path 'C:\lol' because it does not exist.At C:\Data\projects\example.ps1:14 char:12+ Remove-Item <<<<  ($lolFolder+ "\lol") -recurse -force    + CategoryInfo          : ObjectNotFound: (C:\lol:String) [Remove-Item], ItemNotFoundException    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.RemoveItemCommand

Obviously, ItemNotFoundException is not good reason for script to crash,so let's catch this nasty exception,with try/catch block.
To catch ItemNotFoundException...you need type:
Catch [System.Management.Automation.ItemNotFoundException]

For example:

Try

{

    Remove-Item $lolFolder -recurse -force
}
Catch [System.Management.Automation.ItemNotFoundException]
{
    Write-Host "It is hard to delete deleted file :("    
}

Problem solved.
Well ...usually.. yes, BUT ... not for everybody ...some of You will be surprised as You will see error message:

Cannot find path ''C:\lol'' because it does not exist.At C:\Data\projects\example.ps1:18 char:12+ Remove-Item <<<<  ($jbossWorkFolder + "\lol") -recurse -force    + CategoryInfo          : ObjectNotFound: (C:\lol:String) [Remove-Item], ItemNotFoundException    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.RemoveItemCommand
Surprised? Are you saying "Eee..WTF is wrong with you ,powershell?",

SOLUTION:

Well...
Error message is confusing and to make things worse,it is partly correct.
As program stops  on ItemNotFoundException exception.

Why program didn't go to catch block?
Because.. Somewhere in your code (or in config for Powershell) you set option to stop execution (ErrorActionPreference variable is set to "Stop") if PowerShell  found a non-terminating error (exception).

for example:
$ErrorActionPreference = "Stop"
or
Remove-Item "C:\lol" -ErrorAction Stop

What to do ?
Easiest option is to catch System.Management.Automation.ActionPreferenceStopException instead or change $ErrorActionPreference (second option may require change a lot of code).

For example:

Try
{
    Remove-Item $lolFolder -recurse -force
}
Catch [System.Management.System.Management.Automation.ActionPreferenceStopException]
{
    Write-Host "It is hard to delete deleted file :("    
}


More information can be found here: http://technet.microsoft.com/en-us/library/hh847796.aspx