Zabbixからエージェントレスでwindowsを監視する

この記事は [Zabbix Advent Calendar 2016](http://qiita.com/advent-calendar/2016/zabbix) の14日目です。

前回の記事は [rerar](http://qiita.com/rerar)さんの「[ZabbixでLXC Containerを監視する](https://luispc.com/memo/zabbix/2016/12/13/8770)」でした。


今回は「Zabbixからエージェントレスでwindowを監視する」方法を紹介します。

通常、Zabbixでは監視対象のサーバにZabbixエージェントをインストールして運用するスタイルが一般的ですが、
監視対象によっては追加でエージェントの導入できない（または、しづらい）ということがあります。本来ならZabbixエージェントを導入した監視が望ましいのですが、それが出来ないケースで今回の方法は有用かと思います。

監視対象のサーバはWindows7です。
Windows7をホストPCとして Virtualbox上にZabbixサーバ(CentOS' 64bit)を構築し、ホストPC(Windows7)を監視します。

# 環境

- 仮想化ソフトウェア Virtualbox
- ホストPC Windows7
- ゲストPC1 centOS7 64bit (Zabbix サーバ)
- ゲストPC2 Windows10 Insider Preview
- Zabbix 3.2

# WMI(Windows Management Instrumentation)

WindowsではWMIを介して各種の情報や管理が可能です。以下、[Technet - Microsoft](https://technet.microsoft.com/ja-jp/scriptcenter/ff576025.aspx#1) の「 Q 1. WMI はどのようなツールで、どのような機能を提供しますか。」からの抜粋です。

```

WMI (Windows Management Instrumentation) の Instrumentation という単語は "計器" や "計器による測定" を意味します。ちょうど自
動車の計器類がエンジンに関する情報を示すように、WMI はコンピュータ システムの内部状態に関する情報を示します。WMI では、Windows シ
ステム内に検出されたディスクやプロセスなどのオブジェクトをモデリングすることにより、"計器情報" を提供します。WMI によるシステム 
オブジェクトのモデリングには、Win32_LogicalDisk や Win32_Process などのクラスが使用されます。クラス名から推察できるように、
Win32_LogicalDisk はコンピュータ上の論理ディスクをモデリングするクラス、Win32_Process はコンピュータ上で現在稼動している任意の
プロセスをモデリングするクラスです。 - 省略 - 

```

このWMIを利用して監視対象のWindowsサーバから監視データを取得します。

# Zabbix サーバのセットアップ

Zabbix サーバのセットアップは,

[qryuu](http://qiita.com/qryuu)さんの[Zabbix Advent Calendar 2016の10日目の記事](http://blog.serverworks.co.jp/tech/2016/12/10/zabbixinstall/)を参考にZabbixサーバをセットアップして下さい。

今回は以下を構築しました。

- OS Centos7 64bit
- DB mysql-community-server-5.7.17-1.el7.x86_64

## WMIクライアントのインストール

atomic社のリポジトリを登録し、wmiをインストールします。

```
rpm -Uvh http://www6.atomicorp.com/channels/atomic/centos/7/x86_64/RPMS/atomic-release-1.0-19.el7.art.noarch.rpm
yum install wmi
```

## wmicコマンドのテスト

wmiのインストールが終了すると wmic コマンドが使用可能になります。

wmic(wmiクライアント)がホストPCのWindows7から情報を取得できるか確認します。

コマンドサンプル

```
# wmic -U <ドメイン>/<ユーザー>%<パスワード> //<IP アドレス> "<WQL>"
wmic -U yasu%yasuhiro //192.168.56.1 "select * from Win32_OperatingSystem"

```

以下はWin32_OperatingSystemのデータ出力例です。

wmicではWQL(WMI Query Language)とよばれるSQLに似た構文でデータを取得します。

fromで指定するクラスには [WMI Fun!!](http://www.wmifun.net/) の [WMI Library](http://www.wmifun.net/library/) が参考になります。

はじめの一行にFrom句の対象クラス名が、次に行にヘッダー行が出力されます。
それ以降はデータ行です。

```
CLASS: Win32_OperatingSystem
BootDevice|BuildNumber|BuildType|Caption|CodeSet|CountryCode|CreationClassName|CSCreationClassName|CSDVersion|CSName|CurrentTimeZone|DataExecutionPrevention_32BitApplications|DataExecutionPrevention_Available|DataExecutionPrevention_Drivers|DataExecutionPrevention_SupportPolicy|Debug|Description|Distributed|EncryptionLevel|ForegroundApplicationBoost|FreePhysicalMemory|FreeSpaceInPagingFiles|FreeVirtualMemory|InstallDate|LargeSystemCache|LastBootUpTime|LocalDateTime|Locale|Manufacturer|MaxNumberOfProcesses|MaxProcessMemorySize|MUILanguages|Name|NumberOfLicensedUsers|NumberOfProcesses|NumberOfUsers|OperatingSystemSKU|Organization|OSArchitecture|OSLanguage|OSProductSuite|OSType|OtherTypeDescription|PAEEnabled|PlusProductID|PlusVersionNumber|Primary|ProductType|RegisteredUser|SerialNumber|ServicePackMajorVersion|ServicePackMinorVersion|SizeStoredInPagingFiles|Status|SuiteMask|SystemDevice|SystemDirectory|SystemDrive|TotalSwapSpaceSize|TotalVirtualMemorySize|TotalVisibleMemorySize|Version|WindowsDirectory

# データ省力
```

wmicコマンドによるデータの取得が出来ない場合は、Windows側で、コントロール パネル\システムとセキュリティ\Windows ファイアウォール からWindows ファイアーウォールを無効化するか、詳細設定の受信の規則から「Windows Management Instrumentation (WMI 受信)を有効化して下さい。
（CentOS7側でのfirewalldやルーティング設定に誤りがある場合もあります。）

### Windows10 Insider Preview

Windows10 Insider Previewでは

- ファイアーウォールの停止、もしくはファイアーウォール側での受信規則からWMIの許可をする

- Administrator アカウントを使用する、または「管理者承認モード」を無効化して Administratorsグループのユーザーでwmicコマンドを実行する。

ことでデータが取得できました。　

[参考: 大将のネタ帳-AdministratorとAdministratorsグループの違い](https://www.wareportal.co.jp/jm/mainmenu/117-administrator-administrators.html)

## CPU使用率を取得するPerlプログラム

それでは、zabbixからデータを取得できるようにしていきます。

wmicコマンドをPerlから呼び出しCPU使用率を返すスクリプトを作成します。

(以下の内容を wmi_cpu_rate.pl として作成)

```pl

#!/usr/bin/env perl
use strict;
use warnings;

my $host = $ARGV[0];
die "usage wmi_drive.pl <IP> <USER> <PASSWORD>" unless defined $host;

my $txt = wmi(
    host=>$host,
    user=> $ARGV[1] || 'yasu',
    password=> $ARGV[2] || 'yasuhiro',
    #delimiter=>'',
    sql=>'select LoadPercentage from Win32_Processor'
    );

# エラー処理: 値が取得できない場合に -1 
print '-1' and exit(1) if ( $txt eq '' || $txt =~ /ERROR/ );

my @data = split("\n", $txt);

my $class = shift @data;
my @fields = split("\|", shift @data);

my @output = split('\|', shift @data);

print $output[1];

sub wmi {
  my $args = {@_};
  croak("You must provide host") unless defined $args->{host};
  croak("You must provide password") unless defined $args->{password};
  croak("You must provide user") unless defined $args->{user};
  croak("You must provide sql") unless defined $args->{sql};

  my $domain = $args->{domain} || 'localhost';
  my $user = $args->{user};
  my $password = $args->{password};
  my $sql = $args->{sql};
  my $host = $args->{host};
  my $command = "wmic -U $domain/$user%$password //$host ".'"'.$sql.'"';
 
  # debug
  print $command, "\n" if defined $args->{debug};

  my $txt = `$command`;
  return $txt;
}

```

作成したスクリプト(wmi_cpu_rate.pl)に実行権限を付与し、Zabbixサーバから外部スクリプトとして参照可能な場所に配置します。

```
chmod +x wmi_cpu_rate.pl
mv wmi_cpu_rate.pl /usr/lib/zabbix/externalscripts/
```

今回はPerlを利用していますが、wmicコマンドの出力を加工しているだけですので、シェルスクリプトやpython、ruby, nodejs等の他言語で作成してもいいかと思います。

# Zabbixへ監視対象サーバの登録

## 監視ホストの登録
Zabbixのウェブ画面から監視対象のWindows7を登録します。


### Windows7の登録

Zabbixのウェブ画面から監視対象のWindows7を登録します。

![image](https://qiita-image-store.s3.amazonaws.com/0/55033/bc83f8b1-68dd-2b59-c430-ca83596db98e.png)

「設定」- 「ホスト」から以下の情報を登録します。

- ホスト名 hostpc
- グループ windows
- IPアドレス 192.168.56.1

ホスト名は仮にhostpcとしていますが、任意の名前で設定して下さい。グループは最低1つに所属しないといけないで、
ここでは既に作成済みのwindowsグループを指定しています。
また IPアドレスは該当サーバのIPアドレスを指定します。


![image](https://qiita-image-store.s3.amazonaws.com/0/55033/40ecfc25-ffde-59e6-7505-d2c696dece44.png)

Windows10 Insider Previewに関しても同様に登録しました。

## 監視アイテムの登録

追加したホスト(hostpc)にアイテムを登録します。

アイテムは以下の項目を設定します。

- 名前 CPU使用率
- タイプ 外部チェック
- キー wmi_cpu_rate.pl[{HOST.CONN}, "yasu", "yasuhiro"]
- 単位 %

第一引数の{HOST.CONN}はマクロでスクリプト側にはホストのIPアドレスが渡されます。第二、第三引数はそれぞれユーザー名とパスワードです。

![image](https://qiita-image-store.s3.amazonaws.com/0/55033/7d510be7-117b-06c9-b92e-073a82163ccf.png)


追加後のイメージです。

![image](https://qiita-image-store.s3.amazonaws.com/0/55033/24e1d842-cfc7-9b80-5291-296c3684d7d9.png)


## 監視データの確認

ここまでの作業でzabbix側からCPU情報を取得できるようなりました。
監視データの最新データから以下のようにグラフが確認できます。

![image](https://qiita-image-store.s3.amazonaws.com/0/55033/f03cccd5-e8bf-3dae-cc48-2d0b7d394ad9.png)


今回は CPU情報の取得のみでしたが、プロセス情報も同様にWMIを利用して取得できます。
この取得データに対してトリガー設定を追加することで「ZabbixからエージェントレスでWindowsを監視する」となります。




# [Zabbix Advent Calendar 2016](http://qiita.com/advent-calendar/2016/zabbix) 15日目は

次回は[tubeone](http://qiita.com/tubone)さんの「がんばるぞい！パブリックなVPSの監視経路について書きます」です。

# 元ネタ

最近気づいたのですが、既に書いている方がいました。
[完全にエージェントレスでWindowsサーバーを監視してみるテスト](http://www56.hatenablog.jp/entry/2014/12/11/002400)

# 編集履歴
2017/01/26 元ネタ追記
2016/12/15 Windows10の説明を追加、タイトルを修正