“Permanently” inject files into your boot images

When working with OS deployment, it’s sometimes nice to have some extra tools at hand during the Windows PE phase. This requires that the files are included in the boot image. One way to include the files is to fire up dism.exe, mount winpe.wmi, copy the files and commit the changes.  Manual work is boring, so why not make sure it happens automatically every time the boot image is rebuilt?

The method described here is, to my knowledge, not supported by Microsoft, and the changes may be overwritten when a new version of ConfigMgr is installed. So it’s not a one-timer, but it is pretty damn close.

By the way – Mike Terrill already wrote a great post on this one, which inspired to most of the content below.

Adding files to the boot image

Files are added to the boot image when it is rebuild, which is done when you select Update Distribution Point on the boot image in the ConfigMgr Console. However, the build process needs to know which files to include. This is where osdinjection.xml comes into play. This guy specifies which files to add to the boot image, and where to get them from.

Locate the file <ConfigMgr Installation Folder>\bin\X64\osdinjection.xml. The first thing you want to do is to make a backup of this file, since errors in this file will prevent you from updating your boot images.

The osdinjection.xml file is structured like this:

<?xml version="1.0" encoding="utf-8"?>
<InjectionFiles>
	<Architecture imgArch="i386">
		<FileList source="WPE">
			<File name="boot.sdi">
				<LocaleNeeded>false</LocaleNeeded>
				<Source>x86\Media\Boot</Source>
				<Destination>sms\boot</Destination>
			</File>
			...
		</FileList>
		<FileList source="WDT">
		...
		</FileList>
		<FileList source="SCCM">
		...
		</FileList>
	</Architecture>
	<Architecture imgArch="x64">
		<FileList source="WPE">
		...
		</FileList>
		<FileList source="WDT">
		</FileList>
		<FileList source="SCCM">
		...
		</FileList>
	</Architecture>
	<Architecture imgArch="ia64">
		...
	</Architecture>
</InjectionFiles>

The file contains three architecture sections, one for 32-bit boot images (<Architecture imgArch=”i386″>), one for 64-bit boot images (<Architecture imgArch=”x64″>) and finally one for the 64-bit Itanium architecture, which you probably won’t use.

Each architecture section has multiple lists of files (<FileList source=”WPE”>), where the attribute source=”..” specifies where the files should be copied from:

Source Component Resolves to path (at least in my environment)
WPE Windows ADK D:\Program Files (x86)\Windows Kits\8.1\Assessment and Deployment Kit\Windows Preinstallation Environment
WDT Windows ADK D:\Program Files (x86)\Windows Kits\8.1\Assessment and Deployment Kit\Deployment Tools
SCCM ConfigMgr D:\Program Files\Microsoft Configuration Manager\OSD

One <File> section exists for each file, and the <Source></Source> tags in there denotes the relative path to the file. Thus, in the example above, the file boot.sdi would be found in “D:\Program Files (x86)\Windows Kits\8.1\Assessment and Deployment Kit\Windows Preinstallation Environment\x86\Media\Boot”.

What to add to the boot image?

Now we’ve got the explanatory part done, on with the useful part.. What to add to the boot image.

You could add a file smsts.ini to the Windows directory (in Windows PE) to increase the size of the smsts.log. This would be useful if you would want to avoid truncating the smsts.log (I find it nice to be able to have one smsts.log file containing all the events throughout the OS deployment, and this one is a step in the right direction).

To do this, browse to D:\Program Files (x86)\Windows Kits\8.1\Assessment and Deployment Kit\Windows Preinstallation Environment, create the folder Custom and in that folder create smsts.ini and paste the following into it:

[Logging]
LogMaxSize=5242880
LogMaxHistory=5

Returning to osdinjection.xml paste the following <File>..</File> code into the file under the “i386” section:

<Architecture imgArch="i386">
	<FileList source="WPE">
		<File name="smsts.ini">
			<LocaleNeeded>false</LocaleNeeded>
			<Source>Custom</Source>
			<Destination>Windows</Destination>
		</File>

And for the 64-bit boot image:

<Architecture imgArch="x64">
	<FileList source="WPE">
		<File name="smsts.ini">
			<LocaleNeeded>false</LocaleNeeded>
			<Source>Custom</Source>
			<Destination>Windows</Destination>
		</File>

This would cause smsts.ini to be copied into the boot image at C:\Windows.

You could also inject powercfg.exe into Windows PE if you would want to speed up the deployment time. This file is not included by default in Windows PE. If you add it, and set the power-schema to High Performance, it will speed up things for you, such as the “Applying image” part of the “Apply Operating System Image” step.

I will write more on this one in an upcoming post.

Rebuilding the boot image

When you are done altering osdinjection.xml, you locate the boot image in ConfigMgr Console, right-click and select Update Distribution Points:

31-07-2015-11-59-52

This will launch the Update Distribution Point Wizard, which is an easy Next, Close:

31-07-2015-12-02-16

31-07-2015-12-02-42

31-07-2015-12-03-44

And you’re done 🙂

When building the boot image goes wrong

If you do get an error saying Failed to insert OSD binaries into the mounted WIM file, you are able to inspect the log-file c:\Windows\Logs\DISM\DISM.log, since the ConfigMgr UI won’t provide you with any more information. I have found it rather difficult to locate the errors in DISM.log. and instead I look at the changes I’ve made to the osdinjection.xml, compared with the backup of osdinjection.xml.

Things to look for in osdinjection.xml when troubleshooting:

  • Are the name of the added files correct?
  • Are the files physically located where ConfigMgr expect to find them (the source-folder)
  • Are there any syntax errors in osdinjection.xml?

Mounting the boot image manually

If you want to view the files in your boot image, you can mount it using the following command:

Dism /Mount-WIM /Wimfile:"J:\OSD\BootImages\WinPE 5.0 x64\winpe.MTL0000C.wim" /index:1 /MountDir:J:\MountPoint

Make sure that the folder C:\MountPoint exists, or dism will reprove you. Notice that it is the file winpe.MTL0000C.wim, and not the adjacent file winpe.win, which is mounted. That file is the one that contains the added files (and the one that is used when booting). The /index parameter tells which image should be used in the single-instance storage file. A WIM file can contain multiple images, which can use the same files to save storage. Because of this, a WIM file can contain multiple Windows versions without gaining too much weight.

Now you are free to browse through the files in C:\MountPoint (or change the files for that matter, but that would defeat the purpose of ensuring that the files are present each time the boot image is updated).

When you are done looking, use the following command to unmount it:

Dism /Unmount-WIM /mountdir:J:\Mountpoint /discard

You must specify either /discard or /commit when unmounting. Once I received a “Error 50: The request is not supported” when trying to unmount with /discard. Restarting the computer solve that one.

More info on DISM commands can be found here: https://technet.microsoft.com/en-us/library/hh824814.aspx

Happy booting 🙂

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s