しばたテックブログ

PowerShellを中心に気分で書いている技術ブログです。

Nano Serverのアップデートについて私的まとめ

元ネタはこちら。

blogs.technet.microsoft.com

technet.microsoft.com

内容としては割とそのままで、正直なところ、ただの備忘録です。

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

f:id:stknohg:20170110004911p:plain

この結果から、初期イメージはBuild 14393.0、2016年07月15日更新のイメージであることがわかります。
この状態をベースとして以降アップデート手順についてまとめていきます。

1. Windows Updateでの更新

まずは一番わかりやすいWindows Updateでの更新方法について説明します。

Nano ServerではWindows Updateを直接呼び出すコマンドなどは無く、WMIを使う必要があります。

日本語版Nano Serverの問題

山市さんのブログの以下の記事にある様に初期ビルド(14393.0)の日本語版のNano Serverではこの方法が正しく動作しません。

yamanxworld.blogspot.jp

これについては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

実行結果

f:id:stknohg:20170110002305p:plain

この結果を見ると、KB3197356KB3199986KB3206632が対象となっています。

更新の適用

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

実行結果

f:id:stknohg:20170110002642p:plain

適用結果の確認

再起動後は以下の様にして適用結果を確認します。

$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

実行結果

f:id:stknohg:20170110002749p:plain

この結果を見るとKB3199986KB3206632が適用されたことがわかります。
KB3197356についてはどちらかの更新で上書きされている様です。

また、Get-ComputerInfoでOSのビルドバージョンを取得すると、

f:id:stknohg:20170110005015p:plain

と、Build 14393.576、2016年12月08日更新イメージになっており、OSが更新されたことが確認できます。

ちなみに、この更新で初期状態のvhdxファイルは 495 MB → 2.48 GB に更新されていました。

2. New-NanoServerImage、Edit-NanoServerImageでの更新

Nano ServerではNew-NanoServerImageEdit-NanoServerImageコマンドレットを使い、サーバーイメージの作成・更新時にアップデートを適用することができます。

本エントリではわかりやすたのために0. イメージの作成で作成したイメージに対してEdit-NanoServerImageを適用するケースを例示します。

前準備

この方法を実施する前に予め更新対象となるKB(ここではKB3199986KB3206632)の更新プログラムをダウンロードし、そこからcabファイルを抽出する必要があります。

各KBはWindows Update Catalogからダウンロードします。

今回の場合は、

f:id:stknohg:20170110003952p:plain

f:id:stknohg:20170110004008p:plain

  • 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\

実行結果

f:id:stknohg:20170110005224p:plain

この例の場合、抽出した、Windows10.0-KB3199986-x64.cabWindows10.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

実行結果

f:id:stknohg:20170110005528p:plain

上図の様に実行結果はログフォルダにファイルとして出力されます。

f:id:stknohg:20170110005834p:plain

New-NanoServerImageEdit-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の場合と同様の手順で更新結果を確認すると、

f:id:stknohg:20170110012357p:plain

となり、ちゃんと更新されていることがわかります。

ちなみに、この更新で初期状態のvhdxファイルは 495 MB → 873 MB に更新されていました。

3. dismでイメージを更新

前項でNew-NanoServerImageEdit-NanoServerImageコマンドレットは内部的にdism.exeを使用していると説明しましたが、直接dism.exeを使ってイメージを更新しても構いません。

こちらについては元ネタを見てもらった方が早いと思いますので具体的な手順については本エントリでは割愛します。

元ネタではMount-WindowsImageDismount-WindowsImageAdd-WindowsPackageを使ったやり方も併せて例示されています。

最後に

はっきり言ってNano Serverのアップデートは非常にめんどうくさいです。
コマンドで一発というわけにもいかず、更新自体も基本的に累積パッケージのみを提供している*1様で一度の更新にかなり時間がかかってしまいます。

あくまで私見ですが、Nano Serverは従来のWindows Serverの様に随時Widows Updateを適用するものではなく、都度最新の更新を適用したOSイメージを作り直すDisposableなモデルに感じられます。
いちばん分かりやすい例としてはDocker Hubにあるコンテナイメージで、Microsoftの手によって随時最新のイメージが更新されていき、ユーザーは常に最新のイメージを使い続けるという感じです。

この考えが正しいかはわかりませんが、とりあえず現状最新のNano Serverを扱うにはコンテナイメージを使うのが一番楽ですし、それ以外の方法だと非常にめんどうで実環境(とくにオンプレ環境での)運用は厳しいと思われます。

*1:累積パッケージのくせに複数更新あり、その依存関係がわかりにくいというおまけ付きで…