Windows 10 1709 Reference Image

Update – 2018-03-06 – Read at the bottom

When creating a Windows 10 reference image a common issue is that the store updates will autoupdate while you are busy installing software updates and applications. This then causes sysprep to fail in giant ball of fire.

To solve this there are basically two options and for some option one doesn’t seem to work which is why I always opt for option two.

Option 1, follow the guidance for disabling auto store updates. This consists of adding a DWORD registry item to HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsStore named AutoDownload with a value of 2. More info on how to do this check out the blog over at

Option 2, is to use a WSUS and then disable internet access for the duration of the build. This can easily be achieved using PowerShell and a sprinkle of magic.

Here is how! Lets start with creating a small PowerShell Script.

param (

If (!$Disable) {
Write-Output “Adding internet block”
New-NetFirewallRule -DisplayName “Block Outgoing 80, 443” -Enabled True -Direction Outbound -Profile Any -Action Block -Protocol TCP -RemotePort 80,443

if ($Disable) {
Write-Output “Removing internet block”
Get-NetFirewallRule -DisplayName “Block Outgoing 80, 443” | Remove-NetFirewallRule


Save that into as Invoke-InternetAccess.ps1 and place the file into the MDT deployment share script folder.

Now time to set the sequence.
Add two “Run PowerShell script” steps as shown below.


For the first one just set the script name to Invoke-InternetAccess.ps1
For the second one set the script name to Invoke-InternetAccess.ps1 and parameters to –Disable

All done! Now you can run your sequence and not worry about any store updates during your build.

Update – 2018-03-06
There has been some discussion around this and there is an alternative to the way below which will work if you use MDT. The solution is a simple as it is elegant and requires very little configuration.

All you would need is to set HideShell=YES in your customsettings.ini. This will not load a full explorer and hence store will not start and there will be no store updates downloaded.


Happy deploying


Windows Server 2016 Ref Image

Update 2016-10-20: VL media has been release and should be used for production environments. I have also added the servicing update for 2016 that is needed to get a more complete image.

During Ignite Windows Server 2016 was released as an Eval product. This means you can now download and start testing the RTM version of 2016 and prepare for when the volume license bits arrive sometime later this fall.

As with previous version of Windows Server it makes sense to create a reference image to include needed zero day patches and Visual C++ runtimes for any applications you might need to run.

To create a reference image we use Microsoft Deployment Toolkit and guidance on how to set that up can be found on TechNet here: The same principals for Windows 10 applies to Windows Server 2016 with a few differences.

So lets start with importing the operating system this is the same as on the client side, just keep in mind to keep the folder name short to avoid issues with filenames in subfolder getting to long.


Next we create the a Package folder and import the zero day patch with fixes for Storage Spaces Direct (S2D). The patch is at current writing missing a knowledge article but can be found in the update catalog. Search for KB3192366 or use this link

As KB3192366 is an update rollup you will also need the matching service stack update. For 2016 and Windows 10 that is KB3176936 found here

When the folder has been created and the patch imported it should look something like this


Continue with creating a Selection Profile to make sure that when the image is deployed only the relevant patches for WS2016 is imported. Expand the Advanced Configuration in MDT, select the node called Selection Profiles. Create a new profile and select the folder created in the step above.


We also need an application to install the Visual C++ runtimes to make it as easy as possible use the following from the friendly bunny


Next you need to create the task sequence by following the short wizard. When the sequence is created there are a couple of things to sort out.

First off we need to use the selection profile we created earlier. To do that open up the sequence and in the Preinstall section find the step called Apply Patches. To the right you will find a dropdown that is preset to All Packages, this needs to be changed to the Selection Profile created.


The second item to change is to turn on Windows Update in the sequence which is disabled by default. The two Windows Update steps can be found in the State Restore phase. Make sure to untick the Disable this step check box for each of them.


Add the C++ runtimes application to your sequence just above the first Windows Update step to make sure that any patches available for them will be applied as well.


The last thing is to change the default behavior of Windows Update. To to that we need to change a value in the unattend.xml file used by this sequence. Browse to your deployment share and to the Control folder. In here there will be a folder with the same name as the ID of your newly created sequence. Inside of that folder you will find the unattend.xml file, edit the file with Notepad or any other xml compatible editor.

Find the OOBE Section and the value called ProtectYourPC. Change the value from 1 to 3. This will disable Windows Update until MDT is ready to use it and MDT will the turn the feature back on.


That’s it your all set. This can now be run as part of your image factory setup, as a stand alone sequence with either VmWare or Hyper-V as the virtual machine platform.

If you want more information on the Image Factory check Mikes blog here

And if you want more detailed information on the setup and how to skip wizard panes during your reference image creation check Johan’s blog here

Happy deploying!


MDT Database and custom values

I recently wrote a post on why I use the MDT database and how to set it up, the link to the post is here There will almost always be scenarios that are not covered by the built-in features of MDT/SCCM and for this the database is excellent. The fact is that is supported and encouraged to extend the MDT database to cover other scenarios as well.

So this post will cover extending the database and using those custom values in a sequence.

Part 1 – Extending the database

First up is extending the database to have placeholders for whatever value you need. So on your MDT database box launch SQL management studio and open up your database.

Expand the tables view and then the table called dbo.settings. You will then have a “folder” called Columns. If you expand that you can see all the current settings on each object in the database.


Now just right click columns and select New Column.

You will be presented with a nice list on the right side, note that the last box is empty. Type in the name of the variable you want to create, in this case I will call it WSUS. Next you need to specify the type of value stored in the variable. For simplicity create a nvarchar(50) for this. This will create a stringvalue with a maximum of 50 characters. Don’t forget to save the table.


Well that’s all well and good but if you now look inside the MDT workbench you won’t be able to find the new value. This is because the rest of the databases needs to be refreshed. To do this we use a small SQL script. To run this create a new query and make sure it points to your MDT database.

Then run the following query:

EXECUTE sp_refreshview ‘[dbo].[ComputerSettings]’
EXECUTE sp_refreshview ‘[dbo].[LocationSettings]’
EXECUTE sp_refreshview ‘[dbo].[MakeModelSettings]’
EXECUTE sp_refreshview ‘[dbo].[RoleSettings]’

Note that there are single quote signs around the tables being refreshed. Make sure they are copied correctly from the website.

Run the query and then you can see the value inside the Workbench.


(Yes I have included other variables as well but for now we will focus on the WSUS variable)

Part 2 – Using the values

Now let’s put that variable to good use. The variable can be set either on the computer object or a role or any other way you want to.

Here I have created a role and named it DebugRole and then set the value WSUS to OFF. Next we need to make sure we can use the value so open up Customsettings.ini and have a look at the second row called Properties. If you already have custom properties(variables) its fine and you should already know how this work but if not here is how it works.

The row is a simple comma delimited row. So it will look something like this Properties=MyCustomProperty, WSUS

If you have more options its fine just add them before or after with a comma between each.

Ok when a computer that has the role is not image the value WSUS will be set to NO, well that’s just a value than that in itself will do nothing so now what?

In your customsettings.ini under the [Default] block add a line saying WSUS=ON. Open up your task sequence and scroll down to the steps for Windows update (pre and post application) and go to the Options tab on each of them. First make sure the are enabled by deselecting the default option to “disable this step” then click the add button and add a Task Sequence variable. Set the name to WSUS and the option to Equals ON.


Now it’s done! Your sequence will use a custom database value during deployment.

So how will this work then. Well a computer that has been assigned the role of DebugRole will have the WSUS variable set to OFF and as such it will not run the steps for Windows update.

This will decrease the time it takes to image a computer, making your testing faster. If you have other steps in your sequence, they can of course have the same type of condition on them and you can name the condition something like Debug instead and have a lot of steps that should run when debugging.

As a last note, the above have been done in MDT and the workbench but works the same way for SCCM with MDT integration. Haven’t integrated your SCCM with MDT? Do it now!



WSUS and the broken cleanup wizard

For some reason most seem to think that after installing Windows Update Services all is fine and the server can be forgotten and left in a dark corner. I know today we talke about pets and cattle, servers that we care about and servers we replace with new as soon as something is not 100% with them. However a WSUS server is not cattle it is a pet and needs some TLC to continue running smoothly.

The most common problem with a WSUS server is that the DB grows out of control due to not beeing clean up. Since WSUS has been left in a dark corner chances are that it is still running Windows Server 2008 R2 and the powershell cmdlets to WSUS in 2008 R2 is in diplomatic words limited. So again doing what most do, you run the cleanup wizard manual once every eon right?

And when that eon finaly comes around the wizard can’t complete due to the amount of patches and time it takes to clean them.

There are ways of cleaning up even the most horrible setup of WSUS using store procedures inside the database. This is however VERY time consuming. What you instead should do is run a cleanup script that automates the job of the cleanup process for you. A simple scheduled task that runs a script that initiates the clean up and logs the output to a nice log you know whats going on.

I have seen a couple online and most are either limited in their logging or are written for 2012 R2 wich has some nice cleanup cmdlets built in to powershell. So I have written my own and you can find the script here

I would recommend you create a scheduled task that runs this weekly with the following commandline “cmd.exe /c PowerShell.exe -ExecutionPolicy Bypass -File <Path To File>\Cleanup-Wsus.ps1”

If you run this from the same folder i use (C:\Script) the script will work with the above line if you have another folder add the following after the filename “-logfile <Path to use\Logname.log>” and it will use that instead.

If you want to read more about the script just use get-help cleanup-wsus.ps1

Keep your WSUS happy!