Home > Back-end >  Function to Get Value from Registry - 2 issues: DWORD, console error
Function to Get Value from Registry - 2 issues: DWORD, console error

Time:12-18

This is ma very simple PowerShell function to get reg value from registry:

Function GetRegKey {
    Param([String]$GetRegKeyPath, $GetRegKeyName)
    If (Test-Path -Path $GetRegKeyPath) {
        If (Get-ItemProperty -Path $GetRegKeyPath -Name $GetRegKeyName) {
            $GetRegKeyVal = (Get-ItemPropertyValue $GetRegKeyPath $GetRegKeyName)
            Return $GetRegKeyVal
        } Else {
            write-output ("Warning! Path:  '$GetRegKeyPath'  is exist, but RegKey:  '$GetRegKeyName'  is:  not exist.") }           
    } Else {
        write-output ("Warning! Path:  '$GetRegKeyPath'  is not exist!")
        Return $null }
}

Example:
GetRegKey "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion" "ProgramFilesDir"
will give output like: C:\Program Files

I have two things what is not working:

  1. If $GetRegKeyName is not exist script besides go to command write-output ("Warning! Path: '$GetRegKeyPath' is exist, but RegKey: '$GetRegKeyName' is: not exist.") is also display in console error:

enter image description here

Is this can be somehow avoid? I did try with pipe | Out-Null but its bassically not a solution I guess.

  1. Second thing what is not works here is reg with DWORD value. Is command Get-ItemProperty -Path $GetRegKeyPath -Name $GetRegKeyName can't be used with DWORD?

CodePudding user response:

I suggest streamlining your function as follows, which only requires a single Get-ItemPropertyValue (note that I've renamed the function to GetRegValue, because it is a registry value's (data) that is returned):

Function GetRegValue {
  Param(
    [Parameter(Mandatory)]
    [String] $KeyPath, 
    [Parameter(Mandatory)]
    [String] $ValueName
  )

  try {
    Get-ItemPropertyValue -ErrorAction Stop $KeyPath $ValueName
  }
  catch [System.Management.Automation.ItemNotFoundException] {
    Write-Warning "Path:  '$KeyPath'  does not exist."
  }
  catch [System.Management.Automation.PSArgumentException] {
    Write-Warning "Path:  '$KeyPath' exists, but RegKey:  '$ValueName'  doesn't." 
  }

}  
  • A try / catch statement is used to match errors by their exception type, from which the specific error condition can be inferred.

    • Note that any exception type not matched would result in a script-terminating error; that is, error conditions other than the matched ones cause a fatal error (by default), such as a lack of permissions.
  • The common -ErrorAction parameter is used with Stop in order to promote non-terminating errors to (script-)terminating ones, which allows them to be caught with try / catch.

    • As an aside: Due to a longstanding bug still present as of PowerShell 7.3.1, Get-ItemPropertyValue inappropriately reports a (statement-)terminating error when the key path exists, but not the value name - see GitHub issue #5906.
  • Write-Warning is used to emit the warnings, which uses the dedicated warning output stream, which is conceptually preferable and also gives you automatic coloring of the message.


As for DWORD values:

PowerShell is capable of returning types of all data stored in the registry (they get mapped onto equivalent .NET types), so there shouldn't be a problem with REG_DWORD registry values.

You can verify by calling the function above as follows:

GetRegValue  HKCU:\Console FontSize

This should output an [int] (System.Int32) value such as 1048576.

Note that if the value is too large to fit into [int], you'll get a [uint32] (System.UInt32) value instead.

  • Related