1

I wrote a script to check for the file path for firefox in Windows x64 Host Key. It has a try catch block that has a fully qualified error id in the brackets.

Despite the error message being the same that is in the code, it does not catch the error.

 $program = "FireFox"

 $filepath = "HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"

 $FPF = $filepath + "\" + $program 

 try { Get-ChildItem $FPF} 

     catch [PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand] {

         if ($_.Exception.Message -match "Get-ChildItem : Cannot find path*") {

             Write-Host "false"}
     }

The full error that comes out is

Get-ChildItem : Cannot find path 'HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\FireFox' because it does not exist. At line:7 char:7 + try { Get-ChildItem $FPF} + ~~~~~~~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (HKEY_LOCAL_MACH...install\FireFox:String) [Get-ChildItem], ItemNotFoundException + FullyQualifiedErrorId :PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand

What could could be the issue?

5
  • Does your registry path HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\FireFox really exist? Commented Nov 9, 2018 at 16:59
  • No it does not. Ultimately, I am going to put this on a script that will install Firefox after that check is done Commented Nov 9, 2018 at 17:02
  • 2
    There is a difference between a terminating error (what try is for) and a non terminating error (what get-childitem it doing). either way you should be using if(Test-Path $FPF) for things like this. Commented Nov 9, 2018 at 17:02
  • Oh I see. I am going to test that out now Commented Nov 9, 2018 at 17:03
  • That seemed to do it. Test-Path must have been what I needed to do originally. Thank you Commented Nov 9, 2018 at 17:05

1 Answer 1

2

As you've discovered, you can bypass the need for your attempt at exception handling by using the Test-Path cmdlet up front to determine whether a given path exists - and if the existence is all you care about, that is enough: if (Test-Path $FPF) { ... }

Generally speaking, however, even if the path exists, you may still run into errors on traversal.


To address your original attempt: there are two fundamental problems:

  • As Matt points out in a comment, Get-ChildItem not finding a given path results in a non-terminating error, whereas try / catch only applies to terminating errors.

    • You can, however, promote non-terminating errors to terminating ones, by adding common parameter -ErrorAction Stop to the command.

    • For a summary of PowerShell's error types and their handling, see this GitHub post.

  • To qualify conditional catch handlers, you must use exception-type literals, e.g., [System.Management.Automation.ItemNotFoundException], not the value of an error record's .FullyQualifiedErrorId property (e.g., PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand)

    • To determine the full name of an error record's exception type, run the following after the error occurred:
      • $Error[0].Exception.GetType().FullName

Here's an amended version of your code, based on the above:

try {
    Get-ChildItem $FPF -ErrorAction Stop
} catch [System.Management.Automation.ItemNotFoundException] { # input path not found
    Write-Error "Not found: $FPF"
} catch {  # any other error
    Throw "An unexpected error occurred: $_"
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.