この記事は、Microsoft Operations Manager (MOM) でのスクリプト作成に関する 4 部構成シリーズの最終回です。このシリーズの目的は、MOM と Windows Script Host のスクリプトを比較し、Windows Script Host のスクリプトにこれまで蓄積された膨大な知識や資料を有効利用できるようにすることです。
MOM スクリプトの概念を Windows Script Host の概念と比較しながら説明し、2 つのスクリプトの共通オブジェクトおよび異なるオブジェクトを紹介します。ここでは、スクリプトからの出力データを MOM ワークフローに取得する方法を説明します。 | |
データを MOM スクリプトに取得する方法について説明します。パラメータの使い方や、スクリプトを起動する MOM オブジェクトから情報を取得する方法についても説明します。 | |
MOM でのスクリプトの作成およびデバッグの方法について説明します。この記事では、各種のエディタやユーティリティを使用してこれらの機能を実行する方法を説明します。 | |
第 4 部 – ベスト プラクティス | ベスト プラクティスを紹介し、次のような一般的な質問に答えます。MOM スクリプトのイベントに対してどのタイミングでアラートを生成すればよいか。MOM スクリプトがどの程度複雑になったら分割するべきか。セキュリティをどうしたらよいか。 |
このシリーズの 1 〜 3 部では、MOM スクリプトの概要を示し、スクリプトの作成を始めるための基礎的な情報を中心に扱いました。この最終回では、既に説明したメソッドを使用するためのベスト プラクティスと、このシリーズでまだ扱っていない高度なトピックについて説明します。
| イベントまたはアラートを作成する | |
| 小さいスクリプトと大きいスクリプト | |
| 状態変数 | |
| スクリプトを実行する場所 | |
| セキュリティ | |
| タイムアウトと同時実行 | |
| まとめ |
MOM でのスクリプトの最も一般的な使い方は、エージェント コンピュータ上の問題を識別し、アラートを生成することです。高レベルでは、この機能を実行するには 2 とおりの方法があります。それは、ScriptContext.CreateAlert を使用してスクリプトからアラートを直ちに発行する方法と、ScriptContext.CreateEvent を使用してスクリプトでイベントを生成し、ルールに依存してイベントを検知してアラートを生成する方法です。
より複雑なアプローチに見えるかもしれませんが、スクリプトでイベントを生成する方法をお勧めします。MOM 2000 の頃は、アラートの抑制がスクリプトから生成されたアラートに対して動作しなかったため、これは簡単な推奨事項でした。MOM 2005 ではこの制限が廃止されましたが、現在でもいくつかの理由でこの方法が推奨されています。
第一の理由は、スクリプトで実行されるロジックの量が限定されることです。この後の対象を絞った小さいスクリプトの維持に関するトピックで説明するように、スクリプトは必要以上に複雑にしないでください。スクリプトでは、必要なアクションの実行および必要なデータの収集だけを行い、データの解釈を試みずに検出内容を返す必要があります。
アラートを生成する場合は、収集したデータの結果を解釈します。まず第一に、アラートの生成を警告するほど重要な情報であるかどうかを判断し、次に、アラートに割り当てる重大度を決定します。MOM では通常、処理ルールによってデータの解釈が行われます。
最適な方法は、生成される可能性がある出力の種類ごとに、一意のイベント コードを持つイベントをスクリプトで作成することです。次に、処理ルールを作成して、各イベント コードを検知し、適切なアラートを生成します。ロジックが変更された場合でも、MOM の作成者は、スクリプトを変更せずにロジックを変更できます。スクリプトの変更と比較して、ルールは簡単に変更できるうえ、多くの企業ではスクリプトのためのリソースが制限されています。
この方法を使用するもう 1 つの理由は、スクリプトの柔軟性が高くなることです。たとえば、第 1 部では、ファイルのサイズをパフォーマンス データとして収集するスクリプトについて説明しました。このようなスクリプトは、特定のファイルが指定されたサイズを超過しているかどうかを調べる必要があるときに作成されます。この種のスクリプトの実装では、多くの場合、指定したサイズ (パラメータとして受け取ることが可能) とファイル サイズの値を照合し、サイズが超過した場合はアラートを直ちに生成します。この実装の問題は、スクリプトが特定のシナリオに固定されることです。アラートを生成するのではなく、イベントを生成するスクリプトを実装すれば、作成した簡単なスクリプトによって、ファイル サイズの追跡、特定のサイズを超過したファイルの報告、特定のサイズに満たないファイルの報告など、さまざまなシナリオに適用できます。数行のコードを追加すれば、ファイルが見つからないという報告も可能になります。微妙に異なる要件のために新しいスクリプトを作成するのとは対照的に、1 つのスクリプトをさまざまなシナリオで利用できます。図 1 に、この概念を示します。

図 1 - スクリプトからアラートを生成するための推奨された方法
要件が増加すると、スクリプトへの追加が継続的に行われることがよくあります。こうすると、複数のアクティビティを実行する長くて複雑なスクリプトになる傾向があります。長いスクリプトが特に問題になることはありません。MOM スクリプトのサイズ制限に突き当たる可能性はほとんどありません (MOM 2005 の場合)。前のトピックでも強調しているように、より考慮すべき要素は、MOM でのスクリプトの柔軟性です。
単一の MOM ルールに対して複数の応答を持つことが可能であり、これらの応答は連続して実行されます。単一の長いスクリプトではなく、次々に実行される複数の短いスクリプトを持つことができます。この方法の利点は、スクリプトを管理しやすい点と、他のルールで使用するための高い柔軟性が得られる点です。
第 2 部では、ユーザー アカウントを取得し、そのアカウントを無効にするスクリプトを作成しました。このスクリプトを拡張して、現在のユーザーをログオフすると便利であることも説明しました。既存のスクリプトを拡張するのではなく、現在のユーザーをログオフするだけのスクリプトを別途作成し、このスクリプトを同じルールに対する 2 番目の応答として起動したほうが効率が良くなります。
「Windows 2000 Scripting Guide」(英語) にある次のスクリプトでは、現在のコンピュータをシャットダウンしています。
Const SHUTDOWN = 1
strComputer = "."
Set objWMIService = GetObject("winmgmts: {(Shutdown)}" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colOperatingSystems = objWMIService.ExecQuery _
("SELECT * FROM Win32_OperatingSystem")
For Each objOperatingSystem in colOperatingSystems
ObjOperatingSystem.Win32Shutdown(SHUTDOWN)
Next
このスクリプトは、現在のユーザーをログオフするスクリプトに簡単に変更できます。最初に、Win32Shutdown メソッドに渡される定数を変更して、シャットダウンではなくログオフを実行する必要があります。また、ログオフのみを実行する場合は、GetObject モニカに対してシャットダウン特権を指定する必要がありません。これらの小さな変更を加えると、次のようなスクリプトになります。
Const SHUTDOWN = 1
Const FORCE_LOGOFF = 4
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colOperatingSystems = objWMIService.ExecQuery _
("SELECT * FROM Win32_OperatingSystem")
For Each objOperatingSystem in colOperatingSystems
ObjOperatingSystem.Win32Shutdown(FORCE_LOGOFF)
Next
このコードを "Disable a User (ユーザーの無効化)" スクリプトの末尾に貼り付けるのではなく、別個のスクリプトとして保存し、2 番目の応答として起動します。この方法を使用すれば、他のシナリオで現在のユーザーをログオフする必要が生じたとき、このスクリプトを再利用できます。
図 2 に、単一のルールから起動される 2 つのスクリプトを示します。

図 2 - 単一ルールからの複数のスクリプトの呼び出し
前のセクションの提案に従って小さいスクリプトを維持した場合に発生する 1 つの課題は、スクリプト間でのデータの受け渡しです。単一の処理ルールと共に複数のスクリプトを使用する場合、2 番目のスクリプトでは、最初のスクリプトで生成されたデータが必要になる場合があります。このようなケースでは、変数を自由に転送できるように、複数のスクリプトを単一のスクリプトに結合しようとする場合があります。それは、他のスクリプトの変数にアクセスできないと想定しているためですが、このアクセスは可能でしょうか。
MOM では、スクリプトの有効期間に制限が設けられています。スクリプトは、実行が終了すると、すべての変数がメモリから消去され、スクリプトで作成された MOM オブジェクト (イベント、アラート、およびパフォーマンス データ) 以外は、スクリプトを実行した形跡がすべて消去されます。後で同じスクリプトを再び実行する場合でも、前回の実行から情報を即座に取得できるような方法は準備されていません。シナリオによっては、1 つ以上の値を保存しておき、同じスクリプトを次回実行したときにアクセスしたり、別のスクリプトからアクセスできると便利な場合があります。幸運なことに、これを実現する方法があります。それは、状態変数を使用することです。
スクリプトの通常の変数は、スクリプトの実行が完了するとすぐにメモリから消去されますが、状態変数は、エージェントが実行されている期間中メモリに保存されています。状態変数は、ルールの応答またはスクリプトのどちらからでも作成および値の変更が可能ですが、状態変数の値を実際に使用できるのはスクリプトだけです。

図 3 - 状態変数
それでは、第 2 部の "Terminate a Process (プロセスの終了)" スクリプトを使用して、状態変数の中核的な概念と使用について説明します。たとえば、特定のプロセスが終了した回数を追跡することもできます。プロセスが終了した回数を状態変数に保存し、スクリプトを実行するたびに変数の値を 1 増加します。こうすると、イベントで数値を報告でき、実行カウントに基づいて異なった操作を実行することも可能になります。
状態変数は、変数セットになっています。変数セットの作成は、ScriptContext.GetScriptState を使用して Script State オブジェクトを作成することから始めます。次に、GetSet を使用して変数セットを作成し (既存の変数セットがある場合はそれを取得し、存在しない場合は作成する)、Get メソッドと Put メソッドを使用してセット内の各変数にアクセスします。それでは、この例のシナリオの各ステップを説明します。
次のコードは、この例の変数セットを作成します。他のスクリプトで使用する変数セットと明確に区別するために、スクリプトの名前を変数名として使用します。
strVarSetName = "Terminate A Process" Set objScriptState = ScriptContext.GetScriptState Set objVarSet = objScriptState.GetSet(strVarSetName)
変数セット オブジェクト (この例では objVarSet) が作成されたら、Get メソッドと Put メソッドを使用してセット内の状態変数を使用できます。この例では、指定したプロセスの検出および終了の回数を追跡します。プロセス名がベースになった変数名を作成すると便利です。スクリプト パラメータでプロセス名を指定できるように、第 2 部のスクリプトを変更しました。プロセス名を変数名として使用すれば、スクリプトを使用する可能性があるプロセスごとに、別個のカウントを確実に管理できます。実際の変数の作成については、考慮する必要がありません。変数が作成される前に Get を試みた場合は、Null 値が返され、計算式で 0 となります。初めて Put を実行したとき、変数が作成されます。
次のコードは、変数セット オブジェクトを使用して、プロセス名を使用した新しい状態変数を作成し、変数の値を 1 増加する方法を示しています。strProcessName は、状態変数の作成で使用されるプロセス名を保持します。
intCount = objVarSet.Get(strProcessName) intCount = intCount + 1 objVarSet.Put strProcessName,intCount
この状態変数は、エージェントが実行されている期間中、値を保持し続けます。コンピュータの再起動、または MOM エージェントの再起動によって、すべての状態変数が消去されます。その場合は、カウントが 0 にリセットされます。
それでは、この新しいコードを "Terminate a Process (プロセスの終了)" スクリプトに挿入しましょう。この例では、カウント値を単にイベント メッセージで使用するだけですが、この変数は、他の変数と同様、別のコードの起動やパフォーマンス データの保存にも使用できます。
Const EVENT_TYPE_SUCCESS = 0
Const EVENT_TYPE_ERROR = 1
Const EVENT_TYPE_WARNING = 2
Const EVENT_TYPE_INFORMATION = 4
Const EVENT_TYPE_AUDITSUCCESS = 8
Const EVENT_TYPE_AUDITFAILURE = 16
strProcessName = ScriptContext.Parameters.Get("ProcessName")
bolGenerateEvent = CBool(ScriptContext.Parameters.Get("GenerateEvent"))
strVarSetName = "Terminate A Process"
Set objScriptState = ScriptContext.GetScriptState
Set objVarSet = objScriptState.GetSet(strVarSetName)
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colProcessList = objWMIService.ExecQuery _
("Select * from Win32_Process Where Name = '" & strProcessName & "'")
For Each objProcess in colProcessList
objProcess.Terminate()
Next
intCount = objVarSet.Get(strProcessName)
intCount = intCount + 1
objVarSet.Put strProcessName,intCount
If bolGenerateEvent = True Then
CreateEvent 100,EVENT_TYPE_INFORMATION, "Process Monitoring", _
"Terminated " & colProcessList.Count & " instances of process " _
& strProcessName & "." & vbcrlf _
& "This process has been detected and terminated " _
& intCount & " number of times since the last restart. "
End If
Sub CreateEvent(intEventNumber,intEventType,strEventSource,strEventMessage)
Set objEvent = ScriptContext.CreateEvent()
objEvent.EventNumber = intEventNumber
objEvent.EventType = intEventType
objEvent.EventSource = strEventSource
objEvent.Message = strEventMessage
ScriptContext.Submit objEvent
End Sub
このスクリプトは、第 2 部で説明した方法とまったく同じように実行されます。このスクリプトの唯一の相違点は、プロセスごとにスクリプトの実行回数がカウントされることです。
この例のスクリプトは、以前に実行された同じスクリプトの変数にアクセスします。完全に異なるスクリプトがこのスクリプトの変数にアクセスする場合もコードの違いはありません。ただし、別のスクリプトの場合は、変数名とそれに含まれる状態変数セットを知っている必要があります。
状態変数はたいへん役立ちますが、使いすぎないようにしてください。一定期間内に何度も発生する特定イベントへの応答として単にアラートを発行するだけの場合は、統合イベント ルールの使用を検討してください。このルールを使用すると、より簡素化され、信頼性が向上し、ロジックがスクリプトではなくルールに配置されるため、前述の推奨事項にも適合します。
さらにもう 1 つの検討事項は、状態変数が存在するのはエージェントが実行中である期間のみに限定される点です。この期間を超えて存在する必要があるデータの場合は、レジストリやテキスト ファイルなどの代替の保存場所を指定する必要があります (これらのオプションは基本的に Windows Script Host の場合と同じ)。当然、イベントやパフォーマンス データなどの MOM オブジェクトに値を保存することも可能ですが、これらのオブジェクトは、エージェント上で実行中の後続のスクリプトからアクセスしやすいものではありません。SDK を使用してスクリプトから MOM オブジェクトにアクセスできますが、適切なオブジェクトを見つけるために管理サーバーへのアクセスが必要となり、通常ではローカル エージェント上の簡単なストレージ ソリューションとして効率的ではありません。
MOM ルールでスクリプトを実行する場合は、そのスクリプトをエージェント上で実行するか、管理サーバー上で実行するかを指定する必要があります (図 4 参照)。どちらを選択すればよいのでしょうか。コンピューティングの世界の多くの回答と同様に、それは状況次第です。

図 4 – スクリプトの実行場所
エージェント コンピュータ上でスクリプトを実行するという選択は、明らかに最も一般的なシナリオです。ローカル エージェントをインストールした場合の利点の 1 つは、ローカル アクションを実行できることです。集中化されたサービスでさまざまなリモート サーバーにアクセスするための権限が必要となるのとは対照的に、LocalSystem アカウントで実行できます。また、管理サーバー上で何百にも上る可能性があるクライアントに対してスクリプトを実行する必要がないため、管理されたコンピュータへのリモート アクセスに比べて、拡張性が飛躍的に向上します。さらに、大幅な帯域幅の節約にもなります。
ただし、状況によっては、管理サーバーでスクリプトを実行することもあります。たとえば、スクリプトを使用して、別のコンピュータからエージェント コンピュータに対してアクションを実行する場合があります。単にローカルでテストするだけでなく、管理サーバーを利用してネットワーク上でエージェント コンピュータに接続すれば、アプリケーション機能に加えてネットワーク インターフェイスもテストできます。
管理サーバー上でスクリプトを実行するもう 1 つの例は、特定の事象に応答して、別のサーバーまたはネットワーク デバイスに対してスクリプトの実行を開始する必要がある場合です。たとえば、外部デバイス上で起こり得る問題についてのアラートがサーバー上で生成されることがあります。詳細な分析を実行できるスクリプトがある場合でも、ドメインの資格情報なしではこのデバイスにアクセスできません。簡単な解決策は、アラートに応答してこのスクリプトを起動することですが、この場合は管理サーバーをスクリプトの実行場所として指定して、管理サーバー アクション アカウントを使用します。これは通常ではドメイン アカウントであり、必要な操作を実行するのに十分な特権を持ちます。セキュリティについては、この後で詳しく説明します。
エージェントレス コンピュータ上のスクリプト
エージェントレス コンピュータを使用すると、そのコンピュータに対して実行されるすべてのスクリプトが管理サーバー上で実行されます。このシナリオにエージェントが存在しないため、エージェント上でスクリプトが実行されない理由は明白です。使用する環境で、エージェントレス コンピュータを使用してスクリプトを実行する場合は、いくかの点に考慮する必要があります。通常では、ローカル コンピュータに対してスクリプトが実行され、すべてのローカル リソースにアクセスできることが前提となっています。ただし、エージェントレス コンピュータに対してスクリプトを実行する場合は、スクリプトが実行される管理サーバーのローカル リソースとなります。
スクリプトがエージェントレス コンピュータに対して実行されるかどうかを確認するには、この機能にふさわしい名前を持つ ScriptContext の IsTargetAgentless プロパティを使用します。スクリプトの対象コンピュータがエージェントレスの場合は True、そうでない場合は False が返されることは言うまでもありません。対象コンピュータがエージェントレスの場合は、スクリプトを実行しないように指定するか、対象コンピュータにリモート アクセスするために別のコードが必要な場合もあります。次の擬似コードに、この概念を示します。
If Not ScriptContext.IsTargetAgentless Then
'Execute normal code
Else
'Execute code for remote connection or simply exit.
End If
ScriptContext の TargetComputer プロパティを使用すると、対象コンピュータがエージェントレスであるか否かにかかわらず、コンピュータ名が返されます。このシリーズの複数の例では、ローカル コンピュータへの接続に WMI を使用しています。これらのスクリプトに簡単な変更を加えると、ローカル コンピュータ上でスクリプトが実行されることを前提とせずに、対象コンピュータを使用してエージェントレス コンピュータに対してスクリプトを実行できます。WMI の利点の 1 つは、ローカル コンピュータの場合と同様に、リモート コンピュータに対してスクリプトを簡単に実行できることです。
たとえば、第 1 部の "List Process Owners (プロセス所有権の判別)" スクリプトは、ローカル コンピュータに対して実行されます。
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colProcessList = objWMIService.ExecQuery("Select * from Win32_Process")
For Each objProcess in colProcessList
colProperties = objProcess.GetOwner(strNameOfUser,strUserDomain)
ScriptContext.Echo "Process " & objProcess.Name & " is owned by " _
& strUserDomain & "\" & strNameOfUser & "."
Next
上記のスクリプトの 1 行目を次のように変更するだけで、エージェントレスか否かにかかわらず、すべてのコンピュータに対して実行されるようになります。
strComputer = ScriptContext.TargetComputer
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colProcessList = objWMIService.ExecQuery("Select * from Win32_Process")
For Each objProcess in colProcessList
colProperties = objProcess.GetOwner(strNameOfUser,strUserDomain)
ScriptContext.Echo "Process " & objProcess.Name & " is owned by " _
& strUserDomain & "\" & strNameOfUser & "."
Next
スクリプトを実行するセキュリティ コンテキストを理解することは重要です。特に複雑な概念ではありませんが、MOM スクリプトでよく発生する解決しにくいエラーの一部は、セキュリティ関係のエラーです。ユーザー アカウントのコンテキストで、ResponseTest を使用してテストを実行しているときはすべてが順調であるように見えても、スクリプトを運用環境に移行すると適切に実行されない場合があります。MOM セキュリティについては、「MOM 2005 Security Guide」(英語) で詳述しています。ここでは、スクリプトに関連のある事項を簡単に説明します。
MOM のスクリプトは、アクション アカウントのコンテキストで、MOMHost プロセスで実行されます。MOMHost プロセスは、応答 (スクリプトを含む) の実行時に、MOM プロセスによって生成されます。アクション アカウントは、スクリプトが持つことになる権限を定義するので、非常に重要です。このアカウントは、エージェントごとに異なる可能性があります。エージェントのインストール時に設定され、図 5 に示すように、エージェントのプロパティを表示して管理者コンソールから変更できます。

図 5 - エージェント アクション アカウントを指定するダイアログ ボックス
エージェント コンピュータのアクション アカウントの既定値は LocalSystem であり、通常ではこのアカウントを使用します。LocalSystem は、ローカル コンピュータに対する完全な特権を持ちますが、別のコンピュータに接続する権限がありません。ほとんどのスクリプトは、スクリプトが実行されるエージェント コンピュータに対して操作を実行することを目的としているため、通常はこのアカウントで十分です。
一般に、MOM での事実上すべての操作 (スクリプトを含む) は、エージェントがローカル コンピュータで実行するように計画されています。この方法により、ネットワーク トラフィックが削減され、1 台の管理サーバーによる多数のエージェントのサポートが可能になり、MOM の優れた拡張性が維持されます。ただし、状況によっては、この基本戦略から逸脱する場合があります。それは、ローカル コンピュータ以外のコンピュータにスクリプトがアクセスする場合などです。
たとえば、スクリプトを使用して、特定のアプリケーションへのネットワーク アクセスをテストすることがあります。その場合は、プログラムによってエージェント上のスクリプトが他のエージェントにアクセスして、ネットワークでのアプリケーションの応答を調べます。さらにもう 1 つの一般的な例として、データベースへのアクセスがあります。データベースのテストに加えて、スクリプトによってデータベースに情報をログすることも必要な場合があります。
ドメイン アカウントをエージェント アクション アカウントの既定値として使用することはお勧めできません。原則としては、単純に、スクリプトで異なる権限が必要な場合以外は、LocalSystem をエージェント アクション アカウントとして使用します。ドメイン アカウントを使用する場合は、そのスクリプトを実行するエージェントだけで使用し、そのドメイン アカウントに必要最小限の権限を与えます。
通常、管理サーバーのアクション アカウントは、ほとんどがネットワークに対する大幅な権限を持つドメインの資格情報で実行されます。特定のタスクのために通常の MOM エージェントにドメインの資格情報を与えるのではなく、前のセクションで説明したように、管理サーバーでスクリプトを起動することも検討できます。
第 3 部では、ResponseTest を使用してスクリプトをテストしてから、MOM でスクリプトを配置する方法について説明しました。ResponseTest のスクリプトは、テストを実行するときにログインで使用したユーザー アカウントのコンテキストで実行される点に注意してください。このアカウントは通常、ユーザー個人のドメイン ユーザー アカウントです。スクリプトを記述する MOM 管理者の場合、このアカウントは通常では大幅なアクセス許可を持つアカウントであるため、混乱する場合があります。運用環境の品質を備えたスクリプトであると判断する前に、適切なエージェント アクション アカウントの資格情報に基づいて MOMHost プロセスで実行中のスクリプトの最終テストを実行してください。
ほとんどの場合、単一のスクリプトのインスタンスは、比較的短い実行時間でエージェント上で実行されるものと見なすことができます。ただし、スクリプトの実行時間が長い場合や、同じスクリプトのインスタンスが複数存在する場合などについて、MOM での処理方法を理解しておくことが重要です。
同時実行
同じスクリプトの複数のインスタンスを実行する場合も含めて、同じエージェント上で複数のスクリプトが同時に実行されることがあります。たとえば、あるスクリプトの実行の平均所要時間が 3 分であるとします。特定のアプリケーションで一連の複雑なテスト プロセスを実行するスクリプトは、所要時間が長くなる場合があります (または、スクリプトが適切に記述されていない場合もあります)。このとき、2 分間隔でこのスクリプトを実行するようにスケジュールするとします。スクリプトが実行中であるとき、スクリプトの別のインスタンスが起動されます。この場合は、2 つのインスタンスが同時に実行されます。共通リソースに対する 2 つのインスタンスの競合が生じる可能性があるため、これは考慮すべき重要事項です。各インスタンスは、独自のローカル変数を維持しますが、共通のマシン リソースや状態変数にアクセスする可能性があります。通常、スクリプトを記述するときは、1 つのインスタンスだけの実行を前提としているため、複数インスタンスのためのコードは含まれていません。
MOM 2000 では、特定スクリプトのインスタンスを一度に 1 つのみ実行可能であったため、スクリプトの複数インスタンスの競合について考慮する必要がありませんでした。MOM 2005 でこの制限がなくなったとき、高い柔軟性を得ると同時に追加の責任を負うことになりました。実際には、スクリプトの実行時間が長く、スクリプトがこれほど頻繁に起動されるケースはまれですが、起こる可能性はあります。この可能性は、スクリプトのタイムアウトによって抑制されます。
タイムアウト
MOM 2005 の新機能に、スクリプトのタイムアウトがあります。MOM 2000 では、適切に動作していないスクリプトがいつまでも実行し続ける可能性があり、エージェントの停止によってのみ終了できました。これではエージェント コンピュータのリソースが不必要に消費されるだけでなく、後続のスクリプトの実行が阻止されます。
MOM 2005 では、スクリプトを実行中のすべてのルールがスクリプトのタイムアウト値を持ちます。既定値は 5 分であり、開始から 5 分後にスクリプトがまだ実行中であると、スクリプトが自動的に終了します。

図 6 - スクリプトのタイムアウト値
スクリプトの実行時間が 5 分を超えることはまれなケースであるため、通常ではこの値を増加する必要はありません。この期間後に引き続き実行中のスクリプトがある場合は、終了する必要があるスクリプトである可能性が高いと言えます。5 分よりも短い間隔で実行される可能性があるスクリプトの場合は、この値を小さくすることで、同じスクリプトの複数のインスタンスが誤って実行されるのを防ぐことができます。実行時間が 5 分よりも長いスクリプトの場合は、タイムアウト値の増加を考える前に、スクリプトを確認し、より小さなサイズに分割することを検討してください。単純に、スクリプトのタイムアウト値を、スクリプトが起動される間隔よりも短くすれば、複数インタスタンスについて責任を負う必要がなくなります。
その他
複雑なトピックの説明は終わりましたので、いくつかその他の推奨事項について説明します。それほど重要で込み入った内容ではありませんが、これらのトピックは、よく聞かれる質問への回答になります。
スクリプトに関連のあるルールを検索する
よくある質問の 1 つは、特定のスクリプトを実行するルールをすべて検索する方法です。次に簡単な回答を示します。
管理者コンソールで、[管理パック] を右クリックし、[ルールの検索] を選択します。ウィザードの既定値をそのまま使用して、[次へ] を数回クリックします。[応答] ダイアログ ボックスが表示され、[スクリプトの起動] を選択できるようになります。これを選択すると、MOM インストールのスクリプトの一覧がドロップダウン リスト ボックスに表示されます。目的のスクリプトを選択すると、数秒後に、使用中のすべてのルールの一覧が表示されます。
管理パックのスクリプトを変更する
変更しないでください。これは簡単ですね。
それでは、このトピックについて簡単に説明しましょう。ただし、前言を撤回するつもりはありません。管理パックで提供されたスクリプトは、変更しないでください。これらのスクリプトは、特定の目的のために提供されており、特定の方法で実行するため、他のルールやスクリプトがにこれらのスクリプトに依存している場合があります。また、管理パックを更新すると、加えた変更内容と共に、スクリプトが上書きされます。
ただし、必要に応じて機能を変更できないという意味ではありません。管理パックのスクリプトを変更する場合は、スクリプトをコピーし、コピーに変更を加えます。当然、そのスクリプトを実行するように構成されたルールは、元のバージョンを実行することになります。加えた変更内容を実行するには、元のスクリプトを実行しているルールを検索します (前述の [ルールの検索] を使用)。検索結果から、変更内容を実行するようにルールに変更を加えます。
スクリプトの名前を付ける
MOM スクリプトには、好きな名前を付けることが可能であるため、これはつまらないトピックのように思われます。いったい名前にどのような問題があるのでしょうか。
MOM 2005 では、独自のカスタム スクリプトと、管理パックで提供されたスクリプトとを区別するための簡単な方法が提供されていません。上記で、管理パックのスクリプトは変更しないように提言したばかりです。それでは、どのような方法でこれらを区別するのでしょうか。
共通のプレフィックスを使用して、独自に作成したスクリプトを区別することをお勧めします。プレフィックスを使用すると、作成したスクリプト (および変更可能なスクリプト) をすぐに識別でき、スクリプトの一覧を名前で並べ替えたとき、これらのスクリプトがまとまって表示されるため便利です。このシリーズで作成したサンプル スクリプトは、先頭にプレフィックス "TechNet: Scripting MOM: " が付加されています。会社名や略語など、より短いものを使用することもできます。独自のスクリプトと、変更してはならないスクリプトとを区別できるものであれば、何を使用してもかまいません。
この 4 部構成シリーズの全体を読み終えると、MOM でのスクリプトの作成について十分な知識を得ることができます。MOM でのスクリプト作成に関して、考えられる限りのあらゆるトピックを取り上げてはいませんが、非常に多くのことを説明してきました。
このシリーズの主な目標は、通常の Windows Scripting に関連する膨大な量の技術情報を MOM ユーザーが利用できるようにすることです。MOM は、Windows Script Host にない配信およびデータ収集エンジンを提供します。また、定期的な起動や、環境内の定義済みイベントへの応答で起動する MOM のスクリプトは、コマンド ラインから対話形式でのみ実行可能なスクリプトに比べて非常に大きな価値があります。これらの MOM スクリプトを状況に合わせて適応させる技能を習得すれば、完全なサンプル コード ライブラリを開設して、既存のスキルを活用して独自の管理ソリューションを提供できます。
最後にお勧めしたいことは、積極的にスクリプトを作成することです。このシリーズのサンプルよりもさらに高度な MOM スクリプトのサンプル ソリューションの提供を予定しています。ご意見やご希望をお待ちしております。質問やサンプルの提案などがございましたら、scripter@microsoft.com にお送りください。