元ネタはこちら。
内容としては割とそのままで、正直なところ、ただの備忘録です。
2017/02/28ちょっと補足
本エントリでは更新するKBに、KB3199986とKB3206632を使用していますが、元ネタでは、
- KB3176936 : 事前に必要な更新
- KB3192366 : 当時最新の累積更新
となっています。
これらはそれぞれ、
- KB3176936 → KB3199209 → KB3199986 : 事前に必要な更新
- KB3192366 → KB3206632 : 2016/12/13時点の累積更新。(ちなみに現時点ではKB4010672、2017/01/30時点の累積更新が最新の様です)
に置き換えられています。
0. イメージの作成
はじめに今回使用するNano Serverのイメージ作成手順を記載しておきます。
日本語版OSだと問題があるため(詳細は後述)、英語版OSで基本となるイメージを作成します。
英語版のWindows Server 2016のISOイメージをマウントし、以下のスクリプトを実行してイメージを作成しています。
#$MediaPath = (Get-WmiObject Win32_CDROMDrive -Filter "VolumeName='SSS_X64FREE_EN-US_DV9'").Drive $MediaPath = "E:\" # Windows 2016 ServerのISOイメージのあるドライブ $BasePath = "C:\Temp\NanoBase" $TargetPath = "C:\Temp\nanosv01.vhdx" Import-Module (Join-Path $MediaPath "\NanoServer\NanoServerImageGenerator\NanoServerImageGenerator.psm1") $Params = @{ MediaPath = $MediaPath; BasePath = $BasePath; TargetPath = $TargetPath; # デプロイの種類とエディション DeploymentType = "Guest"; Edition = "Standard"; # ホスト名とAdministratorのパスワード ComputerName = "nanosv01"; AdministratorPassword = (ConvertTo-SecureString "P@ssw0rd" -Force -AsPlainText); # リモート管理/EMS設定 EnableRemoteManagementPort = $true; EnableEMS = $true; } New-NanoServerImage @Params
見ての通り最低限の機能だけとしています。
また、実行環境はWindows 10上のHyper-Vによる仮想マシンとしています。
(仮想マシンの細かい設定については割愛します)
初期状態の確認
イメージを作成したあとはEnter-PSSession
で作成した仮想マシンに接続します。
実行例
# PowerShell Directによる接続例 $cred = Get-Credential administrator Enter-PSSession -VMName nano01 -Credential $cred
そしてGet-ComputerInfo
でOSのビルドバージョンを取得すると以下の様になります。
Get-ComputerInfo WindowsBuildLabEx
この結果から、初期イメージはBuild 14393.0、2016年07月15日更新のイメージであることがわかります。
この状態をベースとして以降アップデート手順についてまとめていきます。
1. Windows Updateでの更新
まずは一番わかりやすいWindows Updateでの更新方法について説明します。
Nano ServerではWindows Updateを直接呼び出すコマンドなどは無く、WMIを使う必要があります。
日本語版Nano Serverの問題
山市さんのブログの以下の記事にある様に初期ビルド(14393.0)の日本語版のNano Serverではこの方法が正しく動作しません。
これについてはMicrosoftがこの問題を解決した新しいビルドを同梱したISOイメージを提供してくれない限りどうしようもないです。打つ手なしです。
個人的にはNano Serverに関しては日本語OSを捨ててしまうのが得策だと思います。
更新の確認
上記の問題は置いておいて、更新の確認はMSFT_WUOperationsSession
クラスを使って以下の様にします。
$ci = New-CimInstance -Namespace root/Microsoft/Windows/WindowsUpdate -ClassName MSFT_WUOperationsSession $result = $ci | Invoke-CimMethod -MethodName ScanForUpdates -Arguments @{SearchCriteria="IsInstalled=0";OnlineScan=$true} $result.Updates
実行結果
この結果を見ると、KB3197356、KB3199986、KB3206632が対象となっています。
更新の適用
Invoke-CimMethod
を使いMSFT_WUOperationsSession.ApplyApplicableUpdates()
メソッドを呼ぶことでWindows Updateを実行します。
累積アップデートの更新のため、アップデートした結果は再起動後に反映されます。
$ci = New-CimInstance -Namespace root/Microsoft/Windows/WindowsUpdate -ClassName MSFT_WUOperationsSession Invoke-CimMethod -InputObject $ci -MethodName ApplyApplicableUpdates # 再起動後に反映 Restart-Computer; exit
実行結果
適用結果の確認
再起動後は以下の様にして適用結果を確認します。
$ci = New-CimInstance -Namespace root/Microsoft/Windows/WindowsUpdate -ClassName MSFT_WUOperationsSession $result = $ci | Invoke-CimMethod -MethodName ScanForUpdates -Arguments @{SearchCriteria="IsInstalled=1";OnlineScan=$true} $result.Updates
実行結果
この結果を見るとKB3199986、KB3206632が適用されたことがわかります。
KB3197356についてはどちらかの更新で上書きされている様です。
また、Get-ComputerInfo
でOSのビルドバージョンを取得すると、
と、Build 14393.576、2016年12月08日更新イメージになっており、OSが更新されたことが確認できます。
ちなみに、この更新で初期状態のvhdxファイルは 495 MB → 2.48 GB に更新されていました。
2. New-NanoServerImage、Edit-NanoServerImageでの更新
Nano ServerではNew-NanoServerImage
、Edit-NanoServerImage
コマンドレットを使い、サーバーイメージの作成・更新時にアップデートを適用することができます。
本エントリではわかりやすたのために0. イメージの作成で作成したイメージに対してEdit-NanoServerImage
を適用するケースを例示します。
前準備
この方法を実施する前に予め更新対象となるKB(ここではKB3199986とKB3206632)の更新プログラムをダウンロードし、そこからcabファイルを抽出する必要があります。
各KBはWindows Update Catalogからダウンロードします。
今回の場合は、
- windows10.0-kb3199986-x64_5d4678c30de2de2bd7475073b061d0b3b2e5c3be.msu
- windows10.0-kb3206632-x64_b2e20b7e1aa65288007de21e88cd21c3ffb05110.msu
の2ファイル(msu)をダウンロードします。
ダウンロードしたmsuファイルからexpand
コマンドを以下の様に実行し、cabファイルを抽出します。
expand [msuファイル] -f:* [展開先ディレクトリ]
実行例
mkdir C:\Temp\kb3199986 mkdir C:\Temp\kb3206632 expand C:\Temp\windows10.0-kb3199986-x64_5d4678c30de2de2bd7475073b061d0b3b2e5c3be.msu -f:* C:\Temp\kb3199986\ expand C:\Temp\windows10.0-kb3206632-x64_b2e20b7e1aa65288007de21e88cd21c3ffb05110.msu -f:* C:\Temp\kb3206632\
実行結果
この例の場合、抽出した、Windows10.0-KB3199986-x64.cab
、Windows10.0-KB3206632-x64.cab
の2つのcabファイルを使用します。
更新の適用
そしてEdit-NanoServerImage
の-ServicingPackagePath
パラメーターにこれらのcabファイルを指定してやることでイメージの更新をすることができます。
-TargetPath
に更新を適用するイメージ(vhdx)を指定します。
実行例
$MediaPath = "E:\" Import-Module (Join-Path $MediaPath "\NanoServer\NanoServerImageGenerator\NanoServerImageGenerator.psm1") $params = @{ ServicingPackagePath = ( 'C:\Temp\kb3199986\Windows10.0-KB3199986-x64.cab', 'C:\Temp\kb3206632\Windows10.0-KB3206632-x64.cab' ) TargetPath = 'C:\Temp\nanosv01.vhdx' } Edit-NanoServerImage @params
実行結果
上図の様に実行結果はログフォルダにファイルとして出力されます。
New-NanoServerImage
、Edit-NanoServerImage
コマンドレットは内部的にdism.exe
を使用しているため、ログフォルダにはコマンドのログとdismのログが出力されます。
コマンドのログの中身は以下の様になっておりdism.exe /Add-Package
コマンドで更新を適用していることがわかります。
# NanoServerImageGenerator.log 01/10/2017 00:09:05 ======================================== 01/10/2017 00:09:05 Edit-NanoServerImage Cmdlet Started 01/10/2017 00:09:05 ======================================== 01/10/2017 00:09:05 Edit-NanoServerImage -TargetPath:C:\Temp\nanosv01.vhdx -ServicingPackagePath:@(C:\Temp\kb3199986\Windows10.0-KB3199986-x64.cab, C:\Temp\kb3206632\Windows10.0-KB3206632-x64.cab) 01/10/2017 00:09:36 ======================================== 01/10/2017 00:09:36 Edit-NanoServerImage Cmdlet Started 01/10/2017 00:09:36 ======================================== 01/10/2017 00:09:36 Edit-NanoServerImage -TargetPath:C:\Temp\nanosv01.vhdx -ServicingPackagePath:@(C:\Temp\kb3199986\Windows10.0-KB3199986-x64.cab, C:\Temp\kb3206632\Windows10.0-KB3206632-x64.cab) 01/10/2017 00:09:36 dism.exe /Unmount-Image /MountDir:'C:\Users\********\AppData\Local\Temp\NanoServerImageGenerator\Temp\mount-windows' /Discard /LogLevel:4 /LogPath:'C:\Users\********\AppData\Local\Temp\NanoServerImageGenerator\Logs\2017-01-10_00-09-36-45\DISM.log' /Quiet 01/10/2017 00:09:36 エラー: 50 この要求はサポートされていません。 01/10/2017 00:09:39 dism.exe /Image:'C:\Users\********\AppData\Local\Temp\NanoServerImageGenerator\Temp\mount-windows' /Get-Packages /LogLevel:4 /LogPath:'C:\Users\********\AppData\Local\Temp\NanoServerImageGenerator\Logs\2017-01-10_00-09-36-45\DISM.log' /Quiet 01/10/2017 00:09:43 dism.exe /Add-Package /PackagePath:'C:\Temp\kb3199986\Windows10.0-KB3199986-x64.cab' /Image:'C:\Users\********\AppData\Local\Temp\NanoServerImageGenerator\Temp\mount-windows' /LogLevel:4 /LogPath:'C:\Users\********\AppData\Local\Temp\NanoServerImageGenerator\Logs\2017-01-10_00-09-36-45\DISM.log' /Quiet 01/10/2017 00:09:56 dism.exe /Add-Package /PackagePath:'C:\Temp\kb3206632\Windows10.0-KB3206632-x64.cab' /Image:'C:\Users\********\AppData\Local\Temp\NanoServerImageGenerator\Temp\mount-windows' /LogLevel:4 /LogPath:'C:\Users\********\AppData\Local\Temp\NanoServerImageGenerator\Logs\2017-01-10_00-09-36-45\DISM.log' /Quiet
ちなみに最初に
エラー: 50
この要求はサポートされていません。
エラーが出ていますが、これは(おそらく前回のUnmount漏れ対策のために)最初にdism.exe /Unmount-Image
を実行しているからで特に問題はありません。
更新の確認
Windows Updateの場合と同様の手順で更新結果を確認すると、
となり、ちゃんと更新されていることがわかります。
ちなみに、この更新で初期状態のvhdxファイルは 495 MB → 873 MB に更新されていました。
3. dismでイメージを更新
前項でNew-NanoServerImage
、Edit-NanoServerImage
コマンドレットは内部的にdism.exe
を使用していると説明しましたが、直接dism.exe
を使ってイメージを更新しても構いません。
こちらについては元ネタを見てもらった方が早いと思いますので具体的な手順については本エントリでは割愛します。
元ネタではMount-WindowsImage
、Dismount-WindowsImage
とAdd-WindowsPackage
を使ったやり方も併せて例示されています。
最後に
はっきり言ってNano Serverのアップデートは非常にめんどうくさいです。
コマンドで一発というわけにもいかず、更新自体も基本的に累積パッケージのみを提供している*1様で一度の更新にかなり時間がかかってしまいます。
あくまで私見ですが、Nano Serverは従来のWindows Serverの様に随時Widows Updateを適用するものではなく、都度最新の更新を適用したOSイメージを作り直すDisposableなモデルに感じられます。
いちばん分かりやすい例としてはDocker Hubにあるコンテナイメージで、Microsoftの手によって随時最新のイメージが更新されていき、ユーザーは常に最新のイメージを使い続けるという感じです。
この考えが正しいかはわかりませんが、とりあえず現状最新のNano Serverを扱うにはコンテナイメージを使うのが一番楽ですし、それ以外の方法だと非常にめんどうで実環境(とくにオンプレ環境での)運用は厳しいと思われます。
*1:累積パッケージのくせに複数更新あり、その依存関係がわかりにくいというおまけ付きで…