If you’re Old Skool like me and still use MDT to produce Windows 10 Reference Images then this script may be useful to save some time and hassle.
The script basically automates the creation of the filename for the backup WIM file so that all that is required to produce a new image bi-annually (or as often as you like) is to run a Build & Capture Task Sequence which (providing the VM has access to WSUS or Microsoft Update) will include the all the latest patches.
It produces a filename in the following format which includes the Windows 10 version being captured, architecture, language and the date.
W10X64_20H2_en-GB_19042.572_2020-10-22_1525.wim
Because the date includes the time the image is captured, the filename will always be unique so there will never be an occasion where the image can’t be captured to a pre-existing WIM file being present with the same name.
The net result is that the Reference Image creation can be as simple as booting a VM, choosing a Task Sequence then collecting the WIM file it produces at the end of the process.
The script produces an MDT variable called ‘%WimFileName%‘ which is then used to populate the ‘BackupFile‘ property in the Task Sequence – this is demonstrated in the images below:
The script content is embedded below. Copy and paste into a blank text file and save as ‘Pwsh-SetWimFilename.ps1‘ and copy it into your MDT Deployment share in the following location:
DeploymentShare\Scripts\Custom
Script Content:
<#
.DESCRIPTION
Script to automate the naming of the WIM File Name during MDT OSD
.EXAMPLE
PowerShell.exe -ExecutionPolicy ByPass -File <ScriptName>.ps1 [-Debug]
.NOTES
Author(s): Jonathan Conway
Modified: 17/11/2021
Version: 1.5
Option [-Debug] switch can be run locally to output results to screen to test WIM File Name is correct
#>
Param (
[Switch]$Debug
)
Begin {
# Variables: Information from Registry
$OsRegistryInfo = Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion'
[string]$DisplayVersion = $OsRegistryInfo.DisplayVersion
[string]$ReleaseId = $OsRegistryInfo.ReleaseId
[string]$Ubr = $OsRegistryInfo.UBR
[string]$EditionId = $OsRegistryInfo.EditionID
[string]$OsCurrentBuildNumber = $OsRegistryInfo.CurrentBuildNumber
# Variables: Change 'ReleaseID' to new Windows Release naming format if Windows 10 20H2 or later
if ($ReleaseId -gt '2004' -and $ReleaseId -lt '2009') {
if ($ReleaseId -match "^(..)(01|02|03|04|05|06)$") {
[string]$ReleaseId1stHalf = $ReleaseId.Substring(0, 2)
[string]$ReleaseId2ndHalf = $ReleaseId.Substring(2, 2)
[string]$ReleaseId2ndHalfReplaced = $ReleaseId2ndHalf -replace "$ReleaseId2ndHalf", "H1"
[string]$ReleaseId = "$ReleaseId1stHalf" + "$ReleaseId2ndHalfReplaced"
}
if ($ReleaseId -match "^(..)(07|08|09|10|11|12)$") {
[string]$ReleaseId1stHalf = $ReleaseId.Substring(0, 2)
[string]$ReleaseId2ndHalf = $ReleaseId.Substring(2, 2)
[string]$ReleaseId2ndHalfReplaced = $ReleaseId2ndHalf -replace "$ReleaseId2ndHalf", "H2"
[string]$ReleaseId = "$ReleaseId1stHalf" + "$ReleaseId2ndHalfReplaced"
}
}
elseif ($ReleaseId -ge '2009') {
$ReleaseId = $DisplayVersion
}
# Variables: Information from WMI
$OsWmiInfo = Get-CimInstance -ClassName 'Win32_OperatingSystem'
# Variables: OS 'Caption' information
$Caption = $OsWmiInfo.Caption
[String]$RegExPattern = '(Microsoft\ (Windows|Hyper-V)\ (10|11|Server\ (2016.*?|2019.*?)))'
[String]$MachineOS = ($Caption | Select-String -AllMatches -Pattern $RegExPattern | Select-Object -ExpandProperty 'Matches').Value
# Variables: Media Language
[string]$OsLanguageNumberCode = $OsWmiInfo.OSLanguage
if ($OsLanguageNumberCode -eq '2057') {
$OsLanguage = 'en-GB'
}
if ($OsLanguageNumberCode -eq '1033') {
$OsLanguage = 'en-US'
}
# Variables: Date Information
$BuildDate = Get-Date -Format "yyyy-MM-dd_HHmm"
# Variables: OS Architecture
if ($OsWmiInfo.OSArchitecture -eq '64-bit') {
$Architecture = 'X64'
}
if ($OsWmiInfo.OSArchitecture -eq '32-bit') {
$Architecture = 'X86'
}
}
Process {
# Microsoft Hyper-V Server
if ($MachineOS -like 'Microsoft Hyper-V Server*') {
# Variables: Set OS Prefix
$HypervPrefix = 'HVS'
# Variables: Set Windows Server Version
$WindowsServerVersion = $MachineOS.TrimStart("Microsoft Hyper-V Server")
# Hyper-V Server: Create Wim File Name string
$WimFileName = "$HypervPrefix" + "$WindowsServerVersion" + "$Architecture" + '_' + "$OsLanguage" + '_' + "$OsCurrentBuildNumber" + '.' + "$Ubr" + '_' + "$BuildDate" + '.' + 'wim'
}
# Microsoft Windows 10
if ($MachineOS -like 'Microsoft Windows 10*') {
# Variables: Set OS Prefix
$Os = 'W10'
# Variables: OS Edition
if ($EditionId -eq 'Enterprise') {
$Edition = 'ENT'
}
if ($EditionId -eq 'IoTEnterprise') {
$Edition = 'IOT'
$ReleaseId = $OsRegistryInfo.DisplayVersion
}
if ($EditionId -eq 'EnterpriseS') {
$Edition = 'IOT'
$Channel = 'LTSC'
}
if ($EditionId -eq 'Professional') {
$Edition = 'PRO'
}
if ($EditionId -eq 'EnterpriseS') {
# Windows 10 IoT LTSC: Create Wim File Name string
$WimFileName = "$Os" + "$Architecture" + '_' + "$Edition" + '_' + "2019" + '_' + "$Channel" + '_' + "$OsLanguage" + '_' + "$OsCurrentBuildNumber" + '.' + "$Ubr" + '_' + "$BuildDate" + '.' + 'wim'
}
else {
# Windows 10: Create Wim File Name string
$WimFileName = "$Os" + "$Architecture" + '_' + "$Edition" + '_' + "$ReleaseId" + '_' + "$OsLanguage" + '_' + "$OsCurrentBuildNumber" + '.' + "$Ubr" + '_' + "$BuildDate" + '.' + 'wim'
}
}
# Microsoft Windows 11
if ($MachineOS -like 'Microsoft Windows 11*') {
# Variables: Set OS Prefix
$Os = 'W11'
# Variables: Set Display Version
$OsDisplayVersion = $OsRegistryInfo.DisplayVersion
# Variables: OS Edition
if ($EditionId -eq 'Enterprise') {
$Edition = 'ENT'
}
if ($EditionId -eq 'IoTEnterprise') {
$Edition = 'IOT'
}
if ($EditionId -eq 'Professional') {
$Edition = 'PRO'
}
# Windows 10: Create Wim File Name string
$WimFileName = "$Os" + "$Architecture" + '_' + "$Edition" + '_' + "$OsDisplayVersion" + '_' + "$OsLanguage" + '_' + "$OsCurrentBuildNumber" + '.' + "$Ubr" + '_' + "$BuildDate" + '.' + 'wim'
}
# Microsoft Windows Server
if ($MachineOS -like 'Microsoft Windows Server*') {
# Variables: Set OS Prefix
$ServerPrefix = 'WS'
# Variables: Set Windows Server Version
$WindowsServerVersion = $MachineOS.TrimStart("Microsoft Windows Server")
# Windows Server: Create Wim File Name string
$WimFileName = "$ServerPrefix" + "$WindowsServerVersion" + "$Architecture" + '_' + "$OsLanguage" + '_' + "$OsCurrentBuildNumber" + '.' + "$Ubr" + '_' + "$BuildDate" + '.' + 'wim'
}
}
End {
# If Debug is true then write WIM file name to host
if ($Debug) {
Write-Host "Caption is: `"$Caption`"" -BackgroundColor 'Green' -ForegroundColor 'Black'
Write-Host "MachineOS is: `"$MachineOS`"" -BackgroundColor 'Green' -ForegroundColor 'Black'
Write-Host "MachineOS is: `"$EditionId`"" -BackgroundColor 'Green' -ForegroundColor 'Black'
Write-Host "WIM File Name is: `"$WimFileName`"" -BackgroundColor 'Green' -ForegroundColor 'Black'
}
else {
# Set MDT Task Sequence Variable to be used to populate 'BackupFile'
$tsenv:WimFileName = "$WimFileName"
}
}
It is possible to test the output of the script by copying the script onto a device and running it with the ‘-debug’ switch. This will display the WIM Filename in the PowerShell console so you can check to see if it is correct:
/ JC