Windows Vistaにオフラインでパッチをあてる

どうしてもオンラインにできないVistaマシンに、セキュリティパッチを当てなければならなくなったので方法を調べてみた。もちろん毎回手でパッチをダウンロードしてきてもできるが、本当に必要なパッチがどれなのかハッキリしないし、手間を省きたい。
まず、Microsoft Baseline Security Analyzer(MBSA)を利用して、どのパッチが必要なのかをレポートさせる。

MBSAをオフラインで実行する
http://www.atmarkit.co.jp/fwin2k/win2ktips/1053mbsascan/mbsascan.html

基本的にMBSAGUIのアプリケーションだが、CUIで作業したいので以下のファイルをインストールフォルダから取り出しおく。これ意外は必要ない。

  • mbsacli.exe
  • wusscan.dll

更にwsusscn2.cabをダウンロードして、この上の二つと一緒にパッチを当てたいマシンに置く。wsusscn2.cabはパッチが出るたびに更新されるので、その都度以下からダウンロードする必要がある。

上級ユーザー向けの新しいバージョンの Windows Update オフライン スキャン ファイル Wsusscn2.cab について
http://support.microsoft.com/kb/926464/ja

あとで使い易いようにXMLでレポートを出力させる。

mbsacli.exe /catalog wsusscn2.cab /unicode /xmlout > report.xml

このXMLには既にインストールされているパッチもあわせて出力されているので、スクリプトを書いてインストールされていないパッチを探す。例としてPythonで書いてみた。parseReport()の引数reportStringは文字列として読み込んだレポートのXMLファイルだ。この例ではSeverityもチェックしている。Severityが0のものとは、普通のWindows UpdateMicrosoft Update自動的にインストールされないもの、例えば新バージョンのIEとか、ルート証明書などが該当する。

def parseReport(reportString):
	dom = minidom.parseString(reportString)
	root = dom.documentElement

	for e in root.getElementsByTagName('UpdateData'):
		isInstalled = e.getAttribute('IsInstalled')
		severity = int(e.getAttribute('Severity'))

		if 'false' == isInstalled and 0 < severity:
			for url in e.getElementsByTagName('DownloadURL'):
				yield url.childNodes[0].data

for url in parseReport(reportString):
	print url

これでパッチをダウンロードするためのURLが出力された。さてVista以前(XPなど)でこの方法を使うと、パッチの実行体(EXE)が落ちてくるのでそのまま実行させれば良い。
ところがVistaの場合は、パッチが入ったCABファイルが落ちてくる。このCABファイルをパッチとするには、展開してpkgmgrを使う必要がある。ググってみたら便利そうなBATファイルを公開している人がいた。ロシア語なので内容はぜんぜんわからないが、カレントフォルダにあるCABファイルを全て適応してくれるようだ。

Abrosovさんの書き込みから引用
http://forum.oszone.net/archive/index.php/t-84254-p-4.html

@echo off
for %%a in (*.cab) do (
md %%~na
start /wait expand %%a -f:* %%~na
start /wait pkgmgr /ip /m:%%~na /quiet /norestart
)

これでパッチは適用されたので、あとは忘れずに再起動しておく。(/norestartがついているため)
また事前にアクティーベーションをやっておかないと、海賊版の被害にあっているのでは?というエラーが出るので注意。

実際に試したのはVistaだけだが、恐らくWindows Server 2008Windows Server 2008 R2Windows 7でも同様だと思われる。