Public/Invoke-WinBuilderTask.ps1
function Invoke-WinBuilderTask { [CmdletBinding()] Param ( [Parameter(Mandatory)] [string]$Path ) Add-LoggingTarget -Name Console -Configuration @{Level = 'DEBUG' } Set-DandIEnv if (!(Test-Admin)) { throw "Administrator rights are required!" } if (!(Test-Path $Path)) { throw "Task file not found!" } $ProjectRoot = (Get-Item -Path $Path).Directory.Parent.FullName $DriverRoot = $ProjectRoot + '\drivers' $RegisteryRoot = $ProjectRoot + '\registries' $PackageRoot = $ProjectRoot + '\packages' $content = Get-Content $Path | ConvertFrom-Json $TempDirectory = "$ProjectRoot\build\$(Get-Random)" if (!(Test-Path $TempDirectory)) { New-Item -Path "$TempDirectory" -ItemType Directory -Force | Out-Null } #====================================================================================== # Import-Image #====================================================================================== $ISOPath = "$ProjectRoot\iso\$($content.ISO)" try { if (!(Test-Path $ISOPath)) { throw "ISO file not found!`nISOPath:$ISOPath" } $DevicePath = (Mount-ISO -Path $ISOPath).DevicePath $Letter = (Get-DiskImage -DevicePath $DevicePath | Get-Volume).DriveLetter $IsoLabel = (Get-DiskImage -DevicePath $DevicePath | Get-Volume).FileSystemLabel # Create media directory $MediaPath = "$TempDirectory\media" if (!(Test-Path $MediaPath)) { New-Item -Path "$MediaPath" -ItemType Directory -Force | Out-Null } Copy-Item -Path "${Letter}:\*" -Destination "${MediaPath}" -Exclude @("boot.wim", "install.wim") -Recurse # boot.wim $ImagesInfo = Get-ImageFiles -DriveLetter $Letter -Include ("boot.wim") | Sort-Object -Property ImageIndex $ImagePath = "$TempDirectory\boot.wim" if (Test-Path $ImagePath) { Remove-Item -Force $ImagePath } $ImagesInfo | ForEach-Object { Export-Image $_.ImagePath $_.ImageIndex $ImagePath } # install.wim $ImagesInfo = Get-ImageFiles -DriveLetter $Letter -Include install.wim, install.esd $ImagePath = "$TempDirectory\install.wim" if (Test-Path $ImagePath) { Remove-Item -Force $ImagePath } $ImagesInfo | Where-Object { $content.Editions -match $_.EditionId } | ForEach-Object { Export-Image $_.ImagePath $_.ImageIndex $ImagePath } } catch { Write-Log -Level ERROR $_ throw $_ } finally { $null = Dismount-ISO -Path $ISOPath } # Create mount directory $MountPath = "$TempDirectory\mount" if (!(Test-Path $MountPath)) { New-Item -Path "$MountPath" -ItemType Directory -Force | Out-Null } #====================================================================================== # Edit-BootImage #====================================================================================== $ImagePath = "$TempDirectory\boot.wim" Get-WindowsImage -ImagePath $ImagePath | ForEach-Object { $WimImageInfo = $_ | Select-Object -Property * $WimImageArchitecture = $WimImageInfo.Architecture Write-Log -Level DEBUG "WimImageInfo: $($_.Architecture)" Write-Log -Level DEBUG "WimImageInfo: $WimImageInfo" Write-Log -Level DEBUG "Architecture: $WimImageArchitecture" if ($WimImageArchitecture -eq '0') { $WimImageArchitecture = 'x86' } if ($WimImageArchitecture -eq '6') { $WimImageArchitecture = 'ia64' } if ($WimImageArchitecture -eq '9') { $WimImageArchitecture = 'x64' } if ($WimImageArchitecture -eq '12') { $WimImageArchitecture = 'x64 ARM' } try { Write-Log -Level INFO "Mount Image..." Mount-WindowsImage -Path $MountPath -ImagePath $_.ImagePath -Index $_.ImageIndex | Out-Null Write-Log -Level INFO "Mounted Image: $MountPath" #====================================================================================== # Add-Drivers #====================================================================================== $content.BootDrivers | ForEach-Object { if ($_.EndsWith(".json")) { Add-WimDriver -Path $MountPath -JsonPath "$DriverRoot\$_" } else { Add-WimDriver -Path $MountPath -DriverPath "$DriverRoot\$_" } } #====================================================================================== # Add-Packages #====================================================================================== $content.BootPackages | ForEach-Object { $PackagePath = "$env:WinPERoot\$($content.Architecture)\WinPE_OCs\$_.cab" Add-WimPackage -Path $MountPath -PackagePath $PackagePath } } catch { Write-Log -Level ERROR $_ throw $_ } finally { Write-Log -Level INFO "Dismount Image..." Dismount-WindowsImage -Path $MountPath -Save | Out-Null Write-Log -Level INFO "Dismounted Image: $MountPath" } } $TempImagePath = "$TempDirectory\$(Get-Random).wim" Export-Image -SourceImagePath $ImagePath -DestinationImagePath $TempImagePath Move-Item -Force $TempImagePath $ImagePath # throw "test" #====================================================================================== # Edit-MainImage #====================================================================================== $ImagePath = "$TempDirectory\install.wim" $ImagesInfo = Get-WindowsImage -ImagePath $ImagePath | Sort-Object -Property ImageIndex | ForEach-Object { Get-WindowsImage -ImagePath $_.ImagePath -Index $_.ImageIndex } $ImagesInfo | ForEach-Object { try { #====================================================================================== # Mount-MainImage #====================================================================================== Write-Log -Level INFO "Mount Image..." Mount-WindowsImage -Path $MountPath -ImagePath $_.ImagePath -Index $_.ImageIndex | Out-Null Write-Log -Level INFO "Mounted Image: $MountPath" #====================================================================================== # Add-Drivers #====================================================================================== $content.Drivers | ForEach-Object { if ($_.EndsWith(".json")) { Add-WimDriver -Path $MountPath -JsonPath "$DriverRoot\$_" } else { Add-WimDriver -Path $MountPath -DriverPath "$DriverRoot\$_" } } #====================================================================================== # Add-Registries #====================================================================================== $RegFiles = $content.Registries | ForEach-Object { Get-Item "$RegisteryRoot\$_" } Import-OfflineRegistry -Path $MountPath -RegFiles $RegFiles #====================================================================================== # Deploy-AppxPackages #====================================================================================== $content.AppxPackages | ForEach-Object { if ($_.action -eq "remove") { Remove-WimAppxPackage -Path $MountPath -PackageName $_.name } } #====================================================================================== # Add-Packages #====================================================================================== $content.Packages | ForEach-Object { Dism /Image=$MountPath /Add-ProvisioningPackage /PackagePath:"$PackageRoot\$_" } } catch { Write-Log -Level ERROR $_ throw $_ } finally { #====================================================================================== # Save-Image #====================================================================================== # cmd /c pause Write-Log -Level INFO "Dismount Image..." Dismount-WindowsImage -Path $MountPath -Save | Out-Null Write-Log -Level INFO "Dismounted Image: $MountPath" } } #====================================================================================== # Clean-Image #====================================================================================== $TempImagePath = "$TempDirectory\$(Get-Random).wim" Export-Image -SourceImagePath $ImagePath -DestinationImagePath $TempImagePath Move-Item -Force $TempImagePath $ImagePath Move-Item -Path "$TempDirectory\boot.wim" -Destination "$MediaPath\sources\" Move-Item -Path "$TempDirectory\install.wim" -Destination "$MediaPath\sources\" #====================================================================================== # Add-Unattend #====================================================================================== if ($content.PSobject.Properties.name -match "Unattend") { # $DestDir = "$MountPath\Windows\Panther\Unattend" # if (!(Test-Path $DestDir)) { New-Item -Path $DestDir -ItemType Directory -Force | Out-Null } # Copy-Item -Path "$ProjectRoot\configs\$($content.Unattend)" -Destination $DestDir\Unattend.xml Copy-Item -Path "$ProjectRoot\configs\$($content.Unattend)" -Destination $MediaPath\AutoUnattend.xml } #====================================================================================== # Add-OEM-Files #====================================================================================== if ($content.PSobject.Properties.name -match "OEM") { $OemRoot = $ProjectRoot + '\oem' $OemDirectory = "$MediaPath\sources\`$OEM`$" if (!(Test-Path $OemDirectory)) { New-Item -Path $OemDirectory -ItemType Directory -Force | Out-Null } $content.OEM | ForEach-Object { Copy-Item -Path "$OemRoot\$($_.action)\*" -Destination "$OemDirectory\" -Recurse -Force $appPath = $_.path if ($_.action -eq "audit_install") { $_.packages | ForEach-Object { Copy-Item -Path "$PackageRoot\$_.exe" -Destination "$OemDirectory\`$`$\OEM\$appPath" } } if ($_.action -eq "oobe_install") { $_.packages | ForEach-Object { Copy-Item -Path "$PackageRoot\$_.exe" -Destination "$OemDirectory\`$`$\OEM\$appPath" } } } } $orderFile = Get-Content "$((Get-Item $PSScriptRoot).Parent.FullName)\Private\bootOrder.txt" $orderFile | Out-File "$TempDirectory\bootOrder.txt" -Encoding ascii $bootdata = '2#p0,e,b"{0}"#pEF,e,b"{1}"' -f ` "$MediaPath\boot\etfsboot.com", ` "$MediaPath\efi\microsoft\boot\efisys.bin" # -yo"$TempDirectory\bootOrder.txt" ` oscdimg -bootdata:"$bootdata" ` -u2 -udfver102 -l"$IsoLabel" -m -o ` "$MediaPath" "$TempDirectory\win.iso" if ($content.PSobject.Properties.name -match "Output") { Move-Item -Path "$TempDirectory\win.iso" -Destination $content.Output -Force } } |