Public/New-OSBuildMultiLang.ps1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
<#
.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/osbuild/new-osbuildmultilang
 
.PARAMETER CustomName
Name of the new OSBuild MultiLang to create. MultiLang will be appended to the end of CustomName
#>

function New-OSBuildMultiLang {
    [CmdletBinding()]
    Param (
        [Parameter(Mandatory)]
        [string]$CustomName
    )

    Begin {
        #===================================================================================================
        # Header
        #===================================================================================================
        # Write-Host '========================================================================================' -ForegroundColor DarkGray
        # Write-Host -ForegroundColor Green "$($MyInvocation.MyCommand.Name) BEGIN"
        #===================================================================================================
        # Get-OSDBuilder
        #===================================================================================================
        Get-OSDBuilder -CreatePaths -HideDetails
        #===================================================================================================
        # 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-Host ""
        Write-Warning "This script is under Development at this time"
        
        #===================================================================================================
        # 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 = "$OSDBuilderOSBuilds\$BuildName"
            #===================================================================================================
            # 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]
            #===================================================================================================
            # 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
            


            $TempMount = Join-Path "$env:Temp" "mount$((Get-Date).ToString('mmss'))"
            New-Item "$TempMount" -ItemType Directory | Out-Null
            Mount-WindowsImage -Path "$TempMount" -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:"$TempMount" /Set-AllIntl:$LangMultiLanguage" -ForegroundColor Cyan
                    Dism /Image:"$TempMount" /Set-AllIntl:$LangMultiLanguage

                    Write-Host "Dism /Image:"$TempMount" /Get-Intl" -ForegroundColor Cyan
                    Dism /Image:"$TempMount" /Get-Intl
                    
                    Write-Warning "Waiting 10 seconds for processes to complete before Save-WindowsImage ..."
                    Start-Sleep -Seconds 10
                    Save-WindowsImage -Path "$TempMount" | 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 "$TempMount" -Discard -ErrorAction SilentlyContinue | Out-Null
            }
            catch {
                Write-Warning "Could not dismount $TempMount ... Waiting 30 seconds ..."
                Start-Sleep -Seconds 30
                Dismount-WindowsImage -Path "$TempMount" -Discard | Out-Null
            }
            Write-Warning "Waiting 10 seconds for processes to finish before removing Temporary Files ..."
            Start-Sleep -Seconds 10
            Remove-Item -Path "$TempMount" -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"
    }
}