Difference between revisions of "Windows Remote Management (WinRM)"

From Zenoss Wiki
Jump to: navigation, search
(Created page with "{{Article |Title=Windows Remote Management (WinRM) |Author=Hydruid |Abstract=If you've fought and lost the battle with WMI, never fear WinRM is here! |Cover image=Newsletter3-...")
(3 intermediate revisions by the same user not shown)
Line 3: Line 3:
 
|Author=Hydruid
 
|Author=Hydruid
 
|Abstract=If you've fought and lost the battle with WMI, never fear WinRM is here!
 
|Abstract=If you've fought and lost the battle with WMI, never fear WinRM is here!
|Cover image=Newsletter5-winrm-poewrshell.png
+
|Cover image=Newsletter3-command-data-plugin.jpeg
 
}}
 
}}
 
== Introduction ==
 
== Introduction ==
 
For years and many Zenoss versions, the default tool for monitoring Windows Servers was with WMI. WMI is awesome but has a tendency to stop working and cause gaps in graphs and monitoring. Luckily Microsoft released a different tool and now Zenoss can fully utilize it for more monitoring flexibility and reliability!
 
For years and many Zenoss versions, the default tool for monitoring Windows Servers was with WMI. WMI is awesome but has a tendency to stop working and cause gaps in graphs and monitoring. Luckily Microsoft released a different tool and now Zenoss can fully utilize it for more monitoring flexibility and reliability!
  
== Problem ==
+
== Create a Data Source ==
Unreliable metrics using WMI as the method for monitoring window servers performance counters. WMI seems to die without any reason or warning, but at least it does usually start working again.
+
With your Monitoring Template selected, click on the + (plus) icon in the top center of your interface. The Add Data Source window will appear. Enter a name for your data source, I suggest it be lowercase and one word. Choose "COMMAND" as the Type and click Submit. Double click on your new data source and make sure "Use SSH" is checked. If you do not choose this, the commands will be run locally on the collector assigned to the device that has the monitoring template bound to it.
  
== Approach ==
+
The Command Template field is where you may enter commands to run. Unfortunately, you can't just make a script, paste it in the Command Template field, and call it a day. There are occasional issues you will run into based upon how Zenoss interprets and runs the commands. The commands entered into the Command Template are run through [[http://docs.zope.org/zope2/zope2book/AppendixC.html#tales-overview TALES]] which requires certain characters to be escaped.
Implement the new 'Microsoft Windows' ZenPack, which uses WinRM, with a simple configuration.
+
  
== Goal ==
+
See below for details on different types of Command Templates.
Reliable metrics using WinRM.
+
  
== Results ==
+
== SSH ==
Insert graph pictures
+
SSH is often used for Linux-based devices, either standard servers or embedded. You will need to be familiar with creating [http://www.gnu.org/software/bash/ Bash] command and scripts.
  
== Summary and Future Work ==
+
=== Performance ===
This article covers a very simple configuration of WinRM to get you started. It is highly recommended to convert to using HTTPS so that the data is encrypted and not plain-text!
+
When creating a script, it is recommended to think about performance, especially if it will be bound to many devices and polled often. Try to avoid using pipes and [http://mywiki.wooledge.org/SubShell SubShells].
  
== Acknowledgements ==
+
For example, the following code uses two pipes and two subshells to extract data out of an output:
Lets give a big hand to the Zenoss engineers for making this change and making Zenoss a better product on a day to day basis!
+
<syntaxhighlight lang="bash">
 +
month=$(date -d "$D" '+%b'); day=$(date -d "$D" '+%d'); count=$(fgrep "pf::person" /usr/local/pf/logs/packetfence.log | grep "$month $day" | wc -l); echo "OK|count=$count)";
 +
</syntaxhighlight>
  
 +
The same output can be achieved with the following code, utilizing no pipes and subshells:
 
<syntaxhighlight lang="bash">
 
<syntaxhighlight lang="bash">
echo "EPIC CODE INPUT"
+
month=$(date -d "$D" '+%b'); day=$(date -d "$D" '+%d'); count=$(grep -c "$month $day .*INFO.*pf::person" /usr/local/pf/logs/packetfence.log); printf "OK|count=%d" "$count";
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
 +
In a similar example the following code uses a pipe and subshell to not pass data into a command:
 +
<syntaxhighlight lang="bash">
 +
echo "Message-Authenticator = 0x00, FreeRADIUS-Statistics-Type= 1" | /usr/local/bin/radclient localhost:18120 status adminsecret
 +
</syntaxhighlight>
 +
 +
Here is the same command embedded into some additional code to extract data from the output. Note the use of <<< to pass a string into a command instead of the "echo |" and < <() to pass a set of commands into another:
 +
<syntaxhighlight lang="bash">
 +
i=1; while [[ $i -le 2 ]]; do while IFS= read -r; do [[ $REPLY = [[:space:]]* ]] && _temp=${REPLY#*-*-*} name=${_temp%[[:space:]]=*} name=${name//-} values+="$(tr '[A-Z]' '[a-z]' <<< "$name")=${_temp#*=[[:space:]]} "; done < <(radclient localhost:18120 status adminsecret <<< "Message-Authenticator = 0x00, FreeRADIUS-Statistics-Type = $i"); let ++i; done; printf "OK|$values";
 +
</syntaxhighlight>
 +
 +
=== Portability ===
 +
You must also consider portability between different *nix systems. One of those ways is to use generic tools available to you instead of specific applications that may not be on all devices. An example of this is the use of "printf" over "echo". For former is considered more portable, and preferred by bash scripters. See the following examples again and note the change.
 +
 +
From echo:
 +
<syntaxhighlight lang="bash">
 +
month=$(date -d "$D" '+%b'); day=$(date -d "$D" '+%d'); count=$(fgrep "pf::person" /usr/local/pf/logs/packetfence.log | grep "$month $day" | wc -l); echo "OK|count=$count)";
 +
</syntaxhighlight>
 +
 +
To printf:
 +
<syntaxhighlight lang="bash">
 +
month=$(date -d "$D" '+%b'); day=$(date -d "$D" '+%d'); count=$(grep -c "$month $day .*INFO.*pf::person" /usr/local/pf/logs/packetfence.log); printf "OK|count=%d" "$count";
 +
</syntaxhighlight>
 +
 +
Additionally, you may have issues with commands executing properly, giving you events in /Cmd/Fail, when they execute fine manually. Take note not just of the TALES issues below, but that commands seem to be running in an environment that does not have all the proper environment (PATH) variables set. It is prudent to execute commands using "bash -c" to get around this issue.
 +
 +
For example, the following:
 +
<syntaxhighlight lang="bash">
 +
month=$(date -d "$D" '+%b'); day=$(date -d "$D" '+%d'); count=$(grep -c "$month $day .*INFO.*pf::person" /usr/local/pf/logs/packetfence.log); printf "OK|count=%d" "$count";
 +
</syntaxhighlight>
 +
 +
Would become:
 +
<syntaxhighlight lang="bash">
 +
bash -c month=$(date -d "$D" '+%b'); day=$(date -d "$D" '+%d'); count=$(grep -c "$month $day .*INFO.*pf::person" /usr/local/pf/logs/packetfence.log); printf "OK|count=%d" "$count";
 +
</syntaxhighlight>
 +
 +
=== Escaping TALES ===
 +
One of the caveats to look out for when entering bash commands into the Command Template is its use of TALES. TALES will occasionally get in the way when trying to interpret your commands, generating events for failed TALES expressions. One of the most common issues is variables. TALES strips the first $ from each use in your code it sees, so to get around that you can escape it, by doubling the $.
 +
 +
The following:
 +
<syntaxhighlight lang="bash">
 +
month=$(date -d "$D" '+%b'); day=$(date -d "$D" '+%d'); count=$(grep -c "$month $day .*INFO.*pf::person" /usr/local/pf/logs/packetfence.log); printf "OK|count=%d" "$count";
 +
</syntaxhighlight>
 +
 +
Becomes:
 +
<syntaxhighlight lang="bash">
 +
month=$$(date -d "$$D" '+%b'); day=$$(date -d "$$D" '+%d'); count=$$(grep -c "$$month $$day .*INFO.*pf::person" /usr/local/pf/logs/packetfence.log); printf "OK|count=%d" "$$count";
 +
</syntaxhighlight>
 +
 +
=== Proper Output ===
 +
When creating output for data points, use the following method as noted in the prior examples: "OK|dp1=12345 dp2=abcde dp3=12ab34cd" and so on. The "OK" tells Zenoss the command executed successfully, and the pipe tells it that data points are coming, defined as "datapointname=<data>". Each data point should then be created under your data source.
 
{{ArticleFooter}}
 
{{ArticleFooter}}

Revision as of 14:18, 6 June 2014

Windows Remote Management (WinRM)

If you've fought and lost the battle with WMI, never fear WinRM is here!
Newsletter3-command-data-plugin.jpeg

Introduction

For years and many Zenoss versions, the default tool for monitoring Windows Servers was with WMI. WMI is awesome but has a tendency to stop working and cause gaps in graphs and monitoring. Luckily Microsoft released a different tool and now Zenoss can fully utilize it for more monitoring flexibility and reliability!

Create a Data Source

With your Monitoring Template selected, click on the + (plus) icon in the top center of your interface. The Add Data Source window will appear. Enter a name for your data source, I suggest it be lowercase and one word. Choose "COMMAND" as the Type and click Submit. Double click on your new data source and make sure "Use SSH" is checked. If you do not choose this, the commands will be run locally on the collector assigned to the device that has the monitoring template bound to it.

The Command Template field is where you may enter commands to run. Unfortunately, you can't just make a script, paste it in the Command Template field, and call it a day. There are occasional issues you will run into based upon how Zenoss interprets and runs the commands. The commands entered into the Command Template are run through [TALES] which requires certain characters to be escaped.

See below for details on different types of Command Templates.

SSH

SSH is often used for Linux-based devices, either standard servers or embedded. You will need to be familiar with creating Bash command and scripts.

Performance

When creating a script, it is recommended to think about performance, especially if it will be bound to many devices and polled often. Try to avoid using pipes and SubShells.

For example, the following code uses two pipes and two subshells to extract data out of an output:

month=$(date -d "$D" '+%b'); day=$(date -d "$D" '+%d'); count=$(fgrep "pf::person" /usr/local/pf/logs/packetfence.log | grep "$month $day" | wc -l); echo "OK|count=$count)";

The same output can be achieved with the following code, utilizing no pipes and subshells:

month=$(date -d "$D" '+%b'); day=$(date -d "$D" '+%d'); count=$(grep -c "$month $day .*INFO.*pf::person" /usr/local/pf/logs/packetfence.log); printf "OK|count=%d" "$count";

In a similar example the following code uses a pipe and subshell to not pass data into a command:

echo "Message-Authenticator = 0x00, FreeRADIUS-Statistics-Type= 1" | /usr/local/bin/radclient localhost:18120 status adminsecret

Here is the same command embedded into some additional code to extract data from the output. Note the use of <<< to pass a string into a command instead of the "echo |" and < <() to pass a set of commands into another:

i=1; while [[ $i -le 2 ]]; do while IFS= read -r; do [[ $REPLY = [[:space:]]* ]] && _temp=${REPLY#*-*-*} name=${_temp%[[:space:]]=*} name=${name//-} values+="$(tr '[A-Z]' '[a-z]' <<< "$name")=${_temp#*=[[:space:]]} "; done < <(radclient localhost:18120 status adminsecret <<< "Message-Authenticator = 0x00, FreeRADIUS-Statistics-Type = $i"); let ++i; done; printf "OK|$values";

Portability

You must also consider portability between different *nix systems. One of those ways is to use generic tools available to you instead of specific applications that may not be on all devices. An example of this is the use of "printf" over "echo". For former is considered more portable, and preferred by bash scripters. See the following examples again and note the change.

From echo:

month=$(date -d "$D" '+%b'); day=$(date -d "$D" '+%d'); count=$(fgrep "pf::person" /usr/local/pf/logs/packetfence.log | grep "$month $day" | wc -l); echo "OK|count=$count)";

To printf:

month=$(date -d "$D" '+%b'); day=$(date -d "$D" '+%d'); count=$(grep -c "$month $day .*INFO.*pf::person" /usr/local/pf/logs/packetfence.log); printf "OK|count=%d" "$count";

Additionally, you may have issues with commands executing properly, giving you events in /Cmd/Fail, when they execute fine manually. Take note not just of the TALES issues below, but that commands seem to be running in an environment that does not have all the proper environment (PATH) variables set. It is prudent to execute commands using "bash -c" to get around this issue.

For example, the following:

month=$(date -d "$D" '+%b'); day=$(date -d "$D" '+%d'); count=$(grep -c "$month $day .*INFO.*pf::person" /usr/local/pf/logs/packetfence.log); printf "OK|count=%d" "$count";

Would become:

bash -c month=$(date -d "$D" '+%b'); day=$(date -d "$D" '+%d'); count=$(grep -c "$month $day .*INFO.*pf::person" /usr/local/pf/logs/packetfence.log); printf "OK|count=%d" "$count";

Escaping TALES

One of the caveats to look out for when entering bash commands into the Command Template is its use of TALES. TALES will occasionally get in the way when trying to interpret your commands, generating events for failed TALES expressions. One of the most common issues is variables. TALES strips the first $ from each use in your code it sees, so to get around that you can escape it, by doubling the $.

The following:

month=$(date -d "$D" '+%b'); day=$(date -d "$D" '+%d'); count=$(grep -c "$month $day .*INFO.*pf::person" /usr/local/pf/logs/packetfence.log); printf "OK|count=%d" "$count";

Becomes:

month=$$(date -d "$$D" '+%b'); day=$$(date -d "$$D" '+%d'); count=$$(grep -c "$$month $$day .*INFO.*pf::person" /usr/local/pf/logs/packetfence.log); printf "OK|count=%d" "$$count";

Proper Output

When creating output for data points, use the following method as noted in the prior examples: "OK|dp1=12345 dp2=abcde dp3=12ab34cd" and so on. The "OK" tells Zenoss the command executed successfully, and the pipe tells it that data points are coming, defined as "datapointname=". Each data point should then be created under your data source.