Splitter is a PowerShell module for working with Windows installation ISOs and install images. It can mount media, inspect install image indexes, export selected editions, apply servicing customizations, and build edition-specific bootable ISOs.
- Edition-agnostic ISO splitting with Split-WindowsInstallMedia
- Install image discovery and export (WIM/ESD)
- Optional offline servicing support:
- Add-WindowsDriver
- Add-WindowsPackage
- Add-UnattendFile
- Optional GliderUI desktop front end via Start-SplitterUi
- Verbose, user-controlled progress output
- Supports WhatIf on destructive and media-modifying operations where applicable
- Windows with PowerShell 5.1+ or PowerShell 7+
- Required binary: dism.exe (used for image discovery/export/servicing)
- Expected from Windows: C:\Windows\System32\dism.exe
- Verify: Get-Command dism.exe
- Required binary for ISO creation: oscdimg.exe (used by Build-BootableIso and Split-WindowsInstallMedia when building an ISO)
- Expected ADK path is detected automatically by Get-OscdimgPath:
- C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Deployment Tools\amd64\Oscdimg\oscdimg.exe
- C:\Program Files\Windows Kits\10\Assessment and Deployment Kit\Deployment Tools\amd64\Oscdimg\oscdimg.exe
- Expected ADK path is detected automatically by Get-OscdimgPath:
- Chocolatey install commands (run elevated) if needed:
- Install Windows ADK: choco install windows-adk -y
- Permissions required to mount and dismount ISO images
- Optional for desktop UI: GliderUI on PowerShell 7.4+
- Install: Install-PSResource GliderUI -Scope CurrentUser
Import-Module .\Splitter.psd1 -Force
Get-Command -Module SplitterInstall-PSResource Splitter -Scope CurrentUserInstall-Module Splitter -Scope CurrentUserThe following commands are available:
- Mount-WindowsInstallMedia
- Dismount-WindowsInstallMedia
- Get-WindowsInstallImage
- Export-WindowsInstallImage
- Remove-WindowsInstallImage
- New-WindowsInstallMedia
- Split-WindowsInstallMedia
- Add-WindowsDriver
- Add-WindowsPackage
- Add-UnattendFile
- Build-BootableIso
- Start-SplitterUi
The desktop UI is available and actively improving. It is intended to make the common Splitter workflow easier to run end-to-end, while we continue refining layout and ergonomics.
If you prefer a guided desktop workflow, run:
Install-PSResource GliderUI -Scope CurrentUser
Import-Module .\Splitter.psd1 -Force
Start-SplitterUiRecommended workflow order in the UI:
- Source Media
- Split Editions
- Image Servicing
- Build Outputs
The UI keeps layout and workflow logic separated:
- View layout is in
ui/splitterui.ps1 - UI controller/event wiring is in
private/Initialize-SplitterUi.ps1 - Planning and execution helpers are in private helper functions
Screenshots:
The landing view highlights workflow navigation on the left and the active task page on the right. Start here to understand the top-level sequence before changing any settings.
This page is the entry point for every run. Use it to select the source ISO, run preflight checks, and discover available install image indexes before splitting.
This page applies customizations to extracted media. It shows driver/package/unattend actions plus payload injection for files like PowerShell MSI into sources\$OEM$\$1\Install.
This page creates final artifacts after servicing. Use Build Bootable ISO for install media and Export Install Image when you need selected indexes written to a custom WIM.
For a task-focused walkthrough of the desktop workflow, including a quick start and page-by-page playbooks, see:
docs/UI_USER_GUIDE.md
The easiest way to think about Splitter is as a 4-step workflow:
- Split the ISO into a working media folder.
- Inject files into that folder.
- Add
autounattend.xmlif you want unattended setup. - Build the final bootable ISO.
If you only want the working folder and do not want an ISO yet, use
-SkipBootableIso on Split-WindowsInstallMedia and run Build-BootableIso
later.
This is the cleanest copy-paste path when you want one edition, PowerShell 7, and an unattended install.
Import-Module .\Splitter.psd1 -Force
$sourceIso = 'C:\ISO\Server2025.iso'
$workingRoot = 'C:\work'
$outputIso = 'C:\out\Server2025_DesktopExperience-Standard.iso'
$msiSource = 'D:\Packages\PowerShell-7.6.3-win-x64.msi'
$unattendSource = 'D:\AnswerFiles\autounattend.xml'
$mount = Mount-WindowsInstallMedia -Path $sourceIso -Verbose
$baseMedia = Join-Path $workingRoot 'BaseMedia'
New-WindowsInstallMedia -SourcePath $mount.DriveRoot -DestinationPath $baseMedia -Verbose
$baseImage = Join-Path $baseMedia 'sources\install.wim'
if (-not (Test-Path $baseImage)) {
$baseImage = Join-Path $baseMedia 'sources\install.esd'
}
$selectedImage = Get-WindowsInstallImage -ImagePath $baseImage -Name '*Standard*'
$editionMedia = Join-Path $workingRoot 'Server2025_DesktopExperience-Standard'
New-WindowsInstallMedia -SourcePath $baseMedia -DestinationPath $editionMedia -Verbose
Remove-WindowsInstallImage -MediaRoot $editionMedia -Verbose
$destinationImage = Join-Path $editionMedia (Join-Path 'sources' ([System.IO.Path]::GetFileName($baseImage)))
Export-WindowsInstallImage -SourceImagePath $baseImage -DestinationWim $destinationImage -Image $selectedImage -Compression max -Verbose
Add-UnattendFile -MediaRoot $editionMedia -UnattendPath $unattendSource -Verbose
$payloadDir = Join-Path $editionMedia 'sources\$OEM$\$1\Install'
New-Item -Path $payloadDir -ItemType Directory -Force | Out-Null
Copy-Item -LiteralPath $msiSource -Destination (Join-Path $payloadDir 'PowerShell-7.6.3-win-x64.msi') -Force
Build-BootableIso -MediaRoot $editionMedia -OutputIso $outputIso -Label 'WINSTD' -Verbose
Dismount-WindowsInstallMedia -InputObject $mount -VerboseUse these when you already know the step you need.
# Discover image names and indexes
$mount = Mount-WindowsInstallMedia -Path 'C:\ISO\Windows.iso' -Verbose
$imagePath = Join-Path $mount.DriveRoot 'sources\install.wim'
if (-not (Test-Path $imagePath)) {
$imagePath = Join-Path $mount.DriveRoot 'sources\install.esd'
}
Get-WindowsInstallImage -ImagePath $imagePath | Format-Table Index, Name, Description -AutoSize
Dismount-WindowsInstallMedia -InputObject $mount -Verbose
# Split a source ISO and stop before building the ISO
Split-WindowsInstallMedia -SourceIso 'C:\ISO\Windows.iso' -EditionName 'Standard' -WorkingRoot 'C:\work' -OutputRoot 'C:\out' -SkipBootableIso -PassThru
# Split and build immediately
Split-WindowsInstallMedia -SourceIso 'C:\ISO\Windows.iso' -EditionName 'Standard', 'Datacenter' -WorkingRoot 'C:\work' -OutputRoot 'C:\out' -OutputBaseName 'WinServer_2025' -PassThru
# Inject drivers, packages, and unattend files into an existing working folder
Add-WindowsDriver -MediaRoot 'D:\Work\WindowsCustom-Standard' -DriverPath 'D:\Drivers' -Recurse -Index 1 -Verbose
Add-WindowsPackage -MediaRoot 'D:\Work\WindowsCustom-Standard' -PackagePath 'D:\Packages\kb.cab' -Index 1 -Verbose
Add-UnattendFile -MediaRoot 'D:\Work\WindowsCustom-Standard' -UnattendPath 'D:\AnswerFiles\autounattend.xml' -Verbose
# Build the final ISO from edited media
Build-BootableIso -MediaRoot 'D:\Work\WindowsCustom-Standard' -OutputIso 'D:\Out\WindowsCustom-Standard.iso' -Label 'WINSTD' -VerboseSplit-WindowsInstallMediastill builds the ISO by default so the common case stays one command.- Use
-SkipBootableIsowhen you want to stop after the media folder is ready. sources\$OEM$\$1\Installcopies files toC:\Installon the installed OS.- The MSI filename copied into
sources\$OEM$\$1\Installmust exactly match the path referenced byautounattend.xml. FirstLogonCommandsinautounattend.xmlis the simplest place to launch an MSI after setup, but it runs only after the first interactive logon.
Mount the finished ISO and confirm these paths exist before testing in a VM or on hardware:
$iso = 'C:\out\Server2025_DesktopExperience-Standard.iso'
$mount = Mount-DiskImage -ImagePath $iso -PassThru
$volume = $mount | Get-Volume
$drive = "$($volume.DriveLetter):\"
Test-Path (Join-Path $drive 'autounattend.xml')
Test-Path (Join-Path $drive 'sources\$OEM$\$1\Install\PowerShell-7.6.3-win-x64.msi')
Get-Content (Join-Path $drive 'autounattend.xml') | Select-String 'PowerShell-7.6.3-win-x64.msi'
Dismount-DiskImage -ImagePath $isoIf all three checks succeed, the ISO contains both the answer file and the MSI payload at the path the sample answer file expects.
- oscdimg.exe not found:
- Install Windows ADK Deployment Tools.
- Chocolatey install:
- choco install windows-adk -y
- Confirm path with Get-OscdimgPath after install.
- dism.exe not found:
- Confirm with Get-Command dism.exe.
- Use a standard Windows image with DISM available in C:\Windows\System32.
- No matching indexes found:
- Run Example A to list available indexes and names from the source ISO.
- Then rerun split with EditionName values that match Name or Description.
- Wildcards are supported, for example 'Enterprise'.
- Mount or dismount failures:
- Ensure elevated privileges and that no process has files locked in the mounted media.
- DISM servicing errors:
- Check DISM output and confirm package/driver compatibility with the target image index.