What is this?

This knowledgebase contains questions and answers about PRTG Network Monitor and network monitoring in general.

Learn more

PRTG Network Monitor

Intuitive to Use. Easy to manage.
More than 500,000 users rely on Paessler PRTG every day. Find out how you can reduce cost, increase QoS and ease planning, as well.

Free Download

Top Tags


View all Tags

How can I monitor the Windows registry with PRTG?

Votes:

0

Because the Windows Registry sensor is marked as deprecated as of PRTG 16.x.23 and will be removed from PRTG with version 16.x.25, I would like to know if there are any alternatives so that I can continue monitoring the registry databases of my servers.

Can I still monitor the Windows registry with PRTG?

cleanup custom-script-exe custom-sensor deprecated powershell prtg registry registry-sensor remove sensor

Created on Feb 8, 2016 2:07:20 PM by  Stephan Linke [Paessler Support]

Last change on Feb 8, 2016 3:47:15 PM by  Gerald Schoch [Paessler Support]



4 Replies

Accepted Answer

Votes:

2

This article applies to PRTG Network Monitor 16.x.23 or later

Monitoring the Windows Registry

The Windows Registry sensor is one of the sensor types that we remove in context of The PRTG Sensor Cleanup. This means you cannot monitor your Windows registry anymore with a sensor that is available out of the box in PRTG. You cannot add it as of PRTG version 16.x.23 and running registry sensors are removed from PRTG with version 16.x.25.

However, it is still possible for you to continue (or even to start) monitoring your Windows registry with an EXE/Script sensor. To make this alternative more comfortable for you we provide a PowerShell script that you can use to monitor the Windows registry.

It provides the following monitoring options:

  • Monitor remote registry databases.
  • You can copy the subkey that you want to monitor from the registry editor and provide it in the sensor settings (like in the deprecated registry sensor).
  • You have a -mustcontain and a -mustnotcontain option:
    • -mustcontain sets the sensor to an error if the result does not contain this string.
    • -mustnotcontain sets the sensor to an error if the result contains this string.
    • Both options can either be simple strings or regular expressions and can be used together.
  • The sensor does have a verbose option which you can set to true for debugging output.
  • If the value is empty or the key does not exist, the sensor will also show an error.

Windows Registry Sensor

Steps to Go

Please follow these steps to create a custom Windows registry sensor:

  1. Open a PowerShell (32 bit) with admin privileges and execute the command (and confirm it):
    Set-ExecutionPolicy RemoteSigned
    • Note: Executing the PowerShell script with PowerShell (x86) will not work with this sensor. The sensor message is UnauthorizedAccess when trying a 64-bit PowerShell.
  2. Copy the script below and paste it into a text editor.
  3. Save the file with the extension .ps1, for example, "windowsregistry.ps1"
  4. Copy this file into your PRTG installation folder, subfolder \Custom Sensors\EXE, on the system with the probe from which you want to monitor your registry.
  5. In PRTG add an EXE/Script sensor to the target device.
    1. Choose windowsregistry.ps1 from the list of scripts.
    2. Provide the Parameters that you want to use to execute the script. The parameters definition has to look like this:
      -ComputerName "<Host>" -Path "<Key-Path>" -ValueName "<Value-Name>"
    3. Note: The key path can be copied via right click > Copy Key Name.
    4. Set the security context to "Use Windows credentials of parent device"
    5. Adjust all the other settings to your needs.
    6. Click Continue to add the sensor.

Note: We do not provide official support for custom sensors. Of course, you are free to adjust the script according to your needs!


Version History

VersionRelease Notes
1.1[Added] Sensor will now evaluate numerical results
[Added] x64 parameter for x64 registry
[Improved] documentation
[Fixed] Bug where some values couldn't be retrieved
1.0Initial Release

Script

Use the following script for your custom Windows registry sensor:

#require --version 4.0
<#
 ___ ___ _____ ___
| _ \ _ \_   _/ __|
|  _/   / | || (_ |
|_| |_|_\ |_| \___|
 RegCheckSensor 1.12

 Author:    Stephan Linke
 
 Version History
 ----------------------------
 1.12       [Improved] Removed documentation referenes to RemoteRegistry, which is no longer necessary
 1.1        [Added]    Sensor will now evaluate numerical results
            [Added]    x64 parameter for x64 registry.
            [Improved] documentation
            [Fixed]    Bug where some values couldn't be retrieved
 1.0        Initial Release

#>

<#
.SYNOPSIS
    This sensor will allow you to retrieve registry values from the PRTG server and remote hosts. 
.DESCRIPTION 
    [INSTALLATION]
    Copy the script into your <PRTG Application Directory>/Custom Sensors/EXE directory, as <preferred-script-name>.ps1

    [SENSOR SETUP]
    1. Create a new EXE/Script sensor on the target device
    2. Copy the path of the registry by right clicking the key -> Copy Key Path
    3. Make sure the device has administrative Windows credentials configured
    4. Enter the parameters like this: 
    -ComputerName <Host> -Path "<Path-Of-The-Key>" -ValueName "<Name-Of-The-Value>"
    5. Set the security context to "Use Windows credentials of parent device".

    [SENSOR PARAMETERS]
    -ComputerName: The host you want to query
    -Path: The path where the key is stored 
    -ValueName: The name of the value you want to check
    -MustContain: The result must contain this string, otherwise it will error
    -MustNotContain: The result must not contain this string, otherwise it will error
    -x64: Use this switch if you want to query a x64 registry. 

.EXAMPLE
    PRTG-RegistryKey.ps1 -ComputerName %host -Path "SOFTWARE\Wow6432Node\Paessler\PRTG Network Monitor\Server\Webserver\testkey" -ValueName template
    Description: A very basic example that simply reads a value from the registry. 
    Output: Registry key 'template' holds 'paessler'
.EXAMPLE
    PRTG-RegistryKey.ps1 -ComputerName %host -Path "SOFTWARE\Wow6432Node\Paessler\PRTG Network Monitor\Server\Webserver\testkey" -ValueName template -MustContain "paessler" -MustNotContain "text"
    [Description] Now, just as in the old registry sensor, you can add MustContain and MustNotContain fields:
    [Output] Registry key 'template' holds 'paessler' and matches the 'paessler' pattern.
.EXAMPLE
    PRTG-RegistryKey.ps1 -ComputerName %host -Path "SOFTWARE\Wow6432Node\Paessler\PRTG Network Monitor\Server\Webserver\testkey" -ValueName template -MustContain "paessler" -MustNotContain "text"
    [Description] Lets see what happens when a key holds a value that contains  the mustnotcontain text:
    [Output] System Error: Registry key 'template' holds 'paessler-text', which matches the pattern 'text.'
.EXAMPLE
    PRTG-RegistryKey.ps1 -ComputerName %host -Path "SOFTWARE\Wow6432Node\Paessler\PRTG Network Monitor\Server\Webserver\testkey" -ValueName template -MustContain '\d{2}.\d{2}.\d{4}.'
    [Description] Of course, you can use regular expressions for both mustcontain and mustnotcontain:
    [Output] System Error: Registry key 'template' holds '08.02.2014', which matches the pattern '\d{2}.\d{2}.\d{4}.'
.LINK
   - Paessler KB Thread: https://kb.paessler.com/en/topic/68254  
.NOTES
    - Execute Set-ExecutionPolicy RemoteSigned in a elevated 32bit PowerShell if 
      you don't have any custom script sensors yet.
    - Make sure the device has administrative Windows credentials configured
#>

param(
    [string]$ComputerName         = "",
    [string]$Path                 = "",
    [string]$ValueName            = "",
    [string]$MustContain          = "",
    [string]$MustNotContain       = "",
    [switch]$AllowEmptyResults    = $FALSE,
    [switch]$x64                  = $FALSE
)

[switch]$verbose = $False;

#region function library

## show messages, nicely formatted.
function This-ShowMessage([string]$type,$message){
    if($verbose){
        Write-Host ("[{0}] [" -f (Get-Date)) -NoNewline;
        switch ($type){
            "success" { Write-Host "success" -ForegroundColor Green -NoNewline;}
            "info"    { Write-Host "info"    -ForegroundColor DarkCyan -NoNewline; }
            "warning" { Write-Host "warning" -ForegroundColor DarkYellow -NoNewline; }
            "error"   { Write-Host "error"   -ForegroundColor Red -NoNewline; }
            default   { Write-Host $type -NoNewline; }
        }
        Write-Host ("]`t{0}" -f $message)
    }
}

## this will  connect to the registry and retrieve the values
function This-GetRegistryValue(){

    $Result = (This-PrepareRegObject -Path $Path)
    This-ShowMessage -type info -message "Checking Host $($ComputerName)"
    This-ShowMessage -type info -message "Root: $($Result.Root)";
	This-ShowMessage -type info -message "Registry path: $($Result.Path)";

    $HostDetails = ([System.Net.Dns]::GetHostByName(($env:computerName)))

    if($x64)
    { $arch = [Microsoft.Win32.RegistryView]::Registry64 }
    else 
    { $arch = [Microsoft.Win32.RegistryView]::Registry32 }

    ## try to establish the remote registry connection.
    try
    {
        if(($HostDetails.AddressList -contains $ComputerName) -or ($HostDetails.HostName -match $ComputerName) -or $ComputerName -eq "127.0.0.1")
        { $Reg = [Microsoft.Win32.RegistryKey]::OpenBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine , $arch ) }
        else
        { $Reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($Result.Root,$ComputerName, $arch) }

        This-ShowMessage "info" "Registry connection established."
    }
    catch
    {
        $ErrorMessage = $_.Exception.Message
        This-ShowMessage "error" "Couldn't connect to remote registry. The error was: $($ErrorMessage)"
        Write-Host "0:Couldn't connect to remote registry. The error was: $($ErrorMessage)";
        This-Quit 2;
    }

    $RegSubKey = $Reg.OpenSubKey($Result.Path)
    $Result.Add("Value", $RegSubKey.GetValue($Result.ValueName))

    if($Result.Value -eq -1){
      This-ShowMessage "error" "Can't find the defined registry key $($Result.ValueName) in the path $($Result.Path)"
      Write-Host ([string]::Format("0:Can't find the defined registry key {0} in the path {1}",$Result.ValueName,$Result.Path)); This-Quit 2;
    }

    return $Result;

}

## this will change the path so that we can check it with PowerShell
function This-PrepareRegObject($Path){

    $Result = @{}
    $root = ($path -split "\\")

    switch($root[0]){

        "HKEY_CLASSES_ROOT"   { $Result.Add("Root",[Microsoft.Win32.RegistryHive]::ClassesRoot)   }
        "HKEY_CURRENT_USER"   { $Result.Add("Root",[Microsoft.Win32.RegistryHive]::CurrentUser)   }
        "HKEY_LOCAL_MACHINE"  { $Result.Add("Root",[Microsoft.Win32.RegistryHive]::LocalMachine)  }
        "HKEY_USERS"          { $Result.Add("Root",[Microsoft.Win32.RegistryHive]::Users)         }
        "HKEY_CURRENT_CONFIG" { $Result.Add("Root",[Microsoft.Win32.RegistryHive]::CurrentConfig) }
    }

    $Result.Add("Path",$root[1..($root.Length-1)] -join "\")
    $Result.Add("ValueName",$ValueName)

    return $Result;
}

## this function will evaluate the registry value
function This-CheckRegistryValue(){

    $Result = This-GetRegistryValue;

    #region result evaluation

    # this will be the default value, if the sensor simply checks the registry key.
    $Result.Add("PRTGResultMessage", [string]::Format("Registry key '{0}' holds '{1}'",$Result.ValueName,$Result.Value));

    # if the pattern matches, the sensor will be up
    If(($MustContain) -and (($Result.Value | Select-String -Pattern $MustContain)))
    { $Result.PRTGResultMessage = [string]::Format("Registry key '{0}' holds '{1}' and matches the pattern '{2}.'",$Result.ValueName,$Result.Value,$MustContain); $exitCode = 0; }

    # if the mustcontain variable is set, but nothing is found, the sensor will go down
    elseif(($MustContain) -and (!($Result.Value | Select-String -Pattern $MustContain)))
    { $Result.PRTGResultMessage = [string]::Format("Registry key '{0}' holds '{1}', but the search string '{2}' wasn't found.",$Result.ValueName,$Result.Value,$MustContain); $exitCode = 2; }

    ## if the mustnotcontain variable is set and matches, the sensor will go down
    If(($MustNotContain) -and ($Result.Value | Select-String -Pattern $MustNotContain))
    { $Result.PRTGResultMessage = [string]::Format("Registry key '{0}' holds '{1}', which matches the pattern '{2}.'",$Result.ValueName,$Result.Value,$MustNotContain); $exitCode = 2}

    # if the EmptyAllowed switch is set, this will allow empty values and not let the sensor error
    if($Result.Value.Length -eq 0 -and $AllowEmptyResults)
    { $Result.PRTGResultMessage = [string]::Format("Registry key {0} not set.",$Result.ValueName); $Result.Value = 0; $exitCode = 0}
    elseif($Result.Value.Length -eq 0 -and (!($AllowEmptyResults)))
    { $Result.PRTGResultMessage = [string]::Format("Registry key not set. If it's set in registry, please add -x64 to the parameters.",$Result.ValueName); $Result.Value = 0; $exitCode = 1} 


    try
    { if([int]$Result.Value -is [int]){  Write-Host ([string]::Format("{0}:{1}",$Result.Value, $Result.PRTGResultMessage)); } }
    catch
    { Write-Host ([string]::Format("0:{0}",$Result.PRTGResultMessage)); }


    This-Quit $exitCode;

    #endregion

    This-Quit $exitCode;
}

function This-Quit([int]$exitCode){
    if(!($verbose)){ exit $exitCode }
}

#endregion

This-CheckRegistryValue;

Created on Feb 8, 2016 2:16:30 PM by  Stephan Linke [Paessler Support]

Last change on Jul 21, 2016 8:57:31 AM by  Stephan Linke [Paessler Support]



Votes:

0

How to search HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList for any *.bak entry? I only want an alarm when a Bak Profil is present.

Created on Dec 19, 2017 9:42:27 AM



Votes:

0

Hi FETT,

The script will only check for single existing values. Since it's not possible to use wildcards, you'll need to modify the script to iterate through each value of a given path - something like this (C#).


Kind regards,
Stephan Linke, Tech Support Team

Created on Dec 19, 2017 11:15:01 AM by  Stephan Linke [Paessler Support]



Votes:

0

Hi,

I am trying to check registry but I got the error:

System Error: Couldn't connect to remote registry. The error was: Cannot find an overload for "OpenRemoteBaseKey" and the argument count: "2". (code: PE022)

Created on Feb 9, 2022 10:17:03 AM




Disclaimer: The information in the Paessler Knowledge Base comes without warranty of any kind. Use at your own risk. Before applying any instructions please exercise proper system administrator housekeeping. You must make sure that a proper backup of all your data is available.