前提条件
・WindowsServer2012R2
・PowerShell2.0以上
・ActiveDirectoryドメイン環境
・実行サーバ:ActiveDirectory(ドメインコントローラ)サーバ
⇒ホスト名:CONTOSOADSVR(こちらで操作を行う)
・実行ユーザ:Domain Adminsグループのユーザ
・適用対象サーバ:WindowsServer2012サーバ
⇒ホスト名:CONTOSOMEMSVR
・管理共有が有効であること
⇒ 「\\対象サーバ名\C$」でエクスプローラを開くと、対象サーバのCドライブ直下が参照できる状態。
前段
「いまどきWindowsサーバの更新プログラムなんて、WSUS(Windows Server Update Service)サーバで、一括で適用すればいいんじゃん」
そう思ったあなた、そこのあなた。
世の中にはWSUSを立てず、サーバを何台も管理しているシステムもあるんです。そんなふうに、Windowsサーバがたくさんあるシステムで、大量の更新プログラムを適用しなければならない状況になったら・・・。
想定
ここでは複数のサーバに対して、同一の更新プログラムを適用する場合を想定。
豆知識
Windowsサーバの更新プログラムは、大きく2つに分類されるようです。
・WindowsOSの更新プログラム
・MS製品(Office類)の更新プログラム
紹介するのは、前者のWindowsOSの更新プログラムです。これは主に「セキュリティパッチ」などとも呼ばれています。
また、以下にご紹介する手順はPowerShellと書きつつも、cmdの機能も組み合わせて利用しています。
流れ
・事前準備
・更新プログラムの確認(事前)
・更新プログラムの入手(MSUpdateカタログ)
・更新プログラムの解凍
・更新プログラムの配布
・更新プログラムの適用
・OS再起動
・更新プログラムの確認(事後)
・配布した更新プログラムの削除
事前準備
PowerShellを開いて、cdしておく。
以下は、実行サーバ:ActiveDirectory(ドメインコントローラ)サーバにて、workフォルダにチェンジディレクトリ
cd C:\work
更新プログラムの確認(事前)
事前に更新プログラムの適用状況を出力。
以下は実行サーバであるActiveDirectoryサーバで行う場合。
get-hotfix | ft HotFixID,InstalledOn -AutoSize
ftをパイプラインとして使い、必要な項目だけ出力している。主に必要となる情報は、更新プログラムのID(俗にいう”KB=KnowledgeBase”番号)と、インストール日。-AutoSizeで出力結果の文字途切れを防止している。
配布するサーバに対して、更新プログラムを出力したい場合。
get-hotfix -ComputerName CONTOSOMEMSVR | ft HotFixID,InstalledOn -AutoSize
さらにテキスト出力してログを残す場合(実施しておくと、適用後の確認がラク)。
get-hotfix -ComputerName CONTOSOMEMSVR | ft HotFixID,InstalledOn -AutoSize > CONTOSOMEMSVR-beforeKB.txt
更新プログラムの入手(MSUpdateカタログ)
以下リンクより、更新プログラムを入手する。
MicrosoftUpdate カタログ
https://catalog.update.microsoft.com/v7/site/Home.aspx
検索ボックスに「KB***」を入力すると、入手したい更新プログラムがダウンロードできます。
事前に適用対象のOS種類と、32bitなのか、64bitなのかを調べておくとベター。
今回はWindowsServer2012R2なので、必然的に64bitとなる(WindowsServerのR2シリーズは基本的に64bitのみ、2016は知らん)。
MSUpdateカタログで入手した更新プログラムは、「2018-08 Security Only Quality Update for Windows Server 2012 R2 for x64-based Systems (KBXXXXXXX)」といったフォルダでダウンロードされる。フォルダの中には「AMD64_X86-all-windows8.1-kbXXXXXXX-x64_YYYYYYY.msu」といったmsuファイルが入っている。フォルダ名もファイル名もとても長いので、事前に変更しておくとベター(マイクロソフトは嫌がらせをしているとかしか思えない・・・)。
変更前フォルダ名:2018-08 Security Only Quality Update for Windows Server 2012 R2 for x64-based Systems (KBXXXXXXX)
変更後フォルダ名:Windows_Server_2012_R2-KBXXXXXXX
変更前ファイル名:AMD64_X86-all-windows8.1-kbXXXXXXX-x64_YYYYYYY.msu
変更後ファイル名:kbXXXXXXX-x64.msu
※「X」は番号
更新プログラムの解凍
msuファイルだけでは更新プログラムの適用ができない。そのためwusaコマンドにて、msuファイルを解凍(extract)する必要がある(最近流行の「カモンベイビーアメリカ」と関連はない)。ここではActiveDirectoryサーバの「C:\work」フォルダ内に、先ほどのダウンロードしたフォルダ(とmsuファイル)を置いている。以下の手順では、解凍先もmsuファイルとと同じフォルダに解凍する場合となる。
msuファイル配置先:C:\work\Windows_Server_2012_R2-KBXXXXXXX\kbXXXXXXX-x64.msu
解凍先:C:\work\Windows_Server_2012_R2-KBXXXXXXX
wusa "C:\work\Windows_Server_2012_R2-KBXXXXXXX\kbXXXXXXX-x64.msu" /extract:"C:\work\Windows_Server_2012_R2-KBXXXXXXX"
以上はコマンドプロンプトでも実施可能(というよりcmd標準機能)。
実行すると、「C:\work\Windows_Server_2012_R2-KBXXXXXXX」フォルダに、以下のようなcabファイル(キャビネットファイル)が作られる。
「Windows8.1-KBXXXXXXX-x64.cab」
このファイルが更新プログラムのインストーラに相当する。「WSUSSCAN.cab」などのキャビネットファイルも作成されるが、こちらは利用しない。
更新プログラムの配布
コピー元サーバ「CONTOSOADSVR」内の「C:\work\Windows_Server_2012_R2-KBXXXXXXX」フォルダ(と、フォルダ内のファイルすべて)を、コピー先サーバに配布する。配布方法はrobocopyコマンドを使う。
robocopy "C:\work\Windows_Server_2012_R2-KBXXXXXXX" "\\CONTOSOMEMSVR\C$\work\Windows_Server_2012_R2-KBXXXXXXX" /R:0 /W:0 /LOG+:"C:\work\CONTOSOMEMSVR-robocopylog.txt" /TEE /XJD /XJF /V /E
コピー先は管理共有で指定。コピー先に「C:\work\Windows_Server_2012_R2-KBXXXXXXX」フォルダがなかったとしても、robocopyを使えば自動で作成してくれる。以上コマンドは、コピーに失敗した場合のリトライや再試行はさせないため(する場合、コピーに時間がかかるため)、/R:0 /W:0にて0に指定。実行時のプロンプトにもコピー結果は表示されるが、以上コマンドではrobocopyの結果をログを「C:\work\CONTOSOMEMSVR-robocopylog.txt」として残している。
更新プログラムの適用
dismコマンドにて更新プログラムの適用を行う。適用状態が表示されるため、100%表示で適用状況がわかる。以下は実行サーバであるCONTOSOADSRVで行う場合。
dism /online /add-package /PackagePath:"C:\work\Windows_Server_2012_R2-KBXXXXXXX\Windows8.1-KBXXXXXXX-x64.cab" /norestart
適用対象サーバである、CONTOSOMEMSVRに適用したい場合、ActiveDirectoryサーバから以下のリモートコマンドより適用する。
Invoke-Command CONTOSOMEMSVR -ScriptBlock { cmd /c dism /online /add-package /PackagePath:"C:\work\Windows_Server_2012_R2-KBXXXXXXX\Windows8.1-KBXXXXXXX-x64.cab" /norestart }
/norestartオプションで、更新プログラム適用後の再起動を抑止している。
OS再起動
更新プログラムを適用したら、OS再起動をする。
shutdown /r /t 0
適用対象サーバである、CONTOSOMEMSVRをOS再起動したい場合、ActiveDirectoryサーバから以下のリモートコマンドよりOS再起動を行う。
Invoke-Command CONTOSOMEMSVR -ScriptBlock { cmd /c shutdown /r /t 0 }
更新プログラムの確認(事後)
適用対象サーバである、CONTOSOMEMSVRの更新プログラム一覧を、ファイルとして取得する。
get-hotfix -ComputerName CONTOSOMEMSVR | ft HotFixID,InstalledOn -AutoSize > CONTOSOMEMSVR-afterKB.txt
事前の確認時に取得した「CONTOSOMEMSVR-beforeKB.txt」と比較すると、適用されたことを確実に確認できる。
Compare-Object -ReferenceObject $(Get-Content C:\work\CONTOSOMEMSVR-beforeKB.txt) -DifferenceObject $(Get-Content C:\work\CONTOSOMEMSVR-afterKB.txt)
配布した更新プログラムの削除
クローズ作業に相当。実行サーバでキャビネットファイルやmsuファイルを消す場合。
Remove-Item -Path "C:\work\Windows_Server_2012_R2-KBXXXXXXX" -Recurse
適用対象サーバでのキャビネットファイルやmsuファイルを消す場合(リモート)。
Remove-Item -Path "\\CONTOSOMEMSVR\C$\work\Windows_Server_2012_R2-KBXXXXXXX" -Recurse
以下は削除確認。返り値がFalseであれば、削除完了。
Test-Path "C:\work\Windows_Server_2012_R2-KBXXXXXXX"
Test-Path "\\CONTOSOMEMSVR\C$\work\Windows_Server_2012_R2-KBXXXXXXX"
まとめ
時間があればforeachなどで以上をps1スクリプトにしようかとも考えたけど、しんどくなってやめてしまった(笑)かなりルーチン的な処理なので、時間があるときに以上のスクリプト化をしてみたい。
余談
先日、映画『ミッションインポッシブル6:フォールアウト』を見たのですが、「トムクルーズのジャッキーチェン化」が止まらなくて最高でした。エンドロールにNG集がないのが不思議に感じたぐらいでした。とんでもない映像ばかりで、普段の仕事でもトムの勇姿を見習おうと思いました。
Mission: Impossible-Fallout (2018)- "All Stunts"- Paramount Pictures