Skip to content

Instantly share code, notes, and snippets.

@PatrickLang
Last active July 20, 2023 07:52
Show Gist options
  • Save PatrickLang/f8f3486cbbb49e0bb3f9c97e491c3981 to your computer and use it in GitHub Desktop.
Save PatrickLang/f8f3486cbbb49e0bb3f9c97e491c3981 to your computer and use it in GitHub Desktop.
Automated deployments of Windows Server 2016

This is a draft that will ultimately be blogged later. If you're seeing this after April 2017 it's probably out of date.

Making a pre-updated Windows Server 2016 ISO

Prerequisites

  1. Install the Windows Assessment and Deployment Toolkit
  2. Download a Windows Server 2016 ISO such as the trial here - TODO
  3. Download the latest cumulative update
  • Start at Windows 10 and Windows Server 2016 Update History
  • Click on the latest version in the left, for example "March 14, 2017 KB4013429 (OS Build 14393.953)"
  • Follow the "Microsoft Update Catalog" link at the bottom of the article
  • Download the appropriate Update for Windows Server 2016
  • If your ISO has a name starting with 14393.0.161119-1705.RS1_REFRESH then you can use the delta update
  • Otherwise get the cumulative update

Extracting the Old ISO

First, mount the disk image.

Mount-DiskImage D:\01-2017\14393.0.161119-1705.RS1_REFRESH_SERVER_EVAL_X64FRE_EN-US.ISO

Get the drive letter - in this case it's E

PS C:\slipstream> (get-volume | ? FileSystem -eq UDF)

DriveLetter FileSystemLabel       FileSystem DriveType HealthStatus OperationalStatus SizeRemaining    Size
----------- ---------------       ---------- --------- ------------ ----------------- -------------    ----
E           SSS_X64FREE_EN-US_DV9 UDF        CD-ROM    Healthy      OK                          0 B 6.49 GB

Create a new directory for your work, and two subdirectories for the original files (from the ISO) and mounted WIM. I used c:\slipstream, c:\slipstream\original to hold the original ISO contents, and c:\slipstream\mount for the mounted WIM.

mkdir c:\slipstream
cd c:\slipstream
mkdir original
mkdir mount

Use robocopy to copy everything to your hard disk. This will probably take a few minutes on SSD, several on HDD.

robocopy /s /e e:\ c:\slipstream\original

That's it for the original ISO. Time to unmount it.

Dismount-DiskImage D:\01-2017\14393.0.161119-1705.RS1_REFRESH_SERVER_EVAL_X64FRE_EN-US.ISO

Updating and Making a new ISO

There's a great step by step guide Service a Mounted Windows Image. If you want to learn more about how this works, please give it a read.

Here's a TL;DR version, but if you have trouble please check out that guide first.

Now, remove the read-only property from the install.wim file that we'll be modifying.

Set-ItemProperty .\original\sources\install.wim -Name IsReadOnly -Value $false

Mount the WIM file for the "Windows Server 2016 Standard Evaluation"

dism.exe /mount-wim /wimfile:"original\sources\install.wim" /mountdir:".\mount" /index:1

And apply the update. This is going to take a while and will probably look like it hangs at 1% for at least a few minutes. My Core i5-5200u laptop with SSD takes about 15 minutes.

dism.exe /image:mount /add-package:"D:\03-2017\windows10.0-kb4013429-x64_delta_24521980a64972e99692997216f9d2cf73803b37.msu"

Now that the update is applied, it's time to remove the out of date files.

dism.exe /image:mount /cleanup-image /StartComponentCleanup /ResetBase

Now finally, write all those changes into the WIM file. This is much faster than the above two steps.

dism.exe /unmount-image /mountdir:mount /commit

Last step - create the new ISO!

The Windows Assessment and Deployment Toolkit has a little known tool, oscdimg.exe that can create ISO files. Most guides say to use the Deployment and Imaging Tools Environment shortcut to access it. I'm skipping straight to the file here.

& "C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Deployment Tools\amd64\Oscdimg\oscdimg.exe" -bootdata:"2#p0,e,bboot\Etfsboot.com#pEF,e,befi\Microsoft\boot\Efisys.bin" -u1 -udfver102 C:\slipstream\original C:\slipstream\WindowsServer2016_MarchUpdated.iso
@aaronk1
Copy link

aaronk1 commented Oct 25, 2017

Great post! Thanks for sharing. Much easier to follow than Microsoft documentation, actually.

I think you may have missed a step?

Before this...

& "C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Deployment Tools\amd64\Oscdimg\oscdimg.exe" -bootdata:"2#p0,e,bboot\Etfsboot.com#pEF,e,befi\Microsoft\boot\Efisys.bin" -u1 -udfver102 C:\slipstream\original C:\slipstream\WindowsServer2016_MarchUpdated.iso

Do:

cd c:\slipstream\original

OR

maybe you can pass the full path instead of boot\Etfsboot.com do c:\slipstream\original\boot\Etfsboot.com
and
instead of efi\Microsoft\boot\Efisys.bin pass full path c:\slipstream\original\efi\Microsoft\boot\Efisys.bin

@aaronk1
Copy link

aaronk1 commented Oct 25, 2017

Another comment, it would be helpful to pass a for loop for adding the packages.

Instead of

dism.exe /image:mount /add-package:"D:\03-2017\windows10.0-kb4013429-x64_delta_24521980a64972e99692997216f9d2cf73803b37.msu"

For Loop

For my 2012R2 ISO I copied .cab files from another machine to c:\slipstream\cabs\2012r2_20171018 (forgot how I did this, but an explanation would be useful on how one gathers these cab files)

and then

$Path = "c:\slipstream\cabs\2012r2_20171018"
$Cabs = Get-ChildItem -Path "$Path" -Recurse -Include *.cab | Sort LastWriteTime
ForEach ($Cab in $Cabs){
    Add-WindowsPackage -Path c:\slipstream\mount -PackagePath $Cab.FullName
    if ($? -eq $TRUE){
        $Cab.Name | Out-File -FilePath .\Updates-Sucessful.log -Append
    } else {
        $Cab.Name | Out-File -FilePath .\Updates-Failed.log -Append
    }

@aaronk1
Copy link

aaronk1 commented Oct 25, 2017

Doesn't this remove some of the WinSXS packages, too? This makes updating the OS more difficult, right?

dism.exe /image:mount /cleanup-image /StartComponentCleanup /ResetBase

@ldabney67
Copy link

I can't get your command to make the ISO to work.

ERROR: Could not open boot sector file "boot\Etfsboot.com"

Error 3: The system cannot find the path specified.

@ldabney67
Copy link

FYI, while researching this I discovered if there is a Servicing Stack Update you need to install that first before you install other updates.

@Silvenga
Copy link

Just for reference, you can find the information to what Service Stack update to install by checking:

image

@permaiplace
Copy link

14393.0.161119-1705.RS1_REFRESH_SERVER_EVAL_X64FRE_EN-US.ISO
file size should be 6.4GB to 6.5GB... correct?

@mschomm
Copy link

mschomm commented Jul 20, 2023

Another comment, it would be helpful to pass a for loop for adding the packages.

Instead of

dism.exe /image:mount /add-package:"D:\03-2017\windows10.0-kb4013429-x64_delta_24521980a64972e99692997216f9d2cf73803b37.msu"

For Loop

For my 2012R2 ISO I copied .cab files from another machine to c:\slipstream\cabs\2012r2_20171018 (forgot how I did this, but an explanation would be useful on how one gathers these cab files)

and then

$Path = "c:\slipstream\cabs\2012r2_20171018"
$Cabs = Get-ChildItem -Path "$Path" -Recurse -Include *.cab | Sort LastWriteTime
ForEach ($Cab in $Cabs){
    Add-WindowsPackage -Path c:\slipstream\mount -PackagePath $Cab.FullName
    if ($? -eq $TRUE){
        $Cab.Name | Out-File -FilePath .\Updates-Sucessful.log -Append
    } else {
        $Cab.Name | Out-File -FilePath .\Updates-Failed.log -Append
    }

If you are using dism to add packages you could alternatively use its /PackagePath parameter instead of a loop. Dism will then simply add all packages found in this directory to the image.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment