
TechNet コラムへようこそ。このコラムでは、よく寄せられるシステム管理スクリプトに関する質問に Scripting Guys がお答えします。システム管理スクリプトについて質問がある場合は、scripter@microsoft.com (英語のみ) までお送りください。すべての質問に回答することはできないかもしれませんが、可能な限り対応いたします。
詳細情報
| • | |
| • | |
| • |
![]()
Scripting Guy さん、よろしくお願いします。コンピュータの日時を設定する方法はありますか。
-- KM

KM さん、こんにちは。そうです、今日は TechEd IT Forum の最終日です。つまり、Scripting Guys にとってお楽しみの時間は終わりということになります。明日の朝、飛行機に乗り、それぞれの家路に着きます。言うまでもありませんが、仕事、車や住宅ローンの支払い、家族など、何から何まで現実の世界に戻ります。
もう明日が待ち遠しくて仕方ありません。
何はともあれ、バルセロナでの最後の 1 日を、Scripting Guys にできる唯一の方法で祝いたいと思います。それは、コンピュータの日時を設定するスクリプトを記述することです。皆さんは下がっていてください。このパーティの主役は Scripting Guys ですから。
dtmNewDateTime = "20071115132000.000000-480"
strComputer = "."
Set objWMIService = GetObject("winmgmts:{(Systemtime)}\\" & strComputer & "\root\cimv2")
Set colOSes = objWMIService.ExecQuery("Select * From Win32_OperatingSystem")
For Each objOS In colOSes
objOS.SetDateTime dtmNewDateTime
Next
このスクリプトのしくみを説明する前に、いくつか注意点を挙げておきます。このスクリプトを実行すると、実際にコンピュータの時刻が変更されます。実行対象のコンピュータが Active Directory ドメインのメンバである場合、このことが原因で問題が発生する可能性があります。Active Directory では、コンピュータ間の時刻が同期されていることは重要です。コンピュータとドメイン コントローラの時刻が大幅に異なる場合、そのコンピュータはネットワークにログオンできません (ただし、その場合でもコンピュータ自体にはログオンできます)。また、Active Directory もコンピュータ間の時刻を同期するために最善を尽くします。ドメインにログオンできた場合も、高い確率で、コンピュータの時刻は Active Directory によって、どこかのタイミングで自動的に更新されます。時刻が同期されることは、皆さんにとっては、たいした問題ではないかもしれませんし、コンピュータが Active Directory ドメインに参加していなければ、この動作について気にする必要はまったくありません。ただ、ちょっと覚えておいてほしいというだけです。
注 : そうは言うものの、Active Directory ドメイン内でも、テスト目的で今回のようにコンピュータの時刻を変更することはよくあります。 |
では、このスクリプトのしくみについて見ていきましょう。まず、新しい日時を dtmNewDateTime という名前の変数に代入します。これが 1 行目のコードで行う処理です。
dtmNewDateTime = "20071115130000.000000-480"
ええ、そうですね。あまり日時を表す値には見えません。その原因は、WMI で Universal Time Coordinate (UTC) 形式が使用されていることにあります。UTC 値は見慣れない感じがするかもしれませんが、確かに日時を表す値です。この値の構造を次に示します。
| • | 最初の 4 文字 (2007) は年を表しています。 |
| • | 次の 2 文字 (11) は月を表しています。 |
| • | 次の 2 文字 (15) は日を表しています。 |
| • | 次の 2 文字 (13) は 24 時間形式の時間を表しています。米国の皆さん、13 時は午後 1 時ですよ。 |
| • | 次の 2 文字 (00) は秒を表しています。 |
| • | .000000 はミリ秒を表しています。 |
| • | -480 はグリニッジ標準時からのオフセットを表しています。-480 は、このコンピュータが設置されている場所のタイム ゾーンの時刻がグリニッジ標準時よりも 8 時間 (480 分) 早いことを示しています。つまり、このコンピュータが設置されているワシントン州レドモンドの時刻が正午 (12:00) である場合、英国のグリニッジの時刻は午後 8 時 (20:00) です。 |
注 : グリニッジ標準時からのオフセットを確認するにはどうすればよいのか、ですって。その方法を知りたい場合は、「Microsoft Windows 2000 Scripting Guide」(英語) を参照してください。 |
お気付きかもしれませんが、ここでは、Windows XP より前のバージョンでもこのスクリプトを実行できるように、このスクリプト用に独自の UTC 値を作成しました。Windows XP 以降のバージョンの Windows を実行している場合は、次のように WbemScripting.SWbemDateTime オブジェクトを使用すると、自動的に UTC 値が作成されます。
Set objSWbemDateTime = CreateObject("WbemScripting.SWbemDateTime")
objSWbemDateTime.SetVarDate #11/15/2007 1:20 PM#, True
dtmDateTime = objSWbemDateTime.Value
Wscript.Echo dtmDateTime
詳細については、TechNet Magazine の Hey, Scripting Guy! コラム「It’s About Time (Oh, and About Dates, Too)」(英語) を参照してください。
今回のスクリプトで難しいところは、この適切な UTC 値を取得する部分です。UTC 値を取得したら、ローカル コンピュータ上の WMI サービスに接続します (このスクリプトはリモート コンピュータに対しても実行できます。それには、リモート コンピュータの名前を strComputer 変数に代入します)。その後、次のコードを使用して、コンピュータで現在使用されているすべてのオペレーティング システムのコレクションを取得します。
Set colOSes = objWMIService.ExecQuery("Select * From Win32_OperatingSystem")
注 : なぜ "インストールされている" ではなく "現在使用されている" という表現を使用したと思いますか。理由は簡単で、Win32_OperatingSystem クラスがその基準に従って動作するからです。このクラスは、現在使用されているオペレーティング システムの情報のみを返します。マルチブート システムの場合でも、そのコンピュータにインストールされている他のオペレーティング システムの情報は返されません。 |
コレクションを取得したら、For Each ループを使用してコレクション内の項目を 1 つずつ処理します (今回の場合、コレクション内の項目は 1 つしかありませんが)。ループ内では、次のように SetDateTime メソッドを呼び出し、作成した UTC 値をそのメソッドに渡しているだけです。
objOS.SetDateTime dtmNewDateTime
こうしてコンピュータの時刻は変更され、皆いつまでも幸せに暮らしましたとさ。
これでご質問の回答になっているとよいのですが、KM さん。Scripting Guys は、あと 1 日ブースで働きます。溶かしたチョコレートとホイップ クリームを混ぜ合わせた飲み物を片手にチュロスを食べられるのもあと 1 日です。何もかも今日が最後で、残念としか言いようがありません。偶然にも今日 IT フォーラムにお越しになる皆さんは、22 番ブースを覗いてみてください。Scripting Guys がお待ちしています。皆さんの元気を分けてあげてください。