How to: customize Windows images with DISM

In the initial release of Windows Server 2008 one of the the questions which always came up was “how do I add X” – the answer was we had tools named OCSETUP and OCLIST. These have been superseded in Windows 7 and Server 2008 R2 with the new Deployment Image Servicing and Management tool (DISM.EXE). The major thing of note about DISM is that it works with both the current running windows image and with offline images. So

 DISM.exe /online /enable-feature /featurename=FailoverCluster-Core 

adds failover clustering to a running edition of Server Core,but you can add it to a mounted VHD file (see previous post) on drive V

 DISM.exe /image:V:\ /enable-feature /featurename=FailoverCluster-Core 

DISM has some of the functions of ImageX (which is in the Windows Auto Installation Kit) – the ability to list the Images in a WIM (Windows Image) file, and to mount an image into the file system, and commit the changes made to it.

 DISM.exe /mount-wim /wimfile:C:\dump\install.wim /index:1 /mountdir:c:\dump\mountDISM.exe /image:c:\dump\install.wim /enable-feature /featurename=FailoverCluster-Core DISM.exe /unmount-wim /mountdir:c:\dump\mount /commit

I thought I would have a go at reducing foot print of hyper-V server R2 (note that I’m working with the Release candidate and what is included may change before release) so I used DISM to remove the language packs, and configure the exact features I want. The following command gets a list if packeges

 dism /image:c:\dump\mount /get-packages
  Package Identity : Microsoft-Windows-Server-LanguagePack-Package~31bf3856ad364e35~amd64~de-DE~6.1.7100.0
  Package Identity : Microsoft-Windows-Server-LanguagePack-Package~31bf3856ad364e35~amd64~en-US~6.1.7100.0
  Package Identity : Microsoft-Windows-Server-LanguagePack-Package~31bf3856ad364e35~amd64~es-ES~6.1.7100.0
  Package Identity : Microsoft-Windows-Server-LanguagePack-Package~31bf3856ad364e35~amd64~fr-FR~6.1.7100.0
  Package Identity : Microsoft-Windows-Server-LanguagePack-Package~31bf3856ad364e35~amd64~ja-JP~6.1.7100.0
  Package Identity : Microsoft-Windows-ServerCore-Package~31bf3856ad364e35~amd64~~6.1.7100.0 

I want to keep the English pack and base features, and remove all the others with the remove-package option

 dism /image:c:\dump\mount /remove-Package /packageName:Microsoft-Windows-Server-LanguagePack-Package~31bf3856ad364e35~amd64~ja-JP~6.1.7100.0 

dism /image:c:\dump\mount /remove-Package /packageName:Microsoft-Windows-Server-LanguagePack-Package~31bf3856ad364e35~amd64~fr-FR~6.1.7100.0 

dism /image:c:\dump\mount /remove-Package /packageName:Microsoft-Windows-Server-LanguagePack-Package~31bf3856ad364e35~amd64~es-ES~6.1.7100.0 

dism /image:c:\dump\mount /remove-Package /packageName:Microsoft-Windows-Server-LanguagePack-Packagyue~31bf3856ad364e35~amd64~de-DE~6.1.7100.0

Next I took a look at the installed features. This list has been trimmed down to save space, and when used in the later commands the names are case sensitive

 dism /image:c:\dump\mount /get-features   Feature Name : Microsoft-Hyper-V

  State : Enabled

  Feature Name : Microsoft-Hyper-V-Configuration

  State : Enabled

  Feature Name : ServerCore-WOW64

  State : Enabled

  Feature Name : ServerCore-EA-IME

  State : Enabled

  Feature Name : NetFx2-ServerCore

  State : Disabled

  Feature Name : MicrosoftWindowsPowerShell

  State : Disabled

  Feature Name : ServerManager-PSH-Cmdlets

  State : Disabled

  Feature Name : WindowsServerBackup

  State : Disabled

You can use Get-packageInfo and Get-Feature info to get more information about the features and packages. I decided to remove the 32 bit support (WOW64) and the East Asian Language support (EA-IME), and then put in the PowerShell support.

 dism /image:c:\dump\mount /disable-feature /featureName:ServerCore-EA-IME 
dism /image:c:\dump\mount /disable-feature /featureName:ServerCore-WOW64   
dism /image:c:\dump\mount /enable-feature /featureName:NetFx2-ServerCore 

dism /image:c:\dump\mount /enable-feature /featureName:MicrosoftWindowsPowerShell 
dism /image:c:\dump\mount /enable-feature /featureName:ServerManager-PSH-Cmdlets 
dism /image:c:\dump\mount /enable-feature /featureName:BestPractices-PSH-Cmdlets

With the WIM file mounted it is also possible to copy files into it or to mount the registry hives and tweak registry settings such as allowing PowerShell scripts to run.

 reg load HKLM\MyTemp C:\Dump\mount\windows\system32\config\SOFTWAREreg add "HKLM\MyTemp\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell" /V ExecutionPolicy /t REG_SZ /d "RemoteSigned" reg Unload HKLM\MyTemp

And Finally unmount the WIM fiile

 DISM.exe /unmount-wim /mountdir:c:\dump\mount /commit

That’s done little more than scratch the surface, DISM can add drivers or patches (.MSU files) to an image, it can bring it into line with an Unattend.INF file, set input locales and timezones, even change the machine name. Now, the amount that you customize an existing WIM depends on whether or not you expect to install it enough times to make it worthwhile. It might be useful to update VHD files and of course it is the way to add features to server-Core or hyper-V installations.

Since the last post was about creating VHD files, you can guess that the next one will be about applying the images in WIM files to a VHD.