Check by-winrm¶
Overview¶
This plugin executes PowerShell commands or scripts on remote Windows hosts via WinRM, supporting JEA. It returns standard output (STDOUT) and, in case of failure, standard error (STDERR) along with the command's exit code. By evaluating these results - through threshold checks or pattern matching on STDOUT - the plugin can generate alerts with configurable severity levels.
Important Notes:
- Supports NTLM, Kerberos, CredSSP, Basic, and plaintext transports
- JEA endpoints are only supported with
pypsrp(via--winrm-configuration-name). A JEA endpoint runs a single cmdlet with its parameters and no script text, so--commandis split into the cmdlet and its parameters there, and pipes are refused. The objects the cmdlet returns arrive as oneProperty : Valueline per property, likeFormat-List, so patterns can match their properties. - This plugin is ideal for retrieving Windows-specific metrics, running custom PowerShell-based health checks (such as inventory, backup status, or failover cluster queries), and accessing systems like Active Directory, Exchange, SQL Server, or Hyper-V
- It is especially useful in environments where installing a monitoring agent is not possible or desired
- For Kerberos transport, configure
/etc/krb5.confand obtain a ticket viakinitbefore running the plugin. When Kerberos credentials are present in the cache,--winrm-usernameand--winrm-passwordcan be omitted. - When
--winrm-domainis set, the username is sent asuser@DOMAINfor NTLM authentication. Not needed for Kerberos or local accounts.
Data Collection:
- Connects to the remote Windows host via WinRM and executes the specified PowerShell command
- Automatically prefers PSRP (PowerShell Remoting / JEA) when
pypsrpis installed, and falls back to classic WinRM (pywinrm) when needed - Captures STDOUT, STDERR, and the command's return code
- Evaluates results through pattern matching (
--warning-pattern,--critical-pattern), regex matching (--warning-regex,--critical-regex), and numeric threshold checks (--warning,--criticalwith Nagios range support) - Configurable severity levels for different failure modes (STDOUT, STDERR, return code, connection timeout)
- Supports
--skip-stdoutand--skip-stderrto ignore all or the first N lines of output
Fact Sheet¶
| Fact | Value |
|---|---|
| Check Plugin Download | https://github.com/Linuxfabrik/monitoring-plugins/tree/main/check-plugins/by-winrm |
| Nagios/Icinga Check Name | check_by_winrm |
| Check Interval Recommendation | Every minute |
| Can be called without parameters | No (--command and --winrm-hostname are required) |
| Runs on | Cross-platform |
| Compiled for Windows | No (runs with Python interpreter) |
| 3rd Party Python modules | pypsrp (supports JEA). Alternative without JEA: pywinrm, pywinrm[kerberos], pywinrm[credssp] |
Prerequisites¶
Windows (Remote Host)¶
Enable WinRM on the target Windows host:
Enable-PSRemoting -Force
By default, WinRM listens on port 5985 (HTTP) and 5986 (HTTPS). Ensure the corresponding firewall port is open.
Depending on the chosen transport, additional configuration may be required:
| Transport | When to use | Extra Setup on Windows |
|---|---|---|
ntlm (default) |
Domain and workgroup environments. Works out of the box. | None - works with Enable-PSRemoting. |
kerberos |
Active Directory environments. Most secure; supports SSO via kinit on the monitoring host (no password needed). |
Requires AD domain membership. |
basic |
Testing or HTTPS-only setups. Credentials are base64-encoded (not encrypted). | winrm set winrm/config/service/auth @{Basic="true"}. Use HTTPS in production. |
credssp |
Multi-hop scenarios where credentials must be delegated to a third system. | Enable-WSManCredSSP -Role Server on the target host. |
plaintext |
Same as basic but explicitly over HTTP. |
Same as basic. Insecure - avoid in production. |
Linux (Monitoring Host)¶
For Kerberos transport, configure /etc/krb5.conf for your Active Directory domain and obtain a ticket before running the plugin:
kinit user@EXAMPLE.COM
When Kerberos credentials are present in the cache, --winrm-username and --winrm-password can be omitted.
Help¶
usage: by-winrm [-h] [-V] [--always-ok] --command COMMAND [-c CRIT]
[--critical-pattern CRIT_PATTERN]
[--critical-regex CRIT_REGEX] [--no-perfdata]
[--severity-retc {ok,warn,crit,unknown}]
[--severity-stderr {ok,warn,crit,unknown}]
[--severity-stdout {ok,warn,crit,unknown}]
[--severity-timeout {ok,warn,crit,unknown}]
[--skip-stderr SKIP_STDERR] [--skip-stdout SKIP_STDOUT]
[--verbose] [-w WARN] [--warning-pattern WARN_PATTERN]
[--warning-regex WARN_REGEX]
[--winrm-configuration-name WINRM_CONFIGURATION_NAME]
[--winrm-domain WINRM_DOMAIN] --winrm-hostname WINRM_HOSTNAME
[--winrm-password WINRM_PASSWORD]
[--winrm-transport {basic,ntlm,kerberos,credssp,plaintext}]
[--winrm-username WINRM_USERNAME]
This plugin executes PowerShell commands or scripts on remote Windows hosts
via WinRM, supporting JEA. It returns standard output (STDOUT) and, in case of
failure, standard error (STDERR) along with the command's exit code. By
evaluating these results - through threshold checks or pattern matching on
STDOUT - the plugin can generate alerts with configurable severity levels.
options:
-h, --help show this help message and exit
-V, --version show program's version number and exit
--always-ok Always returns OK.
--command COMMAND PowerShell command or script to execute on the remote
host. Supports pipelines and complex expressions. With
`--winrm-configuration-name` (JEA), a single cmdlet
with its parameters, all by name or all by position.
Example: `--command="Get-Service -Name W32Time"`.
-c, --critical CRIT CRIT threshold for single numeric return values.
Supports Nagios ranges. Example: `@10:20` alerts if
STDOUT is in range 10..20.
--critical-pattern CRIT_PATTERN
Any line matching this pattern (case-insensitive) will
count as a critical. Can be specified multiple times.
--critical-regex CRIT_REGEX
Any line matching this Python regex (case-insensitive)
will count as a critical. Can be specified multiple
times.
--no-perfdata Suppress the performance data section from the output.
The status message and the exit code are unaffected,
so alerting keeps working while trending data is
dropped.
--severity-retc {ok,warn,crit,unknown}
Severity for alerting if there is a return code != 0.
Default: warn
--severity-stderr {ok,warn,crit,unknown}
Severity for alerting if there is an output on STDERR.
Default: warn
--severity-stdout {ok,warn,crit,unknown}
Severity for alerting if there is an output on STDOUT.
Default: ok
--severity-timeout {ok,warn,crit,unknown}
Severity on connection problems. Default: unknown
--skip-stderr SKIP_STDERR
Ignore all (0) or first n lines on STDERR. Default: -1
(no ignore)
--skip-stdout SKIP_STDOUT
Ignore all (0) or first n lines on STDOUT. Default: -1
(no ignore)
--verbose Makes this plugin verbose during the operation. Useful
for debugging and seeing what is going on under the
hood.
-w, --warning WARN WARN threshold for single numeric return values.
Supports Nagios ranges. Example: `@10:20` alerts if
STDOUT is in range 10..20.
--warning-pattern WARN_PATTERN
Any line matching this pattern (case-insensitive) will
count as a warning. Can be specified multiple times.
--warning-regex WARN_REGEX
Any line matching this Python regex (case-insensitive)
will count as a warning. Can be specified multiple
times.
--winrm-configuration-name WINRM_CONFIGURATION_NAME
PowerShell session configuration name (JEA endpoint).
Only supported with pypsrp.
--winrm-domain WINRM_DOMAIN
AD domain name for NTLM authentication. When set,
username is sent as user@DOMAIN. Not needed for
Kerberos or local accounts. Default: None
--winrm-hostname WINRM_HOSTNAME
Target Windows computer on which the command will be
executed.
--winrm-password WINRM_PASSWORD
WinRM account password. Optional for Kerberos (uses
credential cache from kinit).
--winrm-transport {basic,ntlm,kerberos,credssp,plaintext}
WinRM transport type. Default: ntlm
--winrm-username WINRM_USERNAME
WinRM account name. Optional for Kerberos (uses
credential cache from kinit).
Documentation:
https://linuxfabrik.github.io/monitoring-plugins/check-plugins/by-winrm/
Usage Examples¶
Simple example - returns CRIT if the PowerShell Command 1+1 is not in the range 3..infinity:
./by-winrm \
--winrm-hostname=winsrv.example.com \
--winrm-username=Administrator \
--winrm-password=linuxfabrik \
--winrm-domain=EXAMPLE.COM \
--winrm-transport=ntlm \
--command='1+1' \
--critical='3:'
Output:
2 [CRITICAL]
Get a warning if CPU usage is >= 2.1%:
./by-winrm \
--winrm-hostname=winsrv.example.com \
--winrm-username=Administrator \
--winrm-password=linuxfabrik \
--winrm-domain=EXAMPLE.COM \
--winrm-transport=ntlm \
--command='(Get-Counter "\Processor(_Total)\% Processor Time" -SampleInterval 1 -MaxSamples 1).CounterSamples[0].CookedValue' \
--warning=2.1
Output:
2.78062697768402 [WARNING]
Check if the Windows Update service is running - alert with CRIT if it is stopped (uses a pipeline and pattern matching):
./by-winrm \
--winrm-hostname=winsrv.example.com \
--winrm-username=Administrator \
--winrm-password=linuxfabrik \
--winrm-domain=EXAMPLE.COM \
--command='(Get-Service -Name wuauserv).Status' \
--critical-pattern='Stopped'
Output if the service is stopped:
The output matches a critical pattern [CRITICAL]
Stopped
Use regex matching - alert with WARNING if any of the last 50 system event log messages contain "disk", or CRIT if they contain "error" or "fail":
./by-winrm \
--winrm-hostname=winsrv.example.com \
--winrm-username=Administrator \
--winrm-password=linuxfabrik \
--winrm-domain=EXAMPLE.COM \
--command='Get-EventLog -LogName System -Newest 50 | Select-Object -ExpandProperty Message' \
--warning-pattern='disk' \
--critical-regex='error|fail'
Use Kerberos authentication (no password needed when a valid ticket exists):
kinit -V linus@EXAMPLE.COM
klist
./by-winrm \
--winrm-hostname=winsrv.example.com \
--winrm-transport=kerberos \
--command='Get-CpuPercent'
Use a JEA (Just Enough Administration) endpoint - requires pypsrp:
./by-winrm \
--winrm-hostname=winsrv.example.com \
--winrm-username=jea-operator \
--winrm-password=linuxfabrik \
--winrm-domain=EXAMPLE.COM \
--winrm-configuration-name=MyJEAEndpoint \
--command='Get-DiskSpace'
The --winrm-configuration-name specifies the PowerShell session configuration (JEA endpoint) on the target host. Only the cmdlets allowed by the JEA role capability will be available.
With JEA, give the cmdlet's parameters all by name or all by position. The output of a service query looks like this, so --warning-pattern=Stopped finds a stopped service:
./by-winrm \
--winrm-hostname=winsrv.example.com \
--winrm-username=jea-operator \
--winrm-password=linuxfabrik \
--winrm-configuration-name=MyJEAEndpoint \
--command='Get-Service -Name W32Time' \
--warning-pattern=Stopped
DisplayName : Windows Time
ServiceName : W32Time
Status : Running
StartType : Automatic
...
A cmdlet that works with files needs the FileSystem provider in the role capability (VisibleProviders = 'FileSystem'); without it, JEA answers with a ProviderNotFoundException.
What error output looks like - for example when authentication fails:
./by-winrm \
--winrm-hostname=winsrv.example.com \
--winrm-username=Administrator \
--winrm-password=wrong-password \
--winrm-domain=EXAMPLE.COM \
--command='Get-Service'
Output:
Unable to run the command on winsrv.example.com: AuthenticationError: Failed to authenticate the user Administrator with ntlm [UNKNOWN]
States¶
States are computed in this particular order. The worst state is returned (CRIT before WARN before UNKNOWN before OK).
The first line says what raised the state: the value of a single number, a matching pattern, the exit code or the first line of STDERR. The full output follows below it.
Output on STDOUT?
- Depending on the given
--severity-stdout, returns OK (default), WARN, CRIT or UNKNOWN. - Returns WARN or CRIT depending on single numeric return values and
--warning/--critical(Nagios ranges). - Returns WARN depending on the results of
--warning-patternor--warning-regex. - Returns CRIT depending on the results of
--critical-patternor--critical-regex.
Output on STDERR?
- Depending on the given
--severity-stderr, returns OK, WARN (default), CRIT or UNKNOWN if there is output on STDERR.
Return code != 0?
- Depending on the given
--severity-timeout, returns OK, WARN, CRIT or UNKNOWN (default) if WinRM can't connect (no command output but error present). Nothing ran then, so this alone decides the state, and the first line says why the connection failed. - Depending on the given
--severity-retc, returns OK, WARN (default), CRIT or UNKNOWN if there is a return code != 0.
--always-ok suppresses all alerts and always returns OK.
Perfdata / Metrics¶
| Name | Type | Description |
|---|---|---|
| remote_runtime | Seconds | Time connecting, running the command on the remote host and disconnecting. |
Credits, License¶
- Authors: Linuxfabrik GmbH, Zurich; originally written by Dominik Riva, Universitätsspital Basel/Switzerland
- License: The Unlicense, see LICENSE file.