Create a Factory OS image

This lab covers how to use the Windows System Kit (WSK) to design and create a Factory OS image.

We'll cover:

  • Working from a mounted WSK ISO
  • Adding drivers
  • Adding apps
  • Adding a Test content folder
  • Customizing the device layout
  • Customizing settings
  • Generating an image

1. What you need

To complete this lab, you'll need:

  • A technician PC
  • The Windows System Kit
  • If you're creating an FFU:
  • If you're creating a VHDX image:
    • A PC with Hyper-V installed. This can be the same PC as the technician PC.
  • A folder that includes test collateral
  • (Optional) Apps to include in your image
  • (Optional) Drivers to include in your image

2. Mount the WSK ISO and launch the WSK environment

To create Factory OS images, you'll need the WSK, which contains the packages and tooling you need to create an image. You can use the WSK by copying the contents of the WSK ISO to your technician PC or by mounting the ISO from a network share or locally on your PC. In this lab, we'll mount a locally stored WSK ISO and work from there.

Mount the WSK

  1. Create a directory on your technician PC called C:\WSK and copy the WSK ISO from the Lab collateral USB drive into it.
  2. In File explorer, navigate to the WSK ISO
  3. Right-click on the ISO, and click Mount.

Open the Windows System Kit environment

Open the Windows System Kit environment:

  1. Navigate to the root of the drive assigned to the mounted WSK ISO.
  2. Right-click on SetImagGenEnv.cmd and Run as administrator.

Here's what you'll see:

**********************************************************************
** Windows System Kit image generation environment
** Version xxx.xxxxx.1001
**********************************************************************

3. Create a Factory OS workspace

A workspace is a working directory that helps organize the apps, drivers, and other assets needed to create a Factory OS image.

PrepWSKWorkspace C:\FactoryWorkSpace -Product FactoryOS

Note

If you want to create a virtual machine, add the -vm parameter to the above command:

PrepWSKWorkspace C:\FactoryWorkSpace -Product FactoryOS -VM

See PrepWSKWorkspace syntax for all available options.

Here's what you'll see in the WSK environment:

Overwrite == Prompt. PrepOEMWorkspace will prompt for permission to overwrite an existing workspace.
Prepping C:\FactoryWorkSpace as a WSK workspace for building a FactoryOS AMD64 UEFI Hardware image....
OEMInput file C:\FactoryWorkSpace\FactoryOS_Development_AMD64_UEFI_SpacesGPT_Hardware.xml created.

Success!

Per the above output, you now have a workspace at C:\FactoryWorkspace that includes an OEMInput.xml file called FactoryOS_Development_AMD64_UEFI_SpacesGPT_Hardware.xml. You'll modify this OEMInput.xml file throughout the lab. You can also view the path and filename of your OEMInput.xml by running echo %OEMInputFileName% from the WSK environment.

While creating your workspace, the WSK configured the %WSKWorkspaceRoot% environment variable that maps to your workspace. If you close and reopen the Windows System Kit environment, you'll have to re-set WSKWorkspaceRoot by changing directories to your workspace root and running SetWSKWorkspaceRoot.

4. About Feature manifests

Feature manifests define the file locations for the apps, drivers, and packages you want to include in your images. When you add apps and drivers, by default they're added into all images unless you mark them as optional.

These next sections use feature manifests to define the apps, drivers, and settings that you're including in your image.

5. Add drivers

If you're creating an FFU image for a physical device, The Windows System Kit includes scripts that make adding compatible drivers to your Factory OS images easier. These scripts automatically create or update a Feature Manifest file based on the drivers that you add to a workspace:

  • The CreateWSKDriversFM script creates a driver feature manifest and adds all of the drivers from the %WSKWorkspaceRoot%\DCHUDrivers folder into the driver feature manifest.

  • The UpdateWSKDriversFM script adds all of the rivers from the %WSKWorkspaceRoot%\DCHUDrivers folder into an existing driver feature manifest. Since a workspace includes an empty DriversFM, we'll use UpdateWSKDriversFM to add your drivers into the existing driver feature manifest. If you decide to add more drivers later, you can add additional drivers into your DCHUDrivers folder, and re-run this script.

  1. Copy drivers to your workspace:

    xcopy /s E:\Drivers\ %WSKWorkspaceRoot%\DCHUDrivers /chrkyf
    

    Where E:\Drivers\ is where you have your Factory OS-compliant drivers

  2. Add your drivers to the driver feature manifest in your workspace. An empty driver feature manifest, %WSKWorkspaceRoot\FMFiles\OEMDriversFM.xml was created and added to your OEMInput.xml when you created your workspace. The WSK includes a script that adds all of the drivers from the %WSKWorkspaceRoot%\DCHUDrivers folder into the driver feature manifest. Once the drivers are added to the OEMDriversFM feature manifest, they'll be included in your image.

    Run the script to add drivers from the DCHU drivers folder in your workspace:

    UpdateWSKDriversFM
    

    Output:

    Script will backup then append new Drivers to C:\FactoryWorkspace\FMFiles\OEMDriversFM.xml if it exists.
    Existing Drivers FM found. Backing up existing file to C:\Users\username\AppData\Local\Temp\WSKScriptBackups\OEMDriversFM.xml...
    
    Searching C:\FactoryWorkspace\DCHUDrivers for Drivers to add to C:\FactoryWorkspace\FMFiles\OEMDriversFM.xml...
    Adding C:\FactoryWorkspace\DCHUDrivers\devices.driver.display.inf to FM...
    …
    Adding C:\FactoryWorkspace\DCHUDrivers\audio.driver.inf to FM...
    
    FM file successfully created at C:\FactoryWorkspace\FMFiles\OEMDriversFM.xml.
    All newly found Drivers under C:\FactoryWorkspace\DCHUDrivers are now unconditionally in any image that includes C:\FactoryWorkspace\FMFiles\OEMDriversFM.xml.
    Remember to make apps or drivers you do not want in every image "Optional" (apps) or in a FM Feature (drivers).
    
    The previous version of C:\FactoryWorkspace\FMFiles\OEMDriversFM.xml is backed up at C:\Users\username\AppData\Local\Temp\WSKScriptBackups\OEMDriversFM.xml.
    
  3. Open your OEMInput.xml file in a text editor and verify that OEMDriversFM.xml is included in the <AdditionalFMs> element. This ensures that the drivers defined in your OEMDriversFM.xml will be included in your image. If you can't remember what your OEMInput.xml file is called, you can run echo %WSKOEMInputFileName% to see the path to your OEMInput.xml.

    <AdditionalFMs>
    <AdditionalFM>%WSKContentRoot%\FMFiles\%WSKImageArchitecture%\FactoryOS\WindowsCoreProductionFM.xml</AdditionalFM>
    <AdditionalFM>%WSKContentRoot%\FMFiles\%WSKImageArchitecture%\FactoryOS\FOSNonProductionFM.xml</AdditionalFM>
    <AdditionalFM>%WSKContentRoot%\FMFiles\%WSKImageArchitecture%\FactoryOS\WindowsCoreNonProductionFM.xml</AdditionalFM>
    <AdditionalFM>%WSKContentRoot%\FMFiles\%WSKImageArchitecture%\FactoryOS\GenericDeviceFM.xml</AdditionalFM>
    <!-- Add OEM FMs here. -->
    <AdditionalFM>%WSKWorkspaceRoot%\FMFiles\OEMAppsFM.xml</AdditionalFM>
    <AdditionalFM>%WSKWorkspaceRoot%\FMFiles\OEMDriversFM.xml</AdditionalFM>
    </AdditionalFMs>
    

6. Add apps

The Windows System Kit includes scripts that make adding compatible Apps to your Factory OS images easier. These scripts automatically create or update a Feature Manifest file based on the apps that you add to a workspace:

  • The CreateWSKAppsFM script creates an app manifest and adds all of the apps from the %WSKWorkspaceRoot%\Apps folder into the app feature manifest.

  • The UpdateWSKAppsFM script adds all of the apps from the %WSKWorkspaceRoot%\Apps folder into an existing app feature manifest. Since a workspace includes an empty AppsFM, we'll use UpdateWSKAppsFM to add new apps into the existing app feature manifest that's included by default in your OEMInput.xml.

If you have apps you want to add to your image:

  1. Copy apps to your workspace:

    Xcopy /s E:\UWP %WSKWorkspaceRoot%\Apps /chrkyf
    

    Where E:\UWP is where you're copying your UWP apps from

  2. Add your apps from the Apps folder to the OEMAppsFM.xml feature manifest. Once the apps are added to the OEMAppsFM feature manifest, they'll get included in your image:

    UpdateWSKAppsFM
    

    Here's some sample output:

    Script will backup then append new Apps to C:\FactoryWorkSpace\FMFiles\OEMAppsFM.xml if it exists.
    Existing Apps FM found. Backing up existing file to C:\Users\administrator\AppData\Local\Temp\WSKScriptBackups\OEMAppsFM_3.xml...
    
    Searching C:\FactoryWorkSpace\Apps for Apps to add to C:\FactoryWorkSpace\FMFiles\OEMAppsFM.xml...
    Adding C:\FactoryWorkSpace\Apps\Dependencies\arm\Microsoft.NET.Native.Framework.1.7.appx to FM...
    Adding C:\FactoryWorkSpace\Apps\Dependencies\arm\Microsoft.NET.Native.Runtime.1.7.appx to FM...
    Adding C:\FactoryWorkSpace\Apps\Dependencies\arm\Microsoft.VCLibs.Arm.14.00.appx to FM...
    Adding C:\FactoryWorkSpace\Apps\Dependencies\x64\Microsoft.NET.Native.Framework.1.7.appx to FM...
    Adding C:\FactoryWorkSpace\Apps\Dependencies\x64\Microsoft.NET.Native.Runtime.1.7.appx to FM...
    Adding C:\FactoryWorkSpace\Apps\Dependencies\x64\Microsoft.VCLibs.x64.14.00.appx to FM...
    Adding C:\FactoryWorkSpace\Apps\Dependencies\x86\Microsoft.NET.Native.Framework.1.7.appx to FM...
    Adding C:\FactoryWorkSpace\Apps\Dependencies\x86\Microsoft.NET.Native.Runtime.1.7.appx to FM...
    Adding C:\FactoryWorkSpace\Apps\Dependencies\x86\Microsoft.VCLibs.x86.14.00.appx to FM...
    Adding C:\FactoryWorkSpace\Apps\HelloWorld_1.0.0.0_x64.appx to FM...
    
    FM file successfully created at C:\FactoryWorkSpace\FMFiles\OEMAppsFM.xml.
    All newly found Apps under C:\FactoryWorkSpace\Apps are now unconditionally in any image that includes C:\FactoryWorkSpace\FMFiles\OEMAppsFM.xml.
    Remember to make apps or drivers you do not want in every image "Optional" (apps) or in a FM Feature (drivers).
    
    The previous version of C:\FactoryWorkSpace\FMFiles\OEMAppsFM.xml is backed up at C:\Users\administrator\AppData\Local\Temp\WSKScriptBackups\OEMAppsFM_3.xml.
    
  3. Open your OEMInput.xml file and verify that OEMAppsFM.xml is included in the <AdditionalFMs> element. This ensures that the apps defined in your OEMAppsFM.xml will be included in your image.

    You should see:

    <AdditionalFMs>
    <AdditionalFM>%WSKContentRoot%\FMFiles\%WSKImageArchitecture%\FactoryOS\WindowsCoreProductionFM.xml</AdditionalFM>
    <AdditionalFM>%WSKContentRoot%\FMFiles\%WSKImageArchitecture%\FactoryOS\FOSNonProductionFM.xml</AdditionalFM>
    <AdditionalFM>%WSKContentRoot%\FMFiles\%WSKImageArchitecture%\FactoryOS\WindowsCoreNonProductionFM.xml</AdditionalFM>
    <AdditionalFM>%WSKContentRoot%\FMFiles\%WSKImageArchitecture%\FactoryOS\GenericDeviceFM.xml</AdditionalFM>
    <!-- Add OEM FMs here. -->
    <AdditionalFM>%WSKWorkspaceRoot%\FMFiles\OEMAppsFM.xml</AdditionalFM>
    <AdditionalFM>%WSKWorkspaceRoot%\FMFiles\OEMDriversFM.xml</AdditionalFM>
    </AdditionalFMs>
    

    Note

    If you added the -VM option when you created your workspace, your OEMInput.xml will be called FactoryOS_Development_AMD64_UEFI_SpacesGPT_VM.xml.

7. Add a test content folder

The <TestContent> element in an OEMInput.xml file enables you to specify a folder that includes test content like scripts, executables, and other assets that you'll use to run tests on your Factory OS device.

Adding a test content folder when building your image ensures that test collateral is available on your Factory OS devices, and reduces the amount of time spent on manually copying files from a technician PC to a test device.

  1. Create a Test content folder in your Factory OS workspace on your technician PC:

    md %WSKWorkspaceRoot%\TestContent
    
  2. Copy your test collateral into the TestContent folder. Only one test content folder can be included in an image, but that folder can contain subfolders. Make all your test collateral is in a single test content folder:

    xcopy /s E:\TestContent %WSKWorkspaceRoot$\TestContent /chrkyf
    

    Where E:\TestContent is the folder with your test content

  3. Add your test content folder to your OEMInput.xml file. The WSK includes a script that automates this process:

    AddTestContent %WSKWorkspaceRoot%\TestContent
    

    Here's what you'll see if the folder was successfully added to your OEMInput.xml:

    Successfully saved the TestContent path in the OEMInput file.
    
  4. Open your OEMInput.xml file and verify it contains a <TestContent> element, and the element shows the path to your test content folder:

    Note

    You can get the full path and filename of your test content folder by running echo %WSKOEMInputFileName from the WSK environment.

    Here's what your <TestContent> element should look like:

    <TestContent>C:\FactoryWorkspace\TestContent</TestContent>
    

8. DeviceLayout and Device targeting

Note

If you're creating a VM, you can skip this section and move onto the next section, where we cover how to customize settings.

Customize DeviceLayout

A device layout is the blueprint for a Factory OS device's disk configuration. It describes how Microsoft, OEM, and SV content works together to create a disk layout for a Factory OS image. Device layouts are configured by using an XML file and the Windows System Kit to generate a device layout package that's specific for your device.

  1. Open %WSKWorkspaceRoot%\OEMCustomization\DeviceLayout\DeviceLayoutOEM.xml in a text editor. This file allows you to configure the characteristics of the disk that you're using.

    • Add a <DevicePath> for the <Store> with the <ID> {5a585bae-900b-41b5-b736-a4cecffc34b4}. This is where the OS will be flashed. This OS disk will have partitions configured by Microsoft.
      • Sample HDD <DevicePath> - <DevicePath>PciRoot(0x0)/Pci(0x1D,0x0)/Pci(0x0,0x0)/NVMe(0x1,00-00-00-00-00-00-00-00)</DevicePath>
      • Sample UFS <DevicePath> - <DevicePath>PciRoot(0x0)/Pci(0x12,0x5)/UFS(0x0,0x0)</DevicePath>
    • For HDDs, update any GUIDs in the device path to use wildcards (?), for example <DevicePath>PciRoot(0x0)/Pci(0x1D,0x0)/Pci(0x0,0x0)/NVMe(0x1,??-??-??-??-??-??-??-??)</DevicePath>
    • Verify that <SectorSize> matches your device.

    Here's what a sample DeviceLayoutOEM looks like:

    <OEMDeviceLayout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.microsoft.com/embedded/2004/10/ImageUpdate/v2">
        <Stores>
            <Store>
                <Id>{5a585bae-900b-41b5-b736-a4cecffc34b4}</Id>
                <StoreType>Default</StoreType>
    			<DevicePath>PciRoot(0x0)/Pci(0x1D,0x0)/Pci(0x0,0x0)/NVMe(0x1,??-??-??-??-??-??-??-??)</DevicePath>
            </Store>
        </Stores>
        <SectorSize>512</SectorSize>
        <MergeVersionTag>1</MergeVersionTag>
    </OEMDeviceLayout>
    
  2. Save and close DeviceLayoutOEM.xml.

  3. Update OEMInput so that it uses the layout file you created:

    1. Open your OEMinput.xml file in your workspace root in a text editor.
    2. Update the <DeviceLayoutType> element to GPT_SPACES_SPLIT
    <DeviceLayoutType>GPT_SPACES_SPLIT</DeviceLayoutType>
    
    1. Save your OEMInput.xml file. You can leave it open because we'll make more changes to it in the next section.

Customize Device targeting

  1. If you don't currently have it open, open your OEMInput.xml file in a text editor. You can find it at %WSKWorkspaceRoot%\FactoryOS_Development_AMD64_UEFI_SpacesGPT_Hardware.xml.

    Note

    You can run echo %WSKOEMInputFileName from the WSK environment to see the path and filename of your OEMInput.xml file.

  2. Configure the <DevicePlatformIDs> element, for example:

    <DevicePlatformIDs>
    <DevicePlatformID>Contoso.ContosoLaptop.*.1</DevicePlatformID>
    <DevicePlatformID>*.*.*.*</DevicePlatformID>
    </DevicePlatformIDs>
    
  3. Save and close your OEMInput.xml file.

9. Customize settings

When designing a Factory OS image, you can use the settings customization framework to ensure your device's settings are properly configured.

Settings are configured in XML files, which are used to create customization packages that you add into an OEMInput file. Settings are product-specific, so make sure to use settings customization files that are applicable to the device product that you're building.

  1. Create an empty settings customization XML:

    CreateWSKCustomizationsXML
    

    Output:

    Creating output folder: C:\FactoryWorkSpace\OEMCustomization\CustomizationXML
    Created output folder: C:\FactoryWorkSpace\OEMCustomization\CustomizationXML
    …
    wcosimageprep INFO ThreadId1340 Generating WCOS customization file(s)...
    wcosimageprep INFO ThreadId1340 Writing customization files to disk...
    wcosimageprep INFO ThreadId1340 CustomizationXML generation parameters: Advanced=False, Categorize=False
    wcosimageprep INFO ThreadId1340 C:\FactoryWorkSpace\OEMCustomization\CustomizationXML\CustomizationXML.xml
    wcosimageprep INFO ThreadId1340 Time elapsed 00:00:00.4587755
    CustomizationXML file(s) has been generated successfully at C:\FactoryWorkSpace\OEMCustomization\CustomizationXML.
    
  2. Open the settings customization XML in a text editor.

    notepad C:\FactoryWorkSpace\OEMCustomization\CustomizationXML\CustomizationXML.xml
    
  3. Fill in the <Identity> attributes, for example:

    <Identity OwnerName="OEMName" ReleaseType="Test" />
    
  4. For this part of the lab, we'll set:

    • If you're building an FFU, the path to your device layout
    • A version number that's displayed on the Factory OS screen, as well as within Factory Orchestrator

    In your CustomizationXML, fill in the <Value> elements for the settings you want to customize. The following settings will allow us to configure the path to the custom device layout, as well as the favorite bar item:

    Fill in the <Value> elements for the settings you want to customize. For this lab:

    Customization name Value
    OEMVersion <Value>1.1.1.1</Value>
    SplitLayoutFile <Value>C:\FactoryWorkspace\OEMCustomization\DeviceLayout\DeviceLayoutOEM.xml</Value>

    Note

    You don't need to configure SplitLayoutFile if you're creating a VM image.

    For example:

    <Customization Name="SplitLayoutFile">
        <ReadOnlyMetadata Description="OEM/SV-owned split layout file. (File must be named DeviceLayoutOEM.xml)" Type="FILE" DefaultValue="" SupportedExtensions="xml" />
        <Value>C:\FactoryWorkspace\OEMCustomization\DeviceLayout\DeviceLayoutOEM.xml</Value>
    </Customization>
    

    See Available settings for Factory OS to see the settings that are available for the Factory OS product.

  5. Save and close CustomizationXML.xml.

  6. Use the scripts in the Windows System Kit to generate an OEM customization package and add it to your OEMInput.xml file.

    CreateWSKCustomizationsFM
    

    Output:

    wcosimageprep INFO ThreadId21660 Validating arguments for external action.
    wcosimageprep INFO ThreadId21660 Assigning defaults for external action.
    wcosimageprep INFO ThreadId21660 Generating WCOS customization packages from C:\FactoryWorkspace\OEMCustomization\CustomizationXML
    …
    Customization Packages have been generated successfully at C:\FactoryWorkspace\OEMCustomization\Packages
    …
    OEMCustomizationsFM file has been generated successfully at C:\FactoryWorkspace\FMFiles\OEMCustomizationsFM.xml
    
    C:\FactoryWorkspace\FMFiles\OEMCustomizationsFM.xml has been added to the OEMInput file under the AdditionalFms element
    

10. Build your image

Run BuildWSKImage to create an FFU based on your OEMInput.xml file.

BuildWSKImage %WSKWorkspaceRoot%\FactoryOS_Development_AMD64_UEFI_SpacesGPT_Hardware.xml

Or, if you're creating a VM:

BuildWSKImage %WSKWorkspaceRoot%\FactoryOS_Development_AMD64_UEFI_SpacesGPT_VM.xml

Important

If you try to generate an image in the destination folder that already includes an .FFU images or virtual hard disks with the same name, image creation will fail with the following error:

imageapp : ERROR : ThreadId18164 OutputFile C:\FactoryOS.Output\FactoryOS_Development_AMD64_UEFI_SpacesGPT_Hardware.ffu already exists.

Prior to generating an image, make sure that your output folder doesn't already contain a generated image of the same name.

11. Flash your image

Your customized Factory OS image is built and ready to use.

12. Optional Add a driver to an image

On engineering devices, you can add a driver to an existing FFU without having to rebuild the image by using ImageApp.exe, which is included in the Windows System Kit.

Add a driver to an FFU:

ImageApp.exe C:\FactoryWorkspace.Output\FactoryOS_Development_AMD64_UEFI_SpacesGPT_Hardware.ffu /patch /drivers:E:\OfflineDriver\ /CPUType:amd64

Where E:\OfflineDriver\ is the folder that includes the sample driver (driver-test.inf) you want to add to your image.

See ImageApp /patch usage for more information and other uses.