Search code examples
powershellexceptionpowershell-4.0

Why does the exception not get me in the catch block?


I'm trying to interrogate some service information. Sometimes the installer of the application fails to correctly install, so the registry does not contain a service entry. I want to find out which installer steps did get executed correctly, even on systems that do not have proper logging in the installer.

If MyService does not exist, the script below does not go to the catch block even though the exception handling documentation suggests a bare catch should be enough:

try {
    $path = 'hklm:\SYSTEM\CurrentControlSet\services\MyService'
    $key = Get-Item $path
    $namevalues = $key | Select-Object -ExpandProperty Property |
        ForEach-Object {
        [PSCustomObject] @{
            Name = $_;
            Value = $key.GetValue($_)
        }
    }
    $namevalues | Format-Table
}
catch {
    $ProgramFilesX86 = [System.Environment]::GetFolderPath("ProgramFilesX86");
    $ProgramFiles = [System.Environment]::GetFolderPath("ProgramFiles");
    Write-Host $ProgramFilesX86
    Write-Host $ProgramFiles
}

Why is that and how should I force it to end up in the catch?

This is what PowerShell outputs:

Get-Item : Cannot find path 'HKLM:\SYSTEM\CurrentControlSet\services\MyService' because it does not exist.
At C:\Users\Developer\...\GetMyServiceInfo.ps1:17 char:12
+     $key = Get-Item $path
+            ~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (HKLM:\SYSTEM\Cu...vices\MyService:String) [Get-Item], ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetItemCommand

Solution

  • Force the error to be terminating:

    $key = Get-Item $path -ErrorAction Stop
    

    That way it will throw and catch will get it.

    Explanation and links to the official Microsoft documentation: