Hey, Scripting Guy!

Scripting Guys が皆さんの質問にお答えします

Hey, Scripting Guy!

TechNet コラムへようこそ。このコラムでは、よく寄せられるシステム管理スクリプトに関する質問に Scripting Guys がお答えします。システム管理スクリプトについて質問がある場合は、scripter@microsoft.com (英語のみ) までお送りください。すべての質問に回答することはできないかもしれませんが、可能な限り対応いたします。

詳細情報

Hey, Scripting Guy! カテゴリ別アーカイブ

Hey, Scripting Guy! 日付別アーカイブ

Hey, Scripting Guy! ダウンロード

Spacer

*

ファイルが変更されたかどうかを 30 分おきに確認する方法はありますか

Hey, Scripting Guy! Question

Scripting Guy さん、よろしくお願いします。アプリケーションのログ ファイルを監視して、そのファイルのタイムスタンプがこの 30 分間に変更されなかった場合に警告メッセージを表示する方法はありますか。

-- JA

SpacerHey, Scripting Guy! AnswerScript Center

JA さん、こんにちは。非常に興味深い質問ですね。それに・・・。あれ、ちょっと待ってください。ワシントン州スタンウッド在住の JA さんじゃないですよね。本当ですか。わかりました、あなたの言うことを信じて、ご質問にお答えしましょう。でも、もし、あなたがワシントン州スタンウッド在住の JA さんだったら・・・。

念のために言っておきますが、このコラムを執筆している Scripting Guy はワシントン州スタンウッドに恨みがあるわけではありません。ただ、ワシントン州スタンウッドに文句があるのです。先日、この Scripting Guy は、少しの間、スタンウッドで暇つぶしをすることになりました。というのも、息子が Skagit Sox とのダブルヘッダーの試合の 90 分ほど前に町に着いている必要があったためです。Scripting Guy は、予定より仕事が遅れている中、スタンウッドに時間どおりに到着するために、正午にオフィスをこっそり抜け出してきました。そんな Scripting Guy にとって、その 90 分の空き時間はありがたいものでした。試合が始まる前にアイスクリームを食べに行くのにちょうど良い時間です。

と思いきや、ここで 1 つアドバイスです。もしワシントン州スタンウッドに行くことがあっても、アイスクリームは探しに行かない方が賢明です。スタンウッドにはアイスクリームがないのです。一見したところ十分な空き時間があったので、Scripting Guy は、小売店やレストランがいっぱい入った近くのショッピング センターに行きました。しかし、なんと、どのお店にもアイスクリームはありませんでした (つまり、ホット ファッジ サンデーなどの "本物" のアイスクリームです)。途中で、Scripting Guy は "アイスクリーム" と書かれた大きな看板を見つけましたが、近くまで行ってみると、その店舗はしっかりと戸締りがされていました。

: アイスクリーム屋は廃業したのでしょうか。それとも、この Scripting Guy が向かってくるのを見て、戸を閉め、ブラインドを下ろしただけでしょうか。良い質問です・・・。

結局、Scripting Guy は昔ながらのホット ファッジ サンデーを探すのを諦めて、マクドナルドでアイスクリームを買うことにしました。「ええと、アイスクリームですか」と女性の店員が言いました。そして、「アイスクリームはすべて売り切れとなっています」と続けました。

そうですか・・・。

最終的に、このコラムを執筆している Scripting Guy はアイスクリームを食べることができず、息子とそのチームもダブルヘッダーの両試合で負けてしまいました。偶然でしょうか。いいえ、そうは思いません。

まあ、良い知らせと悪い知らせが多くある人生のしくみの上では、これは悪い知らせです。良い知らせは何かというと、このコラムを執筆している Scripting Guy は、ホット ファッジ サンデーを食べて暇をつぶすことができなかったため、まったく予定していなかった作業を遂行できたことです。それは、このコラムの執筆です。

ご想像のとおり、ログ ファイルを監視し、そのファイルのタイムスタンプがこの 30 分間に変更されなかった場合に警告メッセージを表示するという課題のアプローチ方法は、数多く存在します。Scripting Guys が、そうしたすべての選択肢を入念に考慮して、この作業を実行するための最良の方法を選んだと考えられるでしょうか。とんでもありません。ただし、この作業を実行するのに最も簡単な方法を選んだことは確かです。

strComputer = "."

Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

Set colFiles = objWMIService.ExecQuery _
    ("Select * from CIM_Datafile Where Name = 'C:\\Scripts\\Application.log'")

For Each objFile in colFiles
    strOriginalTimestamp = objFile.LastModified
Next

Wscript.Echo "Monitoring application log file: " & Now
Wscript.Echo

Do While True
    Wscript.Sleep 1800000
    Set colFiles = objWMIService.ExecQuery _
        ("Select * from CIM_Datafile Where Name = 'C:\\Scripts\\Application.log'")

    For Each objFile in colFiles
        strLatestTimestamp = objFile.LastModified
    Next 

    If strLatestTimestamp <> strOriginalTimestamp Then
        strOriginalTimestamp = strLatestTimeStamp
    Else
        Wscript.Echo "ALERT: " & Now
        Wscript.Echo "The application log file has not been modified in the last 30 minutes."
        Wscript.Echo
        strOriginalTimestamp = strLatestTimeStamp
    End If
Loop

このスクリプトが機能するしくみをご説明しましょう。まず、ローカル コンピュータの WMI サービスに接続します。この作業を実行するのに WMI を使用するか、FileSystemObject などの別のテクノロジを使用するかというのが、最初に決定する必要がある事項の 1 つでした。WMI を使用することにしたのは、単純な理由からです。WMI を使用することで、ローカル コンピュータのログ ファイルの監視と同じくらい簡単に、リモート コンピュータのログ ファイルを監視できるスクリプトを作成できます。この作業をリモート コンピュータ atl-fs-01 のログ ファイルに対して実行する必要がある場合も、問題ありません。必要なのは、そのコンピュータの名前を strComputer 変数に代入するだけです。

strComputer = "atl-fs-01"

次に、ファイルが最後に変更された時間を特定します。ファイルの LastModified プロパティの現在の値を確認して、その値 (つまり、ファイル自体) がこの 30 分間に変更されたかどうかを知る必要があります。これを念頭に置き、次のコード行を使用して、Name プロパティの値 (パス) が C:\\Scripts\\Application.log に設定されている CIM_Datafile クラスのインスタンスをすべて選択します。

Set colFiles = objWMIService.ExecQuery _
    ("Select * from CIM_Datafile Where Name = 'C:\\Scripts\\Application.log'")

はい、そうです、C:\\Scripts\\ です。\ は WMI の予約文字なので、WQL クエリ内で使用するすべての \ はエスケープする必要があります。つまり、各 \ の前に \ を追加する必要があります。

確かに少し奇妙です。しかし、アイスクリームがまったくない町の奇妙さと比べれば、たいしたことありません。

接続を確立したら、クエリで返されたファイルのコレクションをループ処理する For Each ループを設定します (言うまでもなく、当該のファイルはコレクション内に 1 つだけしか存在しません)。続いて、次のコード行を使用して、LastModified プロパティの値を strOriginalTimestamp という名前の変数に代入します。

strOriginalTimestamp = objFile.LastModified

以上のすべての処理は、出発点を設定するために必要なもので、ここからが本題の処理です。そのために、無期限に (または、少なくとも True が True である間) 実行する Do While ループを設定します。

Do While True

ループでは最初に何をするかというと、ある意味では何の処理も行いません。このループで最初に行う処理は、Sleep メソッドを呼び出して、スクリプトを 30 分間停止することです。

Wscript.Sleep 1800000

: ご参考までに、1800000 は 1,800,000 ミリ秒を表します。1 秒が 1,000 ミリ秒、1 分が 60,000 ミリ秒で、30 分では 1,800,000 ミリ秒 (1,000 x 60 x 30) です。

30 分経過したら、ログ ファイルの LastModified プロパティの現在の値を確認します。それには、ファイルに再接続してから、LastModified プロパティの値を strLatestTimestamp という名前の変数に格納します。

strLatestTimestamp = objFile.LastModified

では、次の行に移りましょう。

If strLatestTimestamp <> strOriginalTimestamp Then

ここで行っている処理は何でしょうか。ここでは、元のタイムスタンプを現在のタイムスタンプと比較しています。その 2 つのタイムスタンプが異なるとしたら、それはどういうことでしょうか。それが意味することはたった 1 つです。ファイルが、この 30 分間のどこかで変更されたということです。したがって、現在のタイムスタンプ (strLatestTimestamp) を strOriginalTimestamp 変数に代入して、ループ処理の先頭に戻り、スクリプトをもう 30 分間停止してから、この確認を再び実行します。

簡単でしたね。では、2 つのタイムスタンプが同じ場合はどうでしょうか。ここでも、それが意味することはたった 1 つです。2 つのタイムスタンプが同じ場合は、この 30 分間にファイルが変更されなかったということです。この場合は、次のコード行を使用して、メッセージをコマンド ウィンドウにエコー バックします (そしてもちろん、ほとんどの監視スクリプトと同様に、CScript スクリプト ホストを使用したコマンド ウィンドウでこのスクリプトを実行することをお勧めします)。

Wscript.Echo "ALERT: " & Now
Wscript.Echo "The application log file has not been modified in the last 30 minutes."
Wscript.Echo

そうすると、次のようなメッセージが画面上に表示されます。

ALERT: 7/20/2007 1:26:35 PM
The application log file has not been modified in the last 30 minutes.

次に、現在のタイムスタンプを strOriginalTimestamp 変数に代入して、ループ処理の先頭に戻り、スクリプトをもう 30 分間停止してから、再び確認を実行します。この処理は、時間の終わり、またはスクリプトを終了するかコマンド ウィンドウを閉じるまで続行します。

いずれか早い方までです。これは、どちらも、スタンウッドでアイスクリームが見つかるよりもかなり前に発生すると推測されます。

言うまでもなく、警告メッセージをエコー バックすることにとどまりません。必要ならば電子メールを送信したり、イベント ログにイベントを書き込んだりするなど、ほとんど何でも実行できます。それは、皆さんにお任せします。

これでご質問の回答になっているとよいのですが、JA さん。もしあなたが本当はワシントン州スタンウッド在住の JA さんだったら、きっともう 1 つ疑問をお持ちでしょう。このコラムを執筆している Scripting Guy が、あなたの町でアイスクリームを見つけられなかったという理由だけであなたのことを恨んでいるのか、という疑問です。JA さんが口にしなかった疑問への答えはこうです。もちろん、そうでしょう。でも心配はいりません。次の住所にホット ファッジ サンデーをお送りください。それで良しとしましょう。

The Scripting Guy Who Writes That Column
Microsoft Corporation
Building 42/4039
Redmond, WA 98052

追伸 : ホイップ クリーム追加、マラスキノ チェリー抜きでお願いします。


ページのトップへページのトップへ