Virtual Machine Servicing Tool 3.0

ある日の出来事。
私「最近、玄関のカギ穴にカギが通りにくいんだよなあ」
私の友人「だったら、551を吹きかければ?」

551?あの金属のサビをなんとかしちゃう556じゃなくて??
その一言は、私にブタまんの肉汁を吹きかけろ、という斬新な一言に聞こえました。

このように、ちょっとしか言葉が違わないのに、
おもいっきり違う意味になってしまうときってありますよね。
それは今回登場する、Virtual Machine Servicing Toolにも当てはまると思います。
Virtual Machine Servicing Toolは、通称VMSTと略されており、
一見すると、VSMT(Virtual Server Migration Tool)と間違えてしまいます。
私も初めてこの文字を目にしたとき、VMSTとVSMTを見間違えてしまい、
とんでもなく間違った解釈をしていた苦い思い出があります。

それはさておき、VMSTですが、
新しいバージョンである、3.0がリリースされようとしています。
VSMT3.0ではライブラリ内の仮想マシンのみならず、
さまざまな場所にある仮想マシン/物理ホストを更新プログラムの適用対象にするようです。

■What’s new in the Virtual Machine Servicing Tool 3.0?(ベータプログラムのダウンロード先もあり)
https://connect.microsoft.com/content/content.aspx?ContentID=17017&SiteID=14

VMSTのドキュメントによると、テンプレート内のSysprep済みディスクに対してはDISMというテクノロジを
使ってVHDファイルをマウントし、パッチを適用するという記述がありました。
オフラインと言いつつ、パッチ適用のためにマシンを起動し、Sysprepを台無しにしてしまう、
前のバージョンと大きな違いですね。
だからこそTechEdでは、デモでご紹介したかったのですが、
実際に動く環境を作ることができず、断念してしまいました。

私は断念してしまいましたが、実際に試してみたいという人や
正式なリリースを待って、すぐに使いたいので、環境だけでも整えておきたいという人のために、
簡単に実装方法を紹介しておきます。
ここでは、かいつまんで紹介しますので、詳細については、ベータプログラムに同梱の
Virtual Machine Servicing Tool Getting Started Guideを参考にしていただければと思います。

1.VMSTをインストールするホスト側の準備
・SCCMまたはWSUSの更新プログラム配布テクノロジの用意
(JREとかAcrobat Readerなどは?と考えると、この条件はハードルが高いですね)
・PsExecユーティリティを%ProgramFiles%\Micrsoft Offline Virtual Machine Servicing Tool\Binフォルダに格納
・PowerShellスクリプトの実行を許可するよう、Set-ExecutionPolicyを実行しておく(RemoteSignedで十分です)

2.仮想マシン側の準備
・ドメインのメンバとして構成 (これまたハードルの高い条件ですね)
・DHCPを有効にする (ということは、DHCPサーバーも用意するってことですね)
・仮想ゲストサービスをインストール
・WSUSを利用する場合は、WSUSサーバーの場所をGPOを通じて設定しておく
・SCCMを利用する場合は、クライアントエージェントのインストールとインベントリの収集、
仮想マシンをグループ化したコレクションを作成する
つまり、仮想マシン側の準備としては、普通にWSUSやSCCMを使って更新プログラムが
適用できるような状態を作っておきなさいって、ことですね。

3.VMSTの設定
VMSTのインストールを済ませたら、VMSTを起動し、次の設定をします。

3-1.左ペイン[Administration]から[Configure Tool]をクリックし、VMSTの基本設定を行う
Configure Toolはウィザードになっていますので、以下の項目を入力してください。
・Configure Servers:VMMサーバー名とWSUSサーバー名(SCCMサイトサーバー名)
・Configure Maintenance Hosts:メンテナンスホストとして使うホストが所属するホストグループとホスト名
・Configure Maintenance Hosts for Servicing Offline VHDs:メンテナンスホスト名と仮想マシンを保存するパス
・Configure Global Settings:タイムアウトまでの時間

3-2.左ペイン[Groups]から更新プログラムを適用する仮想マシンのグループを作成する
グループの作成は以下のように4つの種別に分かれており、
例えば、ホストに展開された仮想マシンのグループを作成する場合は[Virtual Machines on Host Groups]から
グループを作成します。

 VMST1

3-3.左ペイン[Servicing Jobs]から[New Servicing Jobs]をクリックし、
更新プログラム適用のジョブを作成する
New Servicing Jobsはウィザードになっていますので、以下の設定を入れてください。
・Configure Stopped Virtual Machine Servicing Job:ジョブ名と更新プログラム適用に使用するテクノロジ
・Select Virtual Machines:更新プログラムを適用する仮想マシンまたはグループの名前
・Select a Network:更新プログラム適用に使用するネットワーク(仮想ネットワーク)
・Select Maintenance Hosts:メンテナンスホストの指定
・Configure Account Information:更新プログラムを適用するために使用するアカウント(仮想マシンの管理者アカウント)
・Schedule the Servicing Job:更新プログラム適用を開始する日時

VMST2

できあがると上図のようにジョブが登録され、時間になると自動的に更新プログラムの実行を開始します。

このような流れでVMSTを設定して利用します。
最後に、3-3に出てきたウィザード項目について補足を。

■メンテナンスホスト
メンテナンスホストとは、仮想マシンに対して更新プログラムの適用を実行するときに、
仮想マシンを実行するホストのことです。仮想マシンはもともと配置されているホスト上で、
VMSTのジョブを実行するわけではなく、メンテナンスホストとして定義したホストに仮想マシンを移動し、ジョブを実行します。
また、メンテナンスモードとの違いについては、TechNet 「メンテナンスホストについて」にて
以下のように紹介されています。

メンテナンス ホストと “メンテナンス モード” のホストを混同しないように注意してください。メンテナンス モードとは、物理ホストにメンテナンス タスクを実行するために一時的に開始されるもので、メンテナンス ホストは、バーチャル マシンに現行のメンテナンス タスクを実行するために指定されるものです。

■更新プログラム適用に使用するネットワーク
VMST実行時には、仮想マシンが普段使用している仮想ネットワークとは異なる仮想ネットワークを
割り当てて実行することができます。このオプションを定義しておくことで、事実上、オフラインで
更新プログラムを適用することができます。

以上です。

ところで、勘の良い人なら、DISMが使えるなら、わざわざVMST3.0を使わなくてもよいんじゃない?と思うことでしょう。
DISMでどうやって実装しようか、なんてことを考えていたら、COMPUTER WORLDでおなじみの山市良さんが
その方法を紹介してくださってました。

■COMPUTER WORLD BLOG – VHDのオフラインパッチ by DISM
http://blog.computerworld.jp/2010/08/09/offlinepatch-by-dism/

とてもすばらしい記事なので、ぜひご覧になってみてください。

Windows Server 2003の展開とコンポーネントの追加

このブログを書いている少し前、TechEdで私が担当するセッションのリハーサルが終わりました。どんなことを明日はお話ししようかなと考えるにつれ、(時間の関係で)確実にお話しすることができないだろうな、ということが溢れてきます。そんな内容の中から、Windows Server 2003のサーバーコンポーネントの自動インストールについて、触れておきたいと思います。

Windows Server 2003のインストール後(展開後)、サーバーコンポーネントをインストールする場合、
コントロールパネルの[プログラムの追加と削除]-[Windowsコンポーネントの追加と削除]を利用して行います。
これを自動化したい場合、Windows Server 2003に同梱されているsysocmgr.exeというコマンドを使用します。
利用方法については、マイクロソフトのサポート技術情報でも掲載されています。

■Sysocmgr.exeを使用してWindowsコンポーネントの追加または削除する方法
http://support.microsoft.com/kb/222444/ja

サポート技術情報でも紹介されていますが、Sysocmgr.exeでは、
/iスイッチを使って%windir%\inf\sysoc.infを指定(これは決まり事です)、
/uスイッチを使って、インストールするコンポーネントを記載したテキストファイルの指定を行います。

/uスイッチで指定するテキストファイルは、以下のような感じで記載します。

[Components]
iis_common = ON
iis_www = ON
iis_www_vdir_scripts = ON
iis_inetmgr = ON
fp_extensions = ON
iis_ftp = ON[NetOptionalComponents]
DNS = 1

テキストファイルは[Components]と[NetOptionalComponents]から構成されており、
インストールしたいコンポーネントを[Components]または[NetOptionalComponents]に記載します。
[Components]に記載したコンポーネントを追加するときは、=ONと書き、
[NetOptionalComponents]に記載したコンポーネントを追加するときは、=1と書きます。

自分がインストールしたいコンポーネントは[Components]と[NetOptionalComponents]のどちらに書けばよいか
(または、どういう書式で書くか)については、情報をまとめてくださっているサイトがあるので、参考にするとよいと思います。

■Notes of Windows Admin – Remote Installation of the Windows Conponents
http://winadminnotes.wordpress.com/2010/07/09/remote-installation-of-the-windows-components/

実際の使い方について、例を挙げてみたいと思います。

■例1 DNSサーバーのインストール

[NetOptionalComponents]
DNS = 1

上記のようにファイルを作成し、保存したら(ここではc:\dns.txtという名前で保存したとします)
次のようにコマンドを実行すれば完了です。

c:\> sysocmgr.exe /i:%windir%\inf\sysoc.inf /u:c:\dns.txt

■例2 ASP.NETが利用可能なWebサーバーのインストール

[Components]
iis_common = ON
iis_www = ON
aspnet = ON
iis_inetmgr = ON

あとは例1と同じ要領でsysocmgr.exeを実行するだけです。
ASP.NETのコンポーネントにaspnet=ONを指定していますが(赤字部分)、
ご存じのとおり、ASP.NETのコンポーネントにはIIS本体のインストールも必要です。
そのため、ASP.NET=ONとすれば、付随して必要となるIISのコンポーネントは自動的にインストールされます。
ちなみに、IISの自動インストールについては、以下のマイクロソフトのサイトが参考になります。

■IIS6.0の無人インストールを実行する方法
http://support.microsoft.com/kb/309506/ja
■Creating an Answer Files(IIS6.0)
http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/efefcb53-b86e-4cac-9b4b-fcf5f1145aa9.mspx?mfr=true

SCVMMのテンプレートからWindows Server 2003を展開する場合、GUIRunOnceでsysocmgr.exeを指定するという
方法でコンポーネントのインストールまでを自動化することができますね。
(ただし、/uスイッチで指定するテキストファイルの保存場所がネックになりますが…)

最後になりますが、インストールにはWindows Server 2003のメディアが必要になりますので、
あらかじめご用意ください。自動インストールするのに、「インストールのパスを指定してください」なんて聞かれたら、 自動化ではなくなってしまいますよね。また、レジストリの設定でインストールパス(Windows Server 2003のセットアップディスクのi386フォルダが格納されている場所)を指定しておくこともできます。
(パスの指定方法は前述のWebサイト、Notes of Windows Adminさんのところで紹介されています)

SCVMMライブラリに配置したPowerShellスクリプト

SCVMMのライブラリ共有には、vhdファイルやISOファイルなど、仮想マシンを展開するために必要なコンテンツを保存しておくことができますね。今日は、色々なコンテンツを保存できるライブラリ共有からPowerShellスクリプトについてです。

PowerShellスクリプトは、ライブラリの共有フォルダに保存しておくだけで、VMM管理者コンソールに表示され、
管理者コンソールからスクリプトの実行開始ができます。ところが、単純にps1ファイルを配置して、実行しようとすると、
下図のようなエラーが表示されます。

sigerror1
図 見にくくてごめんなさい。要するにデジタル署名されてないよ、と言っています。

エラーメッセージにも書いてあるようにPowerShellスクリプトにデジタル署名(コード署名)を施してあげないといけません。
PowerShellスクリプトにデジタル署名を施す方法については、すでに様々なところで紹介されているので、そちらを参考にしていただければと思います。

■PowerShellで仮想環境も管理!! Hyper-V、SCとの連携
http://journal.mycom.co.jp/articles/2010/06/15/ps_y/001.html

■Set-AuthenticodeSignature
http://technet.microsoft.com/ja-jp/library/dd347598.aspx

ところが、実際に署名を施そうとすると、エラーが表示されました。

sigerror2 
図 Unknown Errorと表示されていることがわかる

PowerShellスクリプトの開発環境である、Windows PowerShell ISEを使って作られたスクリプトは
文字コードがUnicode Big endian形式で保存されるのですが、コード署名するスクリプトはUTF-8形式で
保存しなければなりません。そのため、Windows PowerShell ISEを使ってスクリプトを作成した場合、
いったんメモ帳でスクリプトを開き、UTF-8形式でファイルを保存しなおしてあげる必要があります。
(文字コードを変える方法はメモ帳以外にもありますので、もちろんほかのやり方でも結構です)

sigerror3 
図 UTF-8形式で保存してあげると、コード署名もご覧のとおり

これで、VMM管理者コンソールから、ライブラリ共有のPowerShellスクリプトを実行できるようになりました。

SCVMMのジョブ(3)

人生長くやってれば、誰にだって忘れたい過去のひとつやふたつぐらいあると思います。
人間の記憶を消すことは簡単ではないけれど、SCVMMのジョブの場合には方法があるようです。

■SCVMM How to: Remove failed jobs from SCVMM console
http://social.technet.microsoft.com/wiki/contents/articles/scvmm-how-to-remove-failed-jobs-from-scvmm-console.aspx

ジョブの状態が「失敗」と記録されるレコードを参照しながら、インシデント管理をしている場合、
インシデント対応が完了したなら、ジョブの一覧から「失敗」の状態のレコードは非表示にしたい、
というときに使えそうです。

SCVMM管理者コンソールで参照できるジョブの一覧がこちらなら、

job3-2

SQL Server Management Studioから参照できるジョブの一覧がこちら。

job3-1

ちなみに、この一覧は以下のSQL文で表示しています。

Select TaskState,IsVisible,StartDateTime,CmdletName From tbl_TR_TaskTrail Where IsVisible=1

 

SQLデータベースに登録されているジョブ一覧のうち、IsVisible=1のレコードがSCVMM管理者コンソールに
ログとして表示されるという仕組みになっているようですね。また、StartDateTimeが管理者コンソールでは
開始時刻として表示されているのですが、よく見るとデータベースにはGMTでの表示で、
管理者コンソールにはGMT+9時間で表示されていることもわかりますね。

では、上から2番目の「失敗」のレコードを非表示にしてみます。
前述のWebサイトで紹介されていた方法では、失敗(Failed)のレコードをすべて非表示にしてしまうので、
開始時刻(StartDateTime)をキーにするのがよいかなと思います。
(もっと良い方法があれば、コメントいただけるとありがたいです)

管理者コンソールで表示されている失敗のログは、開始時刻が2010/08/20 12:03:28となっているので、
レコード一覧を見る限り、StartDateTimeが2010-08-20 03:03:28 913となっているレコードが該当する
(+9時間であることに注意)のかな、と推測できます。
そこで、次のSQL文を実行し、該当するレコードをIsVisible=0にします。

update tbl_TR_TaskTrail set IsVisible=0 where StartDateTime = ‘2010-08-20 03:03:28.913’

 

これでSCVMM管理者コンソールに失敗のログが表示されなくなります。
だけど、もうちょっと簡単な方法があったらな、と思います。

SCVMMのジョブ(2)

前回の投稿では、SCVMMのジョブをアーカイブするためのいくつかの方法を紹介しましたが、
今回はGet-Jobコマンドレットを使ったスクリプトを作成し、実際に使ってみたいと思います。

今回使用するスクリプトは、TechNetライブラリに掲載されている、GetLibraryAuditRecords.ps1です。
このスクリプトでは、Get-Jobコマンドレットを実行し、その結果を設定前の値と設定後の値で並べて表示する、
というものですが、実際に利用するに当たり、注意したい点があります。
それは、「ジョブには名前がついているので、どの名前のジョブを出力するか決めておく」ということです。

これだけでは、何を言っているのかわかりにくいですね。もう少し詳しく説明しておきます。
ジョブの名前とは、管理者コンソールのジョブを開いたときに[名前]欄で表示される部分のことを指します。
Job-console1
画面 – 青枠で囲まれたところに表示されているがジョブの名前

GetLibraryAuditRecords.ps1 は、ジョブの名前を単位としてクエリを実行するように作られているため、
なにかしらの名前を指定する必要があります。ちなみに、ジョブの名前はGet-Jobコマンドレットを
次のように実行すれば確認できます。


$LibNames=Microsoft.SystemCenter.VirtualMachineManager\Get-Job -all | Sort-Object name
Foreach ($LibName in $LibNames){
  if ($LibName –ne $i){
    $LibName.name
    $i=$LibName.name
  }
}

 

これで、どのような名前があるか確認することができます。
名前の一覧を確認し、どの名前のジョブ一覧をログとして保存するかを決めたら、
GetLibraryAuditRecords.ps1スクリプトでジョブの名前を指定します
(下の表内、赤字で書いてある「ライブラリ共有の更新」部分)。
ちなみにジョブの名前を指定せずに全件表示させるなら、赤字部分はアスタリスクでもいいですね。

# Filename: GetLibraryAuditRecords.ps1
# Description: Gets all library refresh jobs, and then
# lists the previous and new values for the
# properties that were changed for each job.# Get all library refresh jobs. Because Windows PowerShell 2.0 also contains a Get-Job cmdlet,
# qualify that you are using the VMM Get-Job cmdlet by specifying the VMM snap-in.
$LibraryJobs = Microsoft.SystemCenter.VirtualMachineManager\Get-Job -all | Where {$_.Name -eq “ライブラリ共有の更新“}

# Get the audit records for each library refresh job.
ForEach ($LibJob in $LibraryJobs)
{
$FullLibJob = Microsoft.SystemCenter.VirtualMachineManager\Get-Job -Job $LibJob –Full

# Get and list the changed properties for each audit record.
Foreach ($AuditRecord in $FullLibJob.AuditRecords)
{
Write-Host “”
Write-Host “Property:” $AuditRecord.Name
Write-Host “Previous value:” $AuditRecord.Previous.Value
Write-Host “New value:” $AuditRecord.New.Value
Write-Host “” Write-Host
“#####################################################”
}
}

上表 GetLibraryAuditRecords.ps1のスクリプト(TechNetライブラリから転載) 

私は「ライブラリ共有の更新」の文字を決め打ちするのが嫌だったので、
$LibraryJobs=で始まる行に1行加えて、次のようにGetLibraryAuditRecords.ps1を変更してみました。

$LibName=Read-Host EnterName
$LibraryJobs = Microsoft.SystemCenter.VirtualMachineManager\Get-Job -all | Where {$_.Name -eq $LibName]

 

実行結果はご自身で試していただければ、確認することができますし、
TechEdでもご覧いただくことにしたいと思っています。

SCVMMのジョブ(1)

TechEd 2010のセッションがいよいよ来週に迫り、絶対にセッションの中では細かく
解説することができないだろうなあ、という項目を当ブログに書いています。
今回のテーマは「ジョブ」についてです。

SCVMMでは、実行内容を「ジョブ」として記録し、
どのような処理をしたのか、どのような実行結果になったか、などを確認することができます。

このジョブはSCVMMとともにインストールする(もしくは事前にインストールする)
データベースサーバーの中に格納され、90日間保存されます。
しかし、90日経過すると自動的に消えてしまうため、ログとして永続的に残しておきたい場合には、
どこかに待避させておく処理、つまりアーカイブ処理が必要になってきます。

そこで、どのようなジョブのアーカイブ方法があるのか、私の思いつく限りまとめてみました。

1.ジョブが格納されているデータベースに対し、バックアップを実行する
SCVMMをインストールすると、VirtualManagerDBという名前のデータベースが
作成されるので、VirtualManagerDBデータベースに対してバックアップを実行します。
SQL Serverにデータベースを格納している場合はSQL Management Studioを使ってバックアップを
実行することができますが、SCVMMとともにデータベースサーバーをインストールした場合、
GUIでバックアップを実行することができません。その場合、マイクロソフト ダウンロードセンターから
入手可能なSQL Management Studio Expressを使うとよいでしょう。

ちなみに、SCVMMには、管理者コンソールの[管理]-[全般]から、バックアップを実行する方法が
用意されています。そして、この方法でバックアップを実行した場合、復元にはscvmmrecover.exeという
ツールを使う必要があります。
■VMMデータベースのバックアップと復元
http://technet.microsoft.com/ja-jp/library/cc956045.aspx

ところが、SCVMMのメディアにはこのツールがない!(私だけでしょうか?)
というわけで、SCVMM管理者コンソールからバックアップする方法ではなく、データベースを
直接バックアップする方法をここでは紹介しました。

2.Get-Jobコマンドレットを使ってジョブを全件出力する
ジョブの内容を出力するSCVMMのコマンドレットにGet-Jobというのがあり、
Get-Jobコマンドレットの出力結果をテキストファイルなどに格納すれば、
結果的にアーカイブしたのと同じ効果になります。
(ただし、単なるテキストファイルなので、「ログ」としての効果しかありませんが…)
Get-Jobコマンドレットを使って全件出力するスクリプトが
TechNetライブラリに掲載されているので、参考にしていただければと思います。

3.そもそも90日で消えないようにする
90日という設定は変更可能だそうです。 (試していないので、実現可能かわかりませんが..)
設定方法を掲載しているブログがありますので、参考にしていただければと思います。
■Hyper-V note from the field – SCVMM Service may take up lots of memory
http://technet.microsoft.com/ja-jp/library/ee460934.aspx

今回、3つの方法を紹介しましたが、このうち2番目の方法について次回紹介します。

SCVMMのJobGroupについて

TechEd Japan 2010のセッションを担当させていただくに当たり、自分が作ったスライドを眺めていたら、
スクリプトを紹介するスライドの中で、JobGroupというのを多用していることに気が付きました。
JobGroupって?ということもあるかと思い、こちらに書き留めておくことにしました。

JobGroupとは、SCVMMで行う操作に対して割り当てることができるIDのことで、
JobGroupのIDを使うことで、ひとつのジョブで複数の処理を行うよう指定することができます。
例えば、ハードウェアプロファイルをPowerShellから作成する場合、
・DVDドライブを作成する
・仮想NICを作成する
・メモリの割り当てをする
などの設定を個々のコマンドレットで実行していきます。
このとき、個々のコマンドレットをバラバラに実行するのではなく、ひとつのジョブの括りで実行したい場合、
JobGroupというIDを生成しておき(下表の4行目部分)、そのIDを個々のコマンドレットのオプション-JobGroupで指定します。

$HWName = “test1
$MemoryMB = 1024

$JobGroupID = [System.Guid]::NewGuid()
New-VirtualDVDDrive -Bus 1 -Lun 0 -JobGroup $JobGroupID
New-VirtualNetworkAdapter -EthernetAddressType Dynamic -NoConnection -JobGroup $JobGroupID
$HWProfile = New-HardwareProfile -Name $HWName -MemoryMB $MemoryMB -JobGroup $JobGroupID

表 – ハードウェアプロファイルを作成するスクリプト(赤字部分は環境に合わせて変えてください) 

実行すると、一連の処理がひとつのジョブとして実行されるようになります。
管理者コンソールで確認すると、ご覧のとおりです。

hwprofile 

管理者コンソールから何かの操作を行ったとき、ウィザードの最後に出てくるPowerShellスクリプトを
見てみると、勝手にJobGroupのIDが割り当てられていたりするけれど、それはこういうことだったのですね。

ちなみに、JobGroupはすべてのコマンドレットで使えるわけではなく、
利用できるコマンドレットは限られているようです。そのことがTechNetフォーラムで紹介されています。

http://social.technet.microsoft.com/Forums/en-US/virtualmachinemanager/thread/ab1e7054-69c7-44ee-a475-229f9557b653