Windows Vistaにオフラインでパッチをあてる
どうしてもオンラインにできないVistaマシンに、セキュリティパッチを当てなければならなくなったので方法を調べてみた。もちろん毎回手でパッチをダウンロードしてきてもできるが、本当に必要なパッチがどれなのかハッキリしないし、手間を省きたい。
まず、Microsoft Baseline Security Analyzer(MBSA)を利用して、どのパッチが必要なのかをレポートさせる。
MBSAをオフラインで実行する http://www.atmarkit.co.jp/fwin2k/win2ktips/1053mbsascan/mbsascan.html
基本的にMBSAはGUIのアプリケーションだが、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 UpdateやMicrosoft 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 2008やWindows Server 2008 R2、Windows 7でも同様だと思われる。