検索
連載

第2回 WSHスクリプト・コーディングの第1歩Windows管理者のためのWindows Script Host入門(1/2 ページ)

WSHでは、OOPスタイルでWSHの標準オブジェクト、外部のCOMオブジェクトを操作する。その第1歩となる基礎知識を得る。

Share
Tweet
LINE
Hatena
運用 Windows管理者のためのWindows Script Host入門
Windows Server Insider

 

「運用 Windows管理者のためのWindows Script Host入門」のインデックス

連載目次


 前回は、WSHの内部構造を説明し、WSHを構成する各コンポーネントについて概観してみた。これによりWSHは、MS-DOSのバッチやUNIXのシェルスクリプトとは異なり、特定の言語に依存しない汎用のスクリプト実行環境であることが分かった。

 WSHのプログラミング・スタイルは、いまや常識となったOOP(Object Oriented Programming)に従っており、WSH自身が提供するオブジェクトや、IEやOfficeなどのアプリケーション、WMIやADSIなどのシステム管理用の外部オブジェクトをスクリプトから操作することで処理を実現する。しかしOOPといっても、C++やJava、C#言語のように複雑なものではないので、記述のスタイルにさえ慣れてしまえば、OOP経験のない人でも問題なく使えるだろう。このような読者を想定して、OOPのごく簡単な導入についても述べる。そして今回は、WSHが標準で提供するオブジェクト・モデルをご紹介し、これらを利用した簡単なスクリプトを作成してみる。

スクリプト実行時の各コンポーネントの役割

 作成したWSHのスクリプト・ファイルを実行するには、エクスプローラでスクリプト・ファイルをマウスでダブルクリックしたり、コマンド・プロンプトからCScriptのパラメータとしてWSHファイルを指定して実行したりする。スクリプトを実行した場合のWSHコンポーネントの挙動は以下のとおりである(WSHコンポーネントの構成については、前回の図「WSHの構成」を参照のこと)。

1.WSHスクリプト・ホストの起動
 WSHスクリプトを実行すると、最初にスクリプト・ホストが起動される。エクスプローラでWSHスクリプト・ファイルをダブルクリックしたときにはGUIベースのWScriptスクリプト・ホストが起動され、コマンド・プロンプトからCScriptを利用した場合にはCUIベースのCScriptスクリプト・ホストが起動される。このときいずれの場合も、スクリプト・ファイルのファイル名が各スクリプト・ホストにパラメータとして渡される。

2.スクリプト・エンジンの選択
 起動されたスクリプト・ホストの最初の仕事は、パラメータとして与えられたスクリプト・ファイルの拡張子からスクリプト・エンジン(スクリプト言語を処理するためのプログラム)を決定することである。スクリプト・ホストは、レジストリに保存された情報に従ってスクリプト・エンジンを決定する。標準の状態では、“.vbs”はVBScriptに、“.js”はJScriptに対応している。

3.スクリプト・エンジンの起動とスクリプトの実行
 次にスクリプト・ホストは、スクリプト・ファイルをメモリ上に読み込み、選択したスクリプト・エンジンを起動する。以後スクリプト・ホストとスクリプト・エンジンは、Windows Script Interfacesというインターフェイスで通信しながらスクリプトを実行していく。

 実際のスクリプトの解釈はスクリプト・エンジンが行うが、スクリプト・ホスト側で定義されたシンボル(WSHオブジェクトなどによって定義されたシンボル)を処理する際は、必要に応じてスクリプト・エンジンからスクリプト・ホストに情報を問い合わせることになる。また、スクリプトが外部のCOMコンポーネントを利用する場合は、スクリプト・ホストが提供するライブラリがすべての通信処理を行う。

スクリプト・ファイルの種類

 WSHが標準でサポートするスクリプト・ファイル用の拡張子は以下のとおりである。

拡張子 意味
VBS VBScript言語で記述されたスクリプト・ファイル
JS JScript言語で記述されたスクリプト・ファイル
WSF ジョブ単位でスクリプトを管理するXMLファイル
VBE エンコードされたVBScript
JSE エンコードされたJScript

 このうちWSF(Windows Script File)は、XMLフォーマットのファイルであり、ジョブと呼ばれる作業単位ごとに、1つのファイルの中に異なる複数の種類のスクリプトを記述できる。この際、各スクリプトはVBScriptやJScriptなど異なる言語を混在させて記述したり、外部のスクリプト・ファイルを読み込んで(インクルードして)順次実行したりすることができる。WSFのXML要素の詳細については、ドキュメントを参照されたい。

 VBEとJSEは、エンコード(符号化)されたスクリプト・ファイルである。通常のスクリプト・ファイルはテキスト・ベースで、テキスト・エディタで簡単に表示したり編集したりできる。これは手軽な扱いを可能にするスクリプトの特長だが、一方ではエンドユーザーにはスクリプトの詳細を公開したくない場合もある。そのような場合には、スクリプトをエンコードすることで、スクリプト・コードをユーザーが簡単に表示したり変更したりできないようにすることが可能である。

 作成したスクリプトをエンコードするには、以下のURLからスクリプト・エンコーダをダウンロードする必要がある。

 以上は標準でサポートされるスクリプト用の拡張子である。さらにオプションでスクリプト・エンジンをインストールすれば、Perl(.pls)やRuby(.rb)のスクリプトも実行できるようになる。

 ただし本稿の主眼は、管理者が面倒な繰り返し作業や、単純だが多数のステップにわたるような管理作業をWSHスクリプトで簡略化することにある。大規模で複雑な処理をスクリプトで実行する場合や、エンドユーザー向けに提供するスクリプトでは、WSF形式のスクリプト・ファイルやスクリプトのエンコードが有効な場合もあるが、今回のような目的にはあまり必要はないだろう。以下本稿では、基本的に.VBSファイルと.JSファイルのみを使用することにする。

オブジェクト指向プログラミング超入門

 すでに説明しているとおり、WSHスクリプトでは、WSH自身が提供したり、外部から提供されたりするCOMオブジェクトを操作することで処理を行う。このためVBScriptやJScriptのコーディング・スタイルは、オブジェクト指向プログラミング(OOP:Object Oriented Programming)のそれに従っている。MS-DOSのバッチでは、実行したいコマンドライン・コマンドを1行目から順に書いていくだけだったが、WSHでは、オブジェクトを作成してオブジェクトにメッセージを送る、というスタイルがプログラムの基本的な流れとなる。OOPの経験がない読者は、当初こうしたプログラミング・スタイルに戸惑うかもしれない。ここではそうした読者に向けて、OOPの基礎について簡単にまとめておこう。

 FORTRAN言語やC言語などといった伝統的な手続き型の言語では、プログラムから利用できる機能を関数(やサブルーチン)として実装していく。このためこれらの言語では、実現すべき機能が増えるに従って、機能に対応する関数セットが肥大化していくという特徴がある。例えばWindowsでは、API(Application Programming Interface)と呼ばれる関数をアプリケーションに提供し、アプリケーションがこれを呼び出すことでメモリ管理やウィンドウ管理など、さまざまなWindowsの機能を利用できるようにしている。当初は比較的単純だったWindows APIだが、Windowsのバージョンアップでさまざまな機能拡張が行われるにつれてAPIの数は肥大化の一途をたどり、いまや1人のプログラマで全体を把握するのが困難なほど複雑な仕様になってしまっている(互換性維持のために、古いAPIも捨てるわけにはいかない)。

 この問題を解決して、複雑なシステムをできるだけ単純にプログラムで扱おうとする手法の1つがOOPである。OOPでは、単純な「機能」の呼び出しをプログラムで列挙するだけでなく、プログラムで「何(=オブジェクト)を扱うのか」に注目し、オブジェクトごとに機能を整理する。この際、まとめて扱うべきデータセットとそのデータに関する機能を「クラス」としてひとまとめにして扱えるようにする。プログラムでは、このクラスから、実体となるオブジェクト(インスタンスともいう)を生成して利用する。C言語の知識があるなら、構造体の定義と構造体の実体の関係に等しい。これにより複雑なシステムでもクラスを整理することで分かりやすく構造化することができ、将来の機能拡張も容易になる。C#やVisual Basic .NET、Java、C++など、現在使われているプログラミング言語のほとんどでこのOOPの概念が取り入れられている。WSHにおいても、スクリプトから利用可能な機能はWSHオブジェクトなどとして提供され、スクリプト・コードからは、OOPスタイルに従った記述法でこれらのオブジェクトを操作することになる。

 オブジェクト(object)は「モノ」という意味で、OOPではあらゆるものをオブジェクトの単位で扱う。例えばファイルからデータを読み込む場合を考えてみよう。伝統的な手続き型言語では、それぞれ独立した「オープン」「リード」「クローズ」などのライブラリ関数を呼び出すことになる。どのファイルを開くか(どのディスクの、どのディレクトリにある何という名前のファイルか)という情報は、関数のパラメータとして与える。関数呼び出しの結果は、戻り値などとして得ることができる。

 これに対しOOPでは、最初にファイルを表すオブジェクトを作成し、そのオブジェクトに対して「オープン」「リード」「クローズ」のメッセージを送ることでファイルの操作を行う。ファイル・オブジェクトに対して実行可能な操作は、「オープン」「リード」「ライト」「クローズ」などである。このように各オブジェクトは、自分自身に対して可能な操作を「メソッド」として外部に公開する。プログラムでは、オブジェクトごとに用意されたメソッドにメッセージを送って(呼び出して)処理を進めるわけだ。また、それぞれのファイルは、「ファイル名」や「ファイル・サイズ」など、オブジェクト固有の情報を持っている。このように、各オブジェクトが持つ値は「プロパティ(=属性)」と呼ぶ。

 例えばいま、AというファイルとBというファイルが存在するとして、A、Bを表すオブジェクトをそれぞれa、bとすると、aとbは別のオブジェクトであるが、「リード」や「ファイル名」など使用できるメソッドとプロパティは双方で共通している。これは、a、bともに「ファイル」という同じ概念の「モノ」を表しているからである。このように「ファイル」という抽象的な存在を記述し、それが公開するメソッドやプロパティの枠組みを規定するのが「クラス」であり、そのクラスから生成された実体(この例ではオブジェクトのaとb)を「インスタンス」という。つまりaとbは、同じ「ファイル」クラスから生成されたインスタンスである。

 オブジェクトがどのようなメソッドやプロパティを持つかは、それがどのクラスに属しているかによって決定される。しかし、オブジェクトaとbが共通して提供する「リード」メソッドを呼び出すにしても、オブジェクトaの「リード」メソッドを呼び出すとファイルAの内容が、オブジェクトbの「リード」メソッドを呼び出すとファイルBの内容が読み出される。これは、aとbが別のインスタンスだからである。このようにクラスは、「ファイル」という抽象的な概念を表すのに対し、インスタンスは「ファイルA」「ファイルB」という個々の「モノ」を表す。

 奥深いOOPのすべてをここで語ることはできない。WSHを利用するうえでは、以下に示すOOPの基本中の基本だけ覚えておいてほしい。

OOPで処理を行うには、基本的に次の手順に従う。

  1. 操作対象となるオブジェクトを作成、またはすでに作成されたオブジェクトを指定する。
  2. そのオブジェクトが提供するメソッドを呼び出す。


Copyright© Digital Advantage Corp. All Rights Reserved.

       | 次のページへ
ページトップに戻る