Suppress error for one line

This topic contains 7 replies, has 5 voices, and was last updated by  nohandle 3 years, 2 months ago.

  • Author
    Posts
  • #16473

    Kieran Walsh
    Participant

    Hi there,
    I have a script that will contact all servers in AD and then see if they are Virtual Machines. for any server that doesn't have the appropriate registry value an error is returned. Here are the relevant lines:

    $RegBase = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine,$Server)
     $VMHostName = $RegBase.OpenSubKey("SOFTWARE\Microsoft\Virtual Machine\Guest\Parameters\$_").GetValue('PhysicalHostName')

    The error returned is "You cannot call a method on a null-valued expression."
    -erroraction silently continue is not supported here, and I know that I can set $ErrorActionPreference= 'silentlycontinue' to stop all errors, but really I want to see any other genuine errors.
    So, is there a way to stop errors that only show when the above registry key does not exist?
    Thanks

  • #16474

    Dave Wyatt
    Moderator

    You can use try/catch, or temporarily change $ErrorActionPreference; those are really the only two opetions, when you're calling a .NET method directly.

    try
    {
        $VMHostName = $RegBase.OpenSubKey("SOFTWARE\Microsoft\Virtual Machine\Guest\Parameters\$_").GetValue('PhysicalHostName')
    }
    catch
    {
        $VMHostName = ''
        # Or whatever other error handling action you want to take
    }
    
  • #16475

    Kieran Walsh
    Participant

    Awesome! The Try/Catch worked perfectly.
    Thanks for that.

    In fact both answers worked for me. Just to check I understood you correctly I changed the line to:

    $ErrorActionPreference= 'silentlycontinue' 
    $VMHostName = $RegBase.OpenSubKey("SOFTWARE\Microsoft\Virtual Machine\Guest\Parameters\$_").GetValue('PhysicalHostName')
    $ErrorActionPreference= 'continue' 

    Mind blown – would never have thought of changing system variables mid-script.

    Thanks again.
    Kieran.

  • #16476

    Simon Wåhlin
    Participant

    Just a note on changing the $ErrorActionPreference since it MIGHT not be set to 'Continue' before you changed it the first time I would recommend saving the old value before, like this:

    $OriginalErrorActionPreference = $ErrorActionPreference
    $ErrorActionPreference= 'silentlycontinue' 
    $VMHostName = $RegBase.OpenSubKey("SOFTWARE\Microsoft\Virtual Machine\Guest\Parameters\$_").GetValue('PhysicalHostName')
    $ErrorActionPreference = $OriginalErrorActionPreference
    
  • #16478

    Kieran Walsh
    Participant

    Yes indeed, good idea. Thanks for the tip!
    Kieran.

  • #16496

    Daniel Krebs
    Moderator

    Kieran and Simon,

    I might be completely wrong but changing the ErrorActionPreference variable back and forth does not have any effect around your .NET method calls. Dave showed the correct approach with try/catch if you want to continue to use the .NET method calls. Alternatives are to use PowerShell Remoting if your servers are enabled for it and the Get-ItemProperty cmdlet or the WMI Registry provider. Just search a bit more using your favourite search engine and browse the TechNet Script Center (also available via the Script Browser add-on for the PowerShell ISE).

    try
    {
       $RegBase = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine,$Server)
       $VMHostName = $RegBase.OpenSubKey("SOFTWARE\Microsoft\Virtual Machine\Guest\Parameters\$_").GetValue('PhysicalHostName')
    }
    catch
    {
        $VMHostName = "
        # Or whatever other error handling action you want to take
    }
    
  • #16504

    Dave Wyatt
    Moderator

    The documentation doesn't say so, but changing $ErrorActionPreference does have some effect on terminating errors. They'll still abort a pipeline, but when the error is raised to your current scope, your $ErrorActionPreference variable kicks in. So if you've set it to SilentlyContinue, nothing winds up getting displayed at the console. It's one of the little quirks that I included in the Error Handling ebook.

  • #16507

    nohandle
    Member

    You might consider suppressing just the single exception. Not all possible exceptions.

    $RegBase = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine,$Server)
    try
    {
    	$VMHostName = $RegBase.OpenSubKey("SOFTWARE\Microsoft\Virtual Machine\Guest\Parameters\$_").GetValue('PhysicalHostName')
    }
    catch [Management.Automation.RuntimeException]
    {
    	if ($_.FullyQualifiedErrorId -ne "InvokeMethodOnNull")
    	{
    		throw $_
    	}
    }
    

You must be logged in to reply to this topic.