Public/New-OSBuildMultiLang.ps1
<#
.SYNOPSIS Separates an OSBuild with Language Packs into separate Image Indexes .DESCRIPTION Separates an OSBuild with Language Packs into separate Image Indexes. This will create a new OSBuild .LINK https://osdbuilder.osdeploy.com/module/functions/new-osbuildmultilang #> function New-OSBuildMultiLang { [CmdletBinding()] Param ( #Name of the new OSBuild MultiLang to create. MultiLang will be appended to the end of CustomName [Parameter(Position = 0, Mandatory = $true)] [ValidateNotNullOrEmpty()] [string]$CustomName ) Begin { #=================================================================================================== # Header #=================================================================================================== # Write-Host '========================================================================================' -ForegroundColor DarkGray # Write-Host -ForegroundColor Green "$($MyInvocation.MyCommand.Name) BEGIN" #=================================================================================================== # Get-OSDBuilder #=================================================================================================== Get-OSDBuilder -CreatePaths -HideDetails #=================================================================================================== # Get-OSDUpdates #=================================================================================================== $AllOSDUpdates = @() $AllOSDUpdates = Get-OSDUpdates #=================================================================================================== # Get-OSDGather -Property IsAdmin #=================================================================================================== if ((Get-OSDGather -Property IsAdmin) -eq $false) { Write-Warning 'OSDBuilder: This function needs to be run as Administrator' Pause Break } } PROCESS { Write-Host '========================================================================================' -ForegroundColor DarkGray Write-Host -ForegroundColor Green "$($MyInvocation.MyCommand.Name) PROCESS" Write-Warning "OSBuild MultiLang will take an OSBuild with Language Packs" Write-Warning "and create a new OSBuild with multiple Indexes" Write-Warning "Each Index will have a Language set as the System UI" Write-Warning "This process will take some time as the LCU will be reapplied" #=================================================================================================== # Get OSBuilds with Multi Lang #=================================================================================================== $AllMyOSBuilds = @() $AllMyOSBuilds = Get-OSBuilds | Where-Object {($_.Languages).Count -gt 1} | Where-Object {$_.Name -notlike "*MultiLang"} #=================================================================================================== # Select Source OSBuild #=================================================================================================== $SelectedOSBuild = @() $SelectedOSBuild = $AllMyOSBuilds | Out-GridView -Title "OSDBuilder: Select one or more OSBuilds to split and press OK (Cancel to Exit)" -PassThru #=================================================================================================== # Build #=================================================================================================== foreach ($Media in $SelectedOSBuild) { $SourceFullName = "$($Media.FullName)" $BuildName = "$CustomName MultiLang" $DestinationFullName = "$SetOSDBuilderPathOSBuilds\$BuildName" $Info = "$DestinationFullName\info" #=================================================================================================== # Copy Media #=================================================================================================== Write-Host "Copying Media to $DestinationFullName" -ForegroundColor Cyan if (Test-Path $DestinationFullName) {Write-Warning "Existing contents will be replaced in $DestinationFullName"} robocopy "$SourceFullName" "$DestinationFullName" *.* /mir /ndl /nfl /b /np /ts /tee /r:0 /w:0 /xf install.wim *.iso *.vhd *.vhdx #=================================================================================================== # Process Languages #=================================================================================================== $LangMultiWindowsImage = Import-Clixml "$DestinationFullName\info\xml\Get-WindowsImage.xml" $LangMultiLanguages = $($LangMultiWindowsImage.Languages) [int]$LangMultiDefaultIndex = $($LangMultiWindowsImage.DefaultLanguageIndex) $LangMultiDefaultName = $LangMultiLanguages[$LangMultiDefaultIndex] #=================================================================================================== # #=================================================================================================== $RegValueCurrentBuild = $null if (Test-Path "$DestinationFullName\info\xml\CurrentVersion.xml") { $RegKeyCurrentVersion = Import-Clixml -Path "$DestinationFullName\info\xml\CurrentVersion.xml" $ReleaseId = $($RegKeyCurrentVersion.ReleaseId) $RegValueCurrentBuild = $($RegKeyCurrentVersion.CurrentBuild) if ($ReleaseId -gt 2009) { Write-Host '========================================================================================' -ForegroundColor DarkGray Write-Warning "OSDBuilder does not currently support this version of Windows ... Check for an updated version" } } #=================================================================================================== # Operating System #=================================================================================================== $OSArchitecture = $($LangMultiWindowsImage.Architecture) $OSBuild = $($LangMultiWindowsImage.Build) $OSInstallationType = $($LangMultiWindowsImage.InstallationType) $OSMajorVersion = $($LangMultiWindowsImage.MajorVersion) $OSVersion = $($LangMultiWindowsImage.Version) if ($OSArchitecture -eq '0') {$OSArchitecture = 'x86'} if ($OSArchitecture -eq '6') {$OSArchitecture = 'ia64'} if ($OSArchitecture -eq '9') {$OSArchitecture = 'x64'} if ($OSArchitecture -eq '12') {$OSArchitecture = 'x64 ARM'} $UpdateOS = '' if ($OSMajorVersion -eq 10) { if ($OSInstallationType -notlike "*Server*") {$UpdateOS = 'Windows 10'} #elseif ($OSMBuild -ge 17763) {$UpdateOS = 'Windows Server 2019'} elseif ($OSMImageName -match '2016') {$UpdateOS = 'Windows Server 2016'} elseif ($OSMImageName -match '2019') {$UpdateOS = 'Windows Server 2019'} else {$UpdateOS = 'Windows Server'} } elseif ($OSMajorVersion -eq 6) { if ($OSInstallationType -like "*Server*") { if ($OSVersion -like "6.3*") { $UpdateOS = 'Windows Server 2012 R2' } elseif ($OSVersion -like "6.2*") { $UpdateOS = 'Windows Server 2012' Write-Warning "This Operating System is not supported" Return } elseif ($OSVersion -like "6.1*") { $UpdateOS = 'Windows Server 2008 R2' Write-Warning "This Operating System is not supported" Return } else { Write-Warning "This Operating System is not supported" } } else { if ($OSVersion -like "6.3*") { $UpdateOS = 'Windows 8.1' Write-Warning "This Operating System is not supported" Return } elseif ($OSVersion -like "6.2*") { $UpdateOS = 'Windows 8' Write-Warning "This Operating System is not supported" Return } elseif ($OSVersion -like "6.1*") { $UpdateOS = 'Windows 7' } else { Write-Warning "This Operating System is not supported" } } } #=================================================================================================== # OSDUpdateLCU #=================================================================================================== $OSDUpdateLCU = $AllOSDUpdates $OSDUpdateLCU = $OSDUpdateLCU | Where-Object {$_.UpdateArch -eq $OSArchitecture} $OSDUpdateLCU = $OSDUpdateLCU | Where-Object {$_.UpdateOS -eq $UpdateOS} $OSDUpdateLCU = $OSDUpdateLCU | Where-Object {($_.UpdateBuild -eq $ReleaseId) -or ($_.UpdateBuild -eq '')} $OSDUpdateLCU = $OSDUpdateLCU | Where-Object {$_.UpdateGroup -eq 'LCU'} #=================================================================================================== # Export Install.wim #=================================================================================================== if (Test-Path "$DestinationFullName\OS\Sources\install.wim") {Remove-Item -Path "$DestinationFullName\OS\Sources\install.wim" -Force | Out-Null} $TempInstallWim = Join-Path "$env:Temp" "install$((Get-Date).ToString('mmss')).wim" Write-Host "Exporting install.wim to $DestinationFullName\OS\Sources\install.wim" -ForegroundColor Cyan Export-WindowsImage -SourceImagePath "$SourceFullName\OS\Sources\install.wim" -SourceIndex 1 -DestinationImagePath "$DestinationFullName\OS\Sources\install.wim" -DestinationName "$($Media.ImageName) $LangMultiDefaultName" | Out-Null Write-Host "Exporting temporary install.wim to $TempInstallWim" -ForegroundColor Cyan Export-WindowsImage -SourceImagePath "$SourceFullName\OS\Sources\Install.wim" -SourceIndex 1 -DestinationImagePath "$TempInstallWim" -DestinationName "$($Media.ImageName)" | Out-Null $MountDirectory = Join-Path "$env:Temp" "mount$((Get-Date).ToString('mmss'))" New-Item "$MountDirectory" -ItemType Directory | Out-Null Mount-WindowsImage -Path "$MountDirectory" -ImagePath "$TempInstallWim" -Index 1 | Out-Null #=================================================================================================== # Process Indexes #=================================================================================================== foreach ($LangMultiLanguage in $LangMultiLanguages) { if ($LangMultiLanguage -eq $LangMultiDefaultName) { #=================================================================================================== # Header #=================================================================================================== Show-ActionTime Write-Host -ForegroundColor Green "$($Media.ImageName) $LangMultiDefaultName is already processed as Index 1" } else { Show-ActionTime Write-Host -ForegroundColor Green "Processing $($Media.ImageName) $LangMultiLanguage" Write-Host "Dism /Image:"$MountDirectory" /Set-AllIntl:$LangMultiLanguage" -ForegroundColor Cyan Dism /Image:"$MountDirectory" /Set-AllIntl:$LangMultiLanguage Write-Host "Dism /Image:"$MountDirectory" /Get-Intl" -ForegroundColor Cyan Dism /Image:"$MountDirectory" /Get-Intl Write-Warning "Waiting 10 seconds for processes to complete before applying LCU ..." Start-Sleep -Seconds 10 Update-CumulativeOS -Force Write-Warning "Waiting 10 seconds for processes to complete before Save-WindowsImage ..." Start-Sleep -Seconds 10 Save-WindowsImage -Path "$MountDirectory" | Out-Null Write-Warning "Waiting 10 seconds for processes to complete before Export-WindowsImage ..." Start-Sleep -Seconds 10 Export-WindowsImage -SourceImagePath "$TempInstallWim" -SourceIndex 1 -DestinationImagePath "$DestinationFullName\OS\Sources\install.wim" -DestinationName "$($Media.ImageName) $LangMultiLanguage" | Out-Null } } #=================================================================================================== # Cleanup #=================================================================================================== try { Write-Warning "Waiting 10 seconds for processes to complete before Dismount-WindowsImage ..." Start-Sleep -Seconds 10 Dismount-WindowsImage -Path "$MountDirectory" -Discard -ErrorAction SilentlyContinue | Out-Null } catch { Write-Warning "Could not dismount $MountDirectory ... Waiting 30 seconds ..." Start-Sleep -Seconds 30 Dismount-WindowsImage -Path "$MountDirectory" -Discard | Out-Null } Write-Warning "Waiting 10 seconds for processes to finish before removing Temporary Files ..." Start-Sleep -Seconds 10 Remove-Item -Path "$MountDirectory" -Force | Out-Null if (Test-Path "$TempInstallWim") {Remove-Item -Path "$TempInstallWim" -Force | Out-Null} } } END { #Write-Host '========================================================================================' -ForegroundColor DarkGray #Write-Host -ForegroundColor Green "$($MyInvocation.MyCommand.Name) END" } } |