|
| 1 | +# Check by-winrm |
| 2 | + |
| 3 | +## Overview |
| 4 | + |
| 5 | +Execute commands on remote Windows hosts via WinRM (Windows Remote Management), including support for JEA (Just Enough Administration) and PowerShell Remoting (PSRP). It behaves similarly to [by-ssh](https://github.com/Linuxfabrik/monitoring-plugins/tree/main/check-plugins/by-ssh), but - although running on Linux - is Windows-native, speaking Microsoft's remoting protocols instead of SSH. |
| 6 | + |
| 7 | +This plugin securely executes PowerShell commands or scripts on remote Windows hosts via WinRM, supporting NTLM, Kerberos, CredSSP, Basic, and plaintext transports. It automatically prefers PSRP (PowerShell Remoting / JEA) for modern, least-privilege Windows remoting and falls back to classic WinRM when needed. Output can be evaluated using numeric thresholds, pattern and regex matching, and configurable severity levels based on stdout, stderr, return code, or connection issues. It also exports execution time as performance data (remote_runtime). |
| 8 | + |
| 9 | +This makes the plugin 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, offering a secure and flexible alternative for remote monitoring on Windows hosts. |
| 10 | + |
| 11 | + |
| 12 | +## Fact Sheet |
| 13 | + |
| 14 | +| Fact | Value | |
| 15 | +|----|----| |
| 16 | +| Check Plugin Download | <https://github.com/Linuxfabrik/monitoring-plugins/tree/main/check-plugins/by-winrm> | |
| 17 | +| Check Interval Recommendation | Once a minute | |
| 18 | +| Can be called without parameters | No | |
| 19 | +| Compiled for Windows | No | |
| 20 | +| Requirements | Enable WinRM on the remote host (`Enable-PSRemoting -Force`). For JEA usage, configure a JEA endpoint with a role allowing specific commands only (recommended for security-sensitive environments). | |
| 21 | +| 3rd Party Python modules | `pypsrp` (supports JEA). Alternative without JEA: `pywinrm`, `pywinrm[kerberos]`, `pywinrm[credssp]` | |
| 22 | + |
| 23 | + |
| 24 | +## Help |
| 25 | + |
| 26 | +```text |
| 27 | +usage: by-winrm [-h] [-V] [--always-ok] --command COMMAND [-c CRIT] |
| 28 | + [--critical-pattern CRIT_PATTERN] |
| 29 | + [--critical-regex CRIT_REGEX] |
| 30 | + [--severity-retc {ok,warn,crit,unknown}] |
| 31 | + [--severity-stderr {ok,warn,crit,unknown}] |
| 32 | + [--severity-stdout {ok,warn,crit,unknown}] |
| 33 | + [--severity-timeout {ok,warn,crit,unknown}] |
| 34 | + [--skip-stderr SKIP_STDERR] [--skip-stdout SKIP_STDOUT] |
| 35 | + [--test TEST] [--verbose] [-w WARN] |
| 36 | + [--warning-pattern WARN_PATTERN] [--warning-regex WARN_REGEX] |
| 37 | + [--winrm-domain WINRM_DOMAIN] --winrm-hostname WINRM_HOSTNAME |
| 38 | + --winrm-password WINRM_PASSWORD |
| 39 | + [--winrm-transport {basic,ntlm,kerberos,credssp,plaintext}] |
| 40 | + [--winrm-username WINRM_USERNAME] |
| 41 | +
|
| 42 | +This plugin executes commands on remote Windows hosts by WinRM, supporting |
| 43 | +JEA. It returns standard output (STDOUT) and, in case of failure, standard |
| 44 | +error (STDERR) along with the command's exit code. By evaluating these results |
| 45 | +- through threshold checks or pattern matching on STDOUT - the plugin can |
| 46 | +generate alerts with configurable severity levels. |
| 47 | +
|
| 48 | +options: |
| 49 | + -h, --help show this help message and exit |
| 50 | + -V, --version show program's version number and exit |
| 51 | + --always-ok Always returns OK. |
| 52 | + --command COMMAND WinRM: Command that will be executed on the remote |
| 53 | + host. |
| 54 | + -c, --critical CRIT CRIT threshold for single numeric return values. |
| 55 | + Supports Nagios ranges. Example: `@10:20` alerts if |
| 56 | + STDOUT is in range 10..20. |
| 57 | + --critical-pattern CRIT_PATTERN |
| 58 | + Any line matching this pattern (case-insensitive) will |
| 59 | + count as a critical. Can be specified multiple times. |
| 60 | + --critical-regex CRIT_REGEX |
| 61 | + Any line matching this python regex (case-insensitive) |
| 62 | + will count as a critical. Can be specified multiple |
| 63 | + times. |
| 64 | + --severity-retc {ok,warn,crit,unknown} |
| 65 | + Severity for alerting if there is a return code != 0. |
| 66 | + Default: warn |
| 67 | + --severity-stderr {ok,warn,crit,unknown} |
| 68 | + Severity for alerting if there is an output on STDERR. |
| 69 | + Default: warn |
| 70 | + --severity-stdout {ok,warn,crit,unknown} |
| 71 | + Severity for alerting if there is an output on STDOUT. |
| 72 | + Default: ok |
| 73 | + --severity-timeout {ok,warn,crit,unknown} |
| 74 | + Severity on connection problems. Default: unknown |
| 75 | + --skip-stderr SKIP_STDERR |
| 76 | + Ignore all (0) or first n lines on STDERR. Default: -1 |
| 77 | + (no ignore) |
| 78 | + --skip-stdout SKIP_STDOUT |
| 79 | + Ignore all (0) or first n lines on STDOUT. Default: -1 |
| 80 | + (no ignore) |
| 81 | + --test TEST For unit tests. Needs "path-to-stdout-file,path-to- |
| 82 | + stderr-file,expected-retc". |
| 83 | + --verbose Makes this plugin verbose during the operation. Useful |
| 84 | + for debugging and seeing what's going on under the |
| 85 | + hood. Default: False |
| 86 | + -w, --warning WARN WARN threshold for single numeric return values. |
| 87 | + Supports Nagios ranges. Example: `@10:20` alerts if |
| 88 | + STDOUT is in range 10..20. |
| 89 | + --warning-pattern WARN_PATTERN |
| 90 | + Any line matching this pattern (case-insensitive) will |
| 91 | + count as a warning. Can be specified multiple times. |
| 92 | + --warning-regex WARN_REGEX |
| 93 | + Any line matching this python regex (case-insensitive) |
| 94 | + will count as a warning. Can be specified multiple |
| 95 | + times. |
| 96 | + --winrm-domain WINRM_DOMAIN |
| 97 | + WinRM Domain Name. Default: None |
| 98 | + --winrm-hostname WINRM_HOSTNAME |
| 99 | + Target Windows computer on which the command is to be |
| 100 | + executed. |
| 101 | + --winrm-password WINRM_PASSWORD |
| 102 | + WinRM Account Password. |
| 103 | + --winrm-transport {basic,ntlm,kerberos,credssp,plaintext} |
| 104 | + WinRM transport type. Default: ntlm |
| 105 | + --winrm-username WINRM_USERNAME |
| 106 | + WinRM Account Name. Default: Administrator |
| 107 | +``` |
| 108 | + |
| 109 | + |
| 110 | +## Usage Examples |
| 111 | + |
| 112 | +Simple example - returns CRIT if the PowerShell Command `1+1` is not in the range `3..infinity`: |
| 113 | + |
| 114 | +```bash |
| 115 | +./by-winrm \ |
| 116 | + --winrm-hostname=winsrv.example.com \ |
| 117 | + --winrm-username=Administrator \ |
| 118 | + --winrm-password=linuxfabrik \ |
| 119 | + --winrm-domain=EXAMPLE.COM \ |
| 120 | + --winrm-transport=ntlm \ |
| 121 | + --command='1+1' \ |
| 122 | + --critical='3:' |
| 123 | +``` |
| 124 | + |
| 125 | +Output: |
| 126 | + |
| 127 | +```text |
| 128 | +2 [CRITICAL] |
| 129 | +``` |
| 130 | + |
| 131 | +Get a warning if CPU usage is >= 2.1%: |
| 132 | + |
| 133 | +```bash |
| 134 | +./by-winrm \ |
| 135 | + --winrm-hostname=winsrv.example.com \ |
| 136 | + --winrm-username=Administrator \ |
| 137 | + --winrm-password=linuxfabrik \ |
| 138 | + --winrm-domain=EXAMPLE.COM \ |
| 139 | + --winrm-transport=ntlm \ |
| 140 | + --command='(Get-Counter "\Processor(_Total)\% Processor Time" -SampleInterval 1 -MaxSamples 1).CounterSamples[0].CookedValue' \ |
| 141 | + --warning=2.1 |
| 142 | +``` |
| 143 | + |
| 144 | +Output: |
| 145 | + |
| 146 | +```text |
| 147 | +2.78062697768402 [WARNING] |
| 148 | +``` |
| 149 | + |
| 150 | + |
| 151 | +## States |
| 152 | + |
| 153 | +States are computed in this particular order. The worst state is returned (CRIT before WARN before UNKNOWN before OK). |
| 154 | + |
| 155 | +Output on STDOUT? |
| 156 | + |
| 157 | +* Depending on the given `--severity-stdout`, returns OK (default), WARN, CRIT or UNKNOWN. |
| 158 | +* Returns WARN depending on the return value and `--warning`. |
| 159 | +* Returns CRIT depending on the return value and `--critical`. |
| 160 | +* Returns WARN depending on the results of `--warning-pattern` or `--warning-regex`. |
| 161 | +* Returns CRIT depending on the results of `--critical-pattern` or `--critical-regex`. |
| 162 | + |
| 163 | +Output on STDERR? |
| 164 | + |
| 165 | +* Depending on the given `--severity-stderr`, returns OK, WARN (default), CRIT or UNKNOWN if there is output on STDERR. |
| 166 | + |
| 167 | +Return code != 0? |
| 168 | + |
| 169 | +* Depending on the given `--severity-timeout`, returns OK, WARN, CRIT or UNKNOWN (default) if SSH can't connect. |
| 170 | +* Depending on the given `--severity-retc`, returns OK, WARN (default), CRIT or UNKNOWN if there is a return code != 0. |
| 171 | + |
| 172 | + |
| 173 | +## Perfdata / Metrics |
| 174 | + |
| 175 | +| Name | Type | Description | |
| 176 | +|----|----|----| |
| 177 | +| remote_runtime | Seconds | Time connecting, running the command on the remote host and disconnecting. | |
| 178 | + |
| 179 | + |
| 180 | +## Credits, License |
| 181 | + |
| 182 | +* Authors: [Linuxfabrik GmbH, Zurich](https://www.linuxfabrik.ch); originally written by Dominik Riva, Universitätsspital Basel/Switzerland |
| 183 | +* License: The Unlicense, see [LICENSE file](https://unlicense.org/). |
0 commit comments