CloudWatch で Windows のプロセス監視をする準備に役立つかも知れない PowerShell コマンド

CloudWatch で Windows のプロセス監視したいときに役立つかも知れません。
2020.07.07

哈喽大家好、コンサルティング部の西野です。

弊社の柴田による上記ブログでも解説されているように、CloudWatch Agent の Procstat プラグインを利用することで Windows のプロセス監視ができます。

exeセクションまたはpatternセクションにおいて正しくプロセス名やコマンドラインを指定できているか確認する際、コンフィグの作成 → CloudWatch Agent への適用 → CloudWatch から見る というプロセスを毎回たどるのは少々面倒です。
(コンフィグ適用から CloudWatch のメトリクスとして現れるまでだいたい3-4分ほど要します。)

コンフィグ適用前にこれらの指定の正しさを確認する方法を試したので本ブログで紹介いたします。

LIKE Operator

Windows Serverにおいてはexeセクションまたはpatternセクションで指定した文字列が WMI クエリとして評価されるため、まずはこのクエリに用いられる LIKE Operator をおさえましょう。

Character Description
[ ] Any one character within the specified range ([a-f]) or set ([abcdef]).
^ Any one character not within the range ([^a-f]) or set ([^abcdef].)
% Any string of 0 (zero) or more characters. The following example finds all instances where "Win" is found anywhere in the class name: SELECT * FROM meta_class WHERE __Class LIKE "%Win%"
_ (underscore) Any one character. Any literal underscore used in the query string must be escaped by placing it inside [] (square brackets).

参考:LIKE Operator

PowerShellコマンド

監視対象の Windows Server もしくは検証用の環境で下記のコマンドを実行してください。
なお、検証は Windows Server 2016 (ami-0b9f653146e551eb6) で実施しています。

サービス一覧の取得

サービス(services.msc)から対象プロセスを探す際には下記のコマンドを使いましょう。

サービス名・名前(表示名)・状態・実行ファイルのパス(コマンドライン)を表示してくれます。

> Get-WmiObject win32_service | select Name, DisplayName, State, PathName
Name                                     DisplayName                                            State   PathName
----                                     -----------                                            -----   --------
AJRouter                                 AllJoyn Router Service                                 Stopped C:\Windows\system32\svchost.exe -k LocalServiceNetworkRestricted
ALG                                      Application Layer Gateway Service                      Stopped C:\Windows\System32\alg.exe
AmazonSSMAgent                           Amazon SSM Agent                                       Running "C:\Program Files\Amazon\SSM\amazon-ssm-agent.exe"
AppIDSvc                                 Application Identity                                   Stopped C:\Windows\system32\svchost.exe -k LocalServiceNetworkRestricted
(略)

プロセス名の指定を確かめる

> Get-WmiObject win32_process -filter "Name LIKE '<プロセス名>'" | select Name, ProcessId, CommandLine

<プロセス名> には監視対象のプロセス名を入力してください。select はお好みでどうぞ。

たとえば SSM Agent のプロセス監視を行いたい場合は下記のとおりです。

> Get-WmiObject win32_process -filter "Name LIKE 'amazon-ssm-agent.exe'" | select Name, ProcessId, CommandLine

Name                 ProcessId CommandLine
----                 --------- -----------
amazon-ssm-agent.exe      3048 "C:\Program Files\Amazon\SSM\amazon-ssm-agent.exe"

無事プロセスを表す行が出力されました。これを CloudWatch Agent のコンフィグに置き換えると下記のようになります。

{
    "metrics": {
        "metrics_collected": {
            "procstat": [
                {
                    "exe": "amazon-ssm-agent.exe",
                    "measurement": [
                        "pid_count"
                    ],
                    "metrics_collection_interval": 60
                }
            ]
        }
    }
}

Get-WmiObject コマンドで<プロセス名> として指定した部分をそのままexeセクションの部分に入れればOKです。

プロセス名にamazonを含むプロセスをすべて(単一のメトリクスで)監視したい場合は%amazon%のように%で囲ってあげればOKです。

> Get-WmiObject win32_process -filter "Name LIKE '%amazon%'" | select Name, ProcessId, CommandLine
Name                                      ProcessId CommandLine
----                                      --------- -----------
amazon-ssm-agent.exe                           3048 "C:\Program Files\Amazon\SSM\amazon-ssm-agent.exe"
amazon-cloudwatch-agent-config-wizard.exe      4788 "C:\Program Files\Amazon\AmazonCloudWatchAgent\amazon-cloudwatch-agent-config-wizard.exe"
start-amazon-cloudwatch-agent.exe              2856 "C:\Program Files\Amazon\AmazonCloudWatchAgent\start-amazon-cloudwatch-agent.exe"
amazon-cloudwatch-agent.exe                    3552 "C:\Program Files\Amazon\AmazonCloudWatchAgent\\amazon-cloudwatch-agent.exe" -config C:\ProgramData\Amazon\AmazonCloudWatchAgent\\amazon-cloudwatch-agent.toml

望み通りの出力であった場合(監視したいプロセスが上記の4つである場合)は先程の例と同様に下記のようなコンフィグを作ってあげればOKです。

{
    "metrics": {
        "metrics_collected": {
            "procstat": [
                {
                    "exe": "%amazon%",
                    "measurement": [
                        "pid_count"
                    ],
                    "metrics_collection_interval": 60
                }
            ]
        }
    }
}

コマンドラインの指定を確かめる

> Get-WmiObject win32_process -filter "CommandLine LIKE '<コマンドライン文字列>'" | select Name, CommandLine

プロセス名のケースと似ていますが、LIKEの手前がCommandLineに変わっています。同じく select はお好みでどうぞ。

サービス W3SVC および WAS の実体であるC:\Windows\system32\svchost.exe -k iissvcsを監視したい場合は以下のようにします。

> Get-WmiObject win32_process -filter "CommandLine LIKE 'C:\\Windows\\system32\\svchost.exe -k iissvcs'" | select Name, CommandLine

Name        CommandLine
----        -----------
svchost.exe C:\Windows\system32\svchost.exe -k iissvcs

狙ったコマンドラインが出力されたので、<コマンドライン文字列>をそのままコンフィグに持っていきましょう。バックスラッシュ(円マーク)のエスケープがされていないとうまく出力されない(CloudWatch Agent が監視対象としない)のでご注意ください。

{
    "metrics": {
        "metrics_collected": {
            "procstat": [
                {
                    "pattern": "C:\\Windows\\system32\\svchost.exe -k iissvcs",
                    "measurement": [
                        "pid_count"
                    ],
                    "metrics_collection_interval": 60
                }
            ]
        }
    }
}

やってみる

svchostを含むすべてのコマンドラインを監視したいとします。

まずは Get-WmiObject コマンドを使って監視対象のコマンドライン文字列を確かめましょう。
svchostを含むすべてのコマンドラインなので、%svchost%と指定します。

> Get-WmiObject win32_process -filter "CommandLine LIKE '%svchost%'" | select Name, CommandLine

Name        CommandLine
----        -----------
svchost.exe C:\Windows\system32\svchost.exe -k DcomLaunch
svchost.exe C:\Windows\system32\svchost.exe -k RPCSS
svchost.exe C:\Windows\system32\svchost.exe -k netsvcs
svchost.exe C:\Windows\System32\svchost.exe -k termsvcs
svchost.exe C:\Windows\System32\svchost.exe -k LocalSystemNetworkRestricted
svchost.exe C:\Windows\System32\svchost.exe -k LocalServiceNetworkRestricted
svchost.exe C:\Windows\system32\svchost.exe -k LocalService
svchost.exe C:\Windows\system32\svchost.exe -k LocalServiceNetworkRestricted
svchost.exe C:\Windows\system32\svchost.exe -k NetworkService
svchost.exe C:\Windows\system32\svchost.exe -k LocalServiceNoNetwork
svchost.exe C:\Windows\system32\svchost.exe -k appmodel
svchost.exe C:\Windows\System32\svchost.exe -k smbsvcs
svchost.exe C:\Windows\system32\svchost.exe -k UnistackSvcGroup
svchost.exe C:\Windows\system32\svchost.exe -k apphost
svchost.exe C:\Windows\system32\svchost.exe -k iissvcs
svchost.exe C:\Windows\system32\svchost.exe -k LocalServiceAndNoImpersonation

svchost.exe で動く各サービスが列挙されました。大丈夫そうです。

コマンドを下記のようにつなげてあげるとプロセス数をカウントできます。

> Get-WmiObject win32_process -filter "CommandLine LIKE '%svchost%'" | select Name, CommandLine |  Measure-Object | Format-List Count

Count : 16

上記のコマンド文字列をもとにコンフィグを作ります。Get-WmiObjectコマンドで指定した文字列を持ってくればいいだけです。

{
    "metrics": {
        "metrics_collected": {
            "procstat": [
                {
                    "pattern": "%svchost%",
                    "measurement": [
                        "pid_count"
                    ],
                    "metrics_collection_interval": 60
                }
            ]
        }
    }
}

当該コンフィグを対象 Windows Server の CloudWatch Agent に適用し、マネジメントコンソールから CloudWatch のメトリクスを確認してみます。

コマンドで見た Count と同じ値 (16) が確認できました。

終わりに

このブログがほんの少しでも世界を良くできれば嬉しいです。
コンサルティング部の西野(@xiyegen)がお送りしました。