Skip to content

Instantly share code, notes, and snippets.

@ITPirate
Created February 15, 2017 12:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ITPirate/402a86c9a3221a759628e841b9c09b80 to your computer and use it in GitHub Desktop.
Save ITPirate/402a86c9a3221a759628e841b9c09b80 to your computer and use it in GitHub Desktop.
Customizing_Install_WIM
#╔════════════════════════════════╦════════════════════════════════════════════╗
#║ ║ Customizing Windows10 install.wim ║
#╠════════════════════════════════╩════════════════════════════════════════════╣
#║ Author : Tim Tacin <tim.tacin@weka.de> ║
#║ Created : 15.10.2015 ║
#║ Edited : 08.07.2016 ║
#║ Version : 5.1 ║
#╚═════════════════════════════════════════════════════════════════════════════╝
<#
═══Version info:═══════════════════════════════════════════════════════════=
Version: 5.1
- new: Support for Windows 7/8/8.1/10
- new: Multisource support
- new: Windows 7 with IE11 integration
- new: Jobs with a long duration run in a separate thread
════════════════════════════════════════════════════════════════════════════
Version: 4.0
- new: Added customized StartLayout (If you use a link for Internet Explorer in the StartLayout, then the link for the Internet Explorer must be located in the same folder!)
- new: Added ability to set standard App association
════════════════════════════════════════════════════════════════════════════
Version: 3.1
- BugFix: Support for english Windows versions
════════════════════════════════════════════════════════════════════════════
Version: 3.0
- new: Added Changelog
- new: Added ability to disable "NON" MS APPX since W10 1511 for all users
- new: Added ability to enable/disable features (for NetFx3 the folder /sources/sxs must be available)
════════════════════════════════════════════════════════════════════════════
Version: 2.0
- new: Added removal of build in apps and integration of patches for Win 8.1
- new: Added patches to logfile
- new: ignore failed patches and write entry to logfile
- Bugfix: Fixed a GUI crash during patch integration
════════════════════════════════════════════════════════════════════════════
Version: 2.0
- APPX can be removed
- Ability to integrate PPKGs from WICD
- Ability to remove OneDrive for all users
- Ability to integrate patches
════════════════════════════════════════════════════════════════════════════
#>
cls
###--- Variables ---###
[string]$Global:adkPath = "C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Deployment Tools\amd64\DISM"
[string]$Global:wimPath = "C:\"
[string]$Global:wimmountPath = "C:\"
[string]$Global:startlayoutPath = "C:\"
[string]$Global:startlayoutIELinkPath = ""
[string]$Global:fileassociationPath = "C:\"
[bool]$Global:wimmountPathCreated = $false
[bool]$Global:ondriveCheck = $false
[array]$Global:appxList = @()
[array]$Global:appxselectedList = @()
[array]$Global:ppkgList = @()
[bool]$Global:formClose = $false
[string]$Global:FolderName = ""
[string]$Global:logFile = ""
[string]$Global:patchPath = ""
[bool]$Global:patchesCheck = $false
[bool]$Global:patchie11 = $false
[string]$Global:patchie11path = "C:\"
[array]$Global:selectedFeaturesEnable = @()
[array]$Global:selectedFeaturesDisable = @()
[bool]$Global:appxAdvertisingCheck = $false
[bool]$Global:appFeedbackCheck = $false
[bool]$Global:appContactSupportCheck = $false
[bool]$Global:starlayoutCheck = $false
[bool]$Global:fileassociationCheck = $false
[string]$Global:edition = ""
###--- Load Assenbly ---###
[Reflection.Assembly]::LoadWithPartialName("PresentationFramework") | Out-Null
[Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") | Out-Null
###--- Funktions ---###
#--- Write Logfile ---#
Function Write-LogFile() {
Param(
[string]$Message
)
If([string]::IsNullOrEmpty($Global:logFile) -eq $false) {
Write-Host $Message
Write-Output $Message | Out-File $Global:logFile -Append
}
}
#--- Show an Open Folder Dialog and return the directory selected. ---#
function Read-FolderBrowserDialog() {
param(
[string]$Message,
[string]$InitialDirectory,
[switch]$NoNewFolderButton
)
$browseForFolderOptions = 0
if ($NoNewFolderButton) {
$browseForFolderOptions += 512
}
$app = New-Object -ComObject Shell.Application
$folder = $app.BrowseForFolder(0, $Message, $browseForFolderOptions, $InitialDirectory)
if ($folder) {
$selectedDirectory = $folder.Self.Path
} else {
$selectedDirectory = ''
}
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($app) > $null
return $selectedDirectory
}
#--- Show an Open File Dialog and return the file selected. ---#
function Read-OpenFileDialog() {
param(
[string]$WindowTitle,
[string]$InitialDirectory,
[string]$Filter = "All files (*.*)|*.*",
[switch]$AllowMultiSelect
)
$openFileDialog = New-Object System.Windows.Forms.OpenFileDialog
$openFileDialog.Title = $WindowTitle
if (![string]::IsNullOrWhiteSpace($InitialDirectory)) {
$openFileDialog.InitialDirectory = $InitialDirectory
}
$openFileDialog.Filter = $Filter
if ($AllowMultiSelect) {
$openFileDialog.MultiSelect = $true
}
$openFileDialog.ShowHelp = $true # Without this line the ShowDialog() function may hang depending on system configuration and running from console vs. ISE.
$openFileDialog.ShowDialog() > $null
if ($AllowMultiSelect) {
return $openFileDialog.Filenames
} else {
return $openFileDialog.Filename
}
}
#--- Generate Folder Name ---#
function Get-RandomFolderName() {
param(
[int]$length
)
$chars=[char[]]"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$rndFolderName = ($chars | Get-Random -Count $length) -join ""
return $rndFolderName.ToString()
}
#--- Show ErrorMessage ---#
Function Show-ErrMsg() {
Param(
[string]$message,
[string]$title = "Error!"
)
[System.Windows.Forms.MessageBox]::Show($message,$title,0,[System.Windows.Forms.MessageBoxIcon]::Exclamation) | Out-Null
}
#--- Check Features ---#
function RunspaceCheckFeatures {
param($syncHash,$mountpath)
$syncHash.Host = $host
$Runspace = [runspacefactory]::CreateRunspace()
$Runspace.ApartmentState = "STA"
$Runspace.ThreadOptions = "ReuseThread"
$Runspace.Open()
$Runspace.SessionStateProxy.SetVariable("syncHash",$syncHash)
$Runspace.SessionStateProxy.SetVariable("mountpath",$mountpath)
$code = {
$syncHash.Window.Dispatcher.Invoke(
[action]{
$syncHash.grid_feature_3.Visibility = "Visible"
$syncHash.grid_feature_3_1.Visibility = "Visible"
})
# Check features
$allFeatures = DISM /Image:$mountpath /Get-Features /FORMAT:List | Where-Object { $_.Contains("Name") -OR $_.Contains("name") -OR $_.StartsWith("Stat") }
$features = new-object System.Collections.ArrayList
for($i = 0; $i -lt $allFeatures.length; $i=$i+2) {
$feature = $allFeatures[$i]
$state = $allFeatures[$i+1]
$features.add(@{Status=$state.split(":")[1].trim();FeatureName=$feature.split(":")[1].trim()}) | OUT-NULL
}
foreach ($item in $features){
If ($item.Status.StartsWith("D")){
$syncHash.listbox_feature_d.Items.Add($item.FeatureName)
} else {
$syncHash.listbox_feature_a.Items.Add($item.FeatureName)
}
}
$syncHash.Window.Dispatcher.invoke(
[action]{ # Load new canvas
$syncHash.can_addppkg.Visibility = "Hidden"
$syncHash.can_w7patch.Visibility = "Hidden"
$syncHash.can_features.Visibility = "Visible"}
)
}
$PSinstance = [powershell]::Create().AddScript($Code)
$PSinstance.Runspace = $Runspace
$job = $PSinstance.BeginInvoke()
}
#--- Finalize ---#
function RunspaceFinalize {
param($syncHash,$mountpath,$appxlist,$ppkglist,$patchcheck,$patchpath,$patchie11,$patchie11path,$featuresenable,$wimpath,$featuresdisable,$log)
$syncHash.Host = $host
$Runspace = [runspacefactory]::CreateRunspace()
$Runspace.ApartmentState = "STA"
$Runspace.ThreadOptions = "ReuseThread"
$Runspace.Open()
$Runspace.SessionStateProxy.SetVariable("syncHash",$syncHash)
$Runspace.SessionStateProxy.SetVariable("mountpath",$mountpath)
$Runspace.SessionStateProxy.SetVariable("appxlist",$appxlist)
$Runspace.SessionStateProxy.SetVariable("ppkglist",$ppkglist)
$Runspace.SessionStateProxy.SetVariable("patchcheck",$patchcheck)
$Runspace.SessionStateProxy.SetVariable("patchpath",$patchpath)
$Runspace.SessionStateProxy.SetVariable("patchie11",$patchie11)
$Runspace.SessionStateProxy.SetVariable("patchie11path",$patchie11path)
$Runspace.SessionStateProxy.SetVariable("featuresenable",$featuresenable)
$Runspace.SessionStateProxy.SetVariable("wimpath",$wimpath)
$Runspace.SessionStateProxy.SetVariable("featuresdisable",$featuresdisable)
$Runspace.SessionStateProxy.SetVariable("log",$log)
$code = {
$resultcount = 0
$MessageLine = "============================================================="
# Remove APPX from install.wim
if ($appxlist.Count -gt 0){
Write-Output $MessageLine | Out-File $log -Append
$Message = "=== Removed APPX Packages: =================================="
Write-Output $Message | Out-File $log -Append
$syncHash.Window.Dispatcher.Invoke(
[action]{
$syncHash.txtb_finish.Text = "Remove APPX - Please wait..."
$syncHash.listbox_result.Items.Add($MessageLine)
$syncHash.listbox_result.Items.Add($Message)
$syncHash.listbox_result.Items.MoveCurrentToLast()
$syncHash.listbox_result.ScrollIntoView($syncHash.listbox_result.Items.CurrentItem)}
)
foreach ($package in $appxlist){
Write-Output $package | Out-File $log -Append
$syncHash.Window.Dispatcher.Invoke(
[action]{
$syncHash.listbox_result.Items.Add($package)
$syncHash.listbox_result.Items.MoveCurrentToLast()
$syncHash.listbox_result.ScrollIntoView($syncHash.listbox_result.Items.CurrentItem)}
)
Remove-AppxProvisionedPackage –Path $mountpath –PackageName $package
}
$syncHash.Window.Dispatcher.Invoke(
[action]{
$syncHash.listbox_result.Items.Add($MessageLine)
$syncHash.listbox_result.Items.MoveCurrentToLast()
$syncHash.listbox_result.ScrollIntoView($syncHash.listbox_result.Items.CurrentItem)}
)
Write-Output $MessageLine | Out-File $log -Append
}
# PPKG integration
if ($ppkglist.Count -gt 0){
Write-Output $MessageLine | Out-File $log -Append
$Message = "=== Integrated PPKG: ========================================"
Write-Output $Message | Out-File $log -Append
$syncHash.Window.Dispatcher.Invoke(
[action]{
$syncHash.txtb_finish.Text = "Integrate PPKG - Please wait..."
$syncHash.listbox_result.Items.Add($MessageLine)
$syncHash.listbox_result.Items.Add($Message)
$syncHash.listbox_result.Items.MoveCurrentToLast()
$syncHash.listbox_result.ScrollIntoView($syncHash.listbox_result.Items.CurrentItem)}
)
foreach ($ppkgpackage in $ppkglist){
$Message = $ppkgpackage
Write-Output $Message | Out-File $log -Append
$syncHash.Window.Dispatcher.Invoke(
[action]{
$syncHash.listbox_result.Items.Add($Message)
$syncHash.listbox_result.Items.MoveCurrentToLast()
$syncHash.listbox_result.ScrollIntoView($syncHash.listbox_result.Items.CurrentItem)}
)
$cat = $ppkgpackage.Replace('.ppkg', '.cat')
DISM.exe /Image:$mountpath /Add-ProvisioningPackage /PackagePath:$ppkgpackage /CatalogPath:$cat
}
$syncHash.Window.Dispatcher.Invoke(
[action]{
$syncHash.listbox_result.Items.Add($MessageLine)
$syncHash.listbox_result.Items.MoveCurrentToLast()
$syncHash.listbox_result.ScrollIntoView($syncHash.listbox_result.Items.CurrentItem)}
)
Write-Output $MessageLine | Out-File $log -Append
}
# Deactivate and activate features
if ($featuresenable.Count -gt 0){
Write-Output $MessageLine | Out-File $log -Append
$Message = "=== activate features: ======================================"
Write-Output $Message | Out-File $log -Append
$syncHash.Window.Dispatcher.Invoke(
[action]{
$syncHash.txtb_finish.Text = "Activate features - Please wait..."
$syncHash.listbox_result.Items.Add($MessageLine)
$syncHash.listbox_result.Items.Add($Message)
$syncHash.listbox_result.Items.MoveCurrentToLast()
$syncHash.listbox_result.ScrollIntoView($syncHash.listbox_result.Items.CurrentItem)}
)
$Error.Clear()
foreach ($feature_a in $featuresenable){
if ($feature_a -eq "NetFx3"){
try {
$netfx3path = $wimpath.Replace("\install.wim","")
dism /Image:$mountpath /Enable-Feature /FeatureName:$feature_a /All /Source:"$($netfx3path)\sxs" /LimitAccess
} catch{}
} else {
try {
dism /Image:$mountpath /Enable-Feature /FeatureName:$feature_a
} catch{}
}
if ($Error){
$Message = "$feature_a | Failed"
Write-Output $Message | Out-File $log -Append
$syncHash.Window.Dispatcher.Invoke(
[action]{
$syncHash.listbox_result.Items.Add($Message)
$syncHash.listbox_result.Items.MoveCurrentToLast()
$syncHash.listbox_result.ScrollIntoView($syncHash.listbox_result.Items.CurrentItem)}
)
$Error.Clear()
} else {
$Message = "$feature_a | Successful"
Write-Output $Message | Out-File $log -Append
$syncHash.Window.Dispatcher.Invoke(
[action]{
$syncHash.listbox_result.Items.Add($Message)
$syncHash.listbox_result.Items.MoveCurrentToLast()
$syncHash.listbox_result.ScrollIntoView($syncHash.listbox_result.Items.CurrentItem)}
)
}
}
Write-Output $MessageLine | Out-File $log -Append
$syncHash.Window.Dispatcher.Invoke(
[action]{
$syncHash.listbox_result.Items.Add($MessageLine)
$syncHash.listbox_result.Items.MoveCurrentToLast()
$syncHash.listbox_result.ScrollIntoView($syncHash.listbox_result.Items.CurrentItem)}
)
}
if ($featuresdisable.Count -gt 0){
Write-Output $MessageLine | Out-File $log -Append
$Message = "=== deactivate features: ===================================="
Write-Output $Message | Out-File $log -Append
$syncHash.Window.Dispatcher.Invoke(
[action]{
$syncHash.txtb_finish.Text = "Deactivate features - Please wait..."
$syncHash.listbox_result.Items.Add($MessageLine)
$syncHash.listbox_result.Items.Add($Message)
$syncHash.listbox_result.Items.MoveCurrentToLast()
$syncHash.listbox_result.ScrollIntoView($syncHash.listbox_result.Items.CurrentItem)}
)
$Error.Clear()
foreach ($feature_d in $featuresdisable){
try {
dism /Image:$mountpath /Disable-Feature /FeatureName:$feature_d
} catch{}
if ($Error){
$Message = "$feature_d | Failed"
Write-Output $Message | Out-File $log -Append
$syncHash.Window.Dispatcher.Invoke(
[action]{
$syncHash.listbox_result.Items.Add($Message)
$syncHash.listbox_result.Items.MoveCurrentToLast()
$syncHash.listbox_result.ScrollIntoView($syncHash.listbox_result.Items.CurrentItem)}
)
$Error.Clear()
} else {
$Message = "$feature_d | Successful"
Write-Output $Message | Out-File $log -Append
$syncHash.Window.Dispatcher.Invoke(
[action]{
$syncHash.listbox_result.Items.Add($Message)
$syncHash.listbox_result.Items.MoveCurrentToLast()
$syncHash.listbox_result.ScrollIntoView($syncHash.listbox_result.Items.CurrentItem)}
)
}
}
Write-Output $MessageLine | Out-File $log -Append
$syncHash.Window.Dispatcher.Invoke(
[action]{
$syncHash.listbox_result.Items.Add($MessageLine)
$syncHash.listbox_result.Items.MoveCurrentToLast()
$syncHash.listbox_result.ScrollIntoView($syncHash.listbox_result.Items.CurrentItem)}
)
$Message = "=== actiavte/deactivate features finished ==================="
Write-Output $Message | Out-File $log -Append
Write-Output $MessageLine | Out-File $log -Append
$syncHash.Window.Dispatcher.Invoke(
[action]{
$syncHash.listbox_result.Items.Add($Message)
$syncHash.listbox_result.Items.Add($MessageLine)
$syncHash.listbox_result.Items.MoveCurrentToLast()
$syncHash.listbox_result.ScrollIntoView($syncHash.listbox_result.Items.CurrentItem)}
)
}
# Install IE11 on Windows 7
if($patchie11 -eq "True"){
Write-Output $MessageLine | Out-File $log -Append
$Message = "=== Integrate IE11: ======================================"
Write-Output $Message | Out-File $log -Append
$syncHash.Window.Dispatcher.Invoke(
[action]{
$syncHash.txtb_finish.Text = "Install IE11 - Please wait..."
$syncHash.listbox_result.Items.Add($MessageLine)
$syncHash.listbox_result.Items.Add($Message)
$syncHash.listbox_result.Items.MoveCurrentToLast()
$syncHash.listbox_result.ScrollIntoView($syncHash.listbox_result.Items.CurrentItem)}
)
[int]$successfulcount = 0
[int]$failedcount = 0
$patchFolder = @("pre","ie","post") # folder structure for Windows 7
$Error.Clear()
$count = 0
foreach ($folder in $patchFolder){
$updatefolder = $patchie11path + '\' + $folder
$patches = Get-ChildItem -Path $updatefolder -Recurse
foreach ($patch in $patches){
try {
$syncHash.Window.Dispatcher.Invoke(
[action]{
$syncHash.txtb_finish.Text = "Install $($patch) - Please wait..."}
)
Add-WindowsPackage -Path $mountpath -PackagePath $patch.FullName -NoRestart -ErrorAction SilentlyContinue -WarningAction SilentlyContinue | Out-Null
} catch {}
$count++
if ($Error){
$failedcount++
$Message = "$($count): $($patch) | Failed"
Write-Output $Message | Out-File $log -Append
$syncHash.Window.Dispatcher.Invoke(
[action]{
$syncHash.listbox_result.Items.Add($Message)
$syncHash.listbox_result.Items.MoveCurrentToLast()
$syncHash.listbox_result.ScrollIntoView($syncHash.listbox_result.Items.CurrentItem)}
)
$Error.Clear()
} else {
$successfulcount++
$Message = "$($count): $($patch) | Successful"
Write-Output $Message | Out-File $log -Append
$syncHash.Window.Dispatcher.Invoke(
[action]{
$syncHash.listbox_result.Items.Add($Message)
$syncHash.listbox_result.Items.MoveCurrentToLast()
$syncHash.listbox_result.ScrollIntoView($syncHash.listbox_result.Items.CurrentItem)}
)
}
}
}
Write-Output $MessageLine | Out-File $log -Append
$syncHash.Window.Dispatcher.Invoke(
[action]{
$syncHash.listbox_result.Items.Add($MessageLine)
$syncHash.listbox_result.Items.MoveCurrentToLast()
$syncHash.listbox_result.ScrollIntoView($syncHash.listbox_result.Items.CurrentItem)}
)
$Message = "$successfulcount Patches-IE11 successful"
Write-Output $Message | Out-File $log -Append
$syncHash.Window.Dispatcher.Invoke(
[action]{
$syncHash.listbox_result.Items.Add($Message)
$syncHash.listbox_result.Items.MoveCurrentToLast()
$syncHash.listbox_result.ScrollIntoView($syncHash.listbox_result.Items.CurrentItem)}
)
$Message = "$failedcount Patches IE11 failed"
Write-Output $Message | Out-File $log -Append
$syncHash.Window.Dispatcher.Invoke(
[action]{
$syncHash.listbox_result.Items.Add($Message)
$syncHash.listbox_result.Items.Add($MessageLine)
$syncHash.listbox_result.Items.MoveCurrentToLast()
$syncHash.listbox_result.ScrollIntoView($syncHash.listbox_result.Items.CurrentItem)}
)
Write-Output $MessageLine | Out-File $log -Append
}
# Install patches
if ($patchcheck -eq "True"){
Write-Output $MessageLine | Out-File $log -Append
$Message = "=== Integrate patches: ======================================"
Write-Output $Message | Out-File $log -Append
$syncHash.Window.Dispatcher.Invoke(
[action]{
$syncHash.txtb_finish.Text = "Install patches - Please wait..."
$syncHash.listbox_result.Items.Add($MessageLine)
$syncHash.listbox_result.Items.Add($Message)
$syncHash.listbox_result.Items.MoveCurrentToLast()
$syncHash.listbox_result.ScrollIntoView($syncHash.listbox_result.Items.CurrentItem)}
)
[int]$successfulcount = 0
[int]$failedcount = 0
$Error.Clear()
$count = 0
$patches = Get-ChildItem -Path $patchpath -Recurse
foreach ($patch in $patches){
try {
$syncHash.Window.Dispatcher.Invoke(
[action]{
$syncHash.txtb_finish.Text = "Install $($patch) - Please wait..."}
)
Add-WindowsPackage -Path $mountpath -PackagePath $patch.FullName -NoRestart -ErrorAction SilentlyContinue -WarningAction SilentlyContinue | Out-Null
} catch {}
$count++
if ($Error){
$failedcount++
$Message = "$($count): $($patch) | Failed"
Write-Output $Message | Out-File $log -Append
$syncHash.Window.Dispatcher.Invoke(
[action]{
$syncHash.listbox_result.Items.Add($Message)
$syncHash.listbox_result.Items.MoveCurrentToLast()
$syncHash.listbox_result.ScrollIntoView($syncHash.listbox_result.Items.CurrentItem)}
)
$Error.Clear()
} else {
$successfulcount++
$Message = "$($count): $($patch) | Successful"
Write-Output $Message | Out-File $log -Append
$syncHash.Window.Dispatcher.Invoke(
[action]{
$syncHash.listbox_result.Items.Add($Message)
$syncHash.listbox_result.Items.MoveCurrentToLast()
$syncHash.listbox_result.ScrollIntoView($syncHash.listbox_result.Items.CurrentItem)}
)
}
}
Write-Output $MessageLine | Out-File $log -Append
$syncHash.Window.Dispatcher.Invoke(
[action]{
$syncHash.listbox_result.Items.Add($MessageLine)
$syncHash.listbox_result.Items.MoveCurrentToLast()
$syncHash.listbox_result.ScrollIntoView($syncHash.listbox_result.Items.CurrentItem)}
)
$Message = "$successfulcount Patches successful"
Write-Output $Message | Out-File $log -Append
$syncHash.Window.Dispatcher.Invoke(
[action]{
$syncHash.listbox_result.Items.Add($Message)
$syncHash.listbox_result.Items.MoveCurrentToLast()
$syncHash.listbox_result.ScrollIntoView($syncHash.listbox_result.Items.CurrentItem)}
)
$Message = "$failedcount Patches failed"
Write-Output $Message | Out-File $log -Append
$syncHash.Window.Dispatcher.Invoke(
[action]{
$syncHash.listbox_result.Items.Add($Message)
$syncHash.listbox_result.Items.Add($MessageLine)
$syncHash.listbox_result.Items.MoveCurrentToLast()
$syncHash.listbox_result.ScrollIntoView($syncHash.listbox_result.Items.CurrentItem)}
)
}
Write-Output $MessageLine | Out-File $log -Append
$syncHash.Window.Dispatcher.Invoke(
[action]{
$syncHash.txtb_6.Visibility = "Visible"
$syncHash.txtb_finish.Text = ""
$syncHash.grid_finish.Visibility = "Hidden"
$syncHash.btn_cancel_6.Visibility = "Visible"
$syncHash.btn_save.Visibility = "Visible"
$syncHash.listbox_result.Items.MoveCurrentToLast()
$syncHash.listbox_result.ScrollIntoView($syncHash.listbox_result.Items.CurrentItem)}
)
}
$PSinstance = [powershell]::Create().AddScript($Code)
$PSinstance.Runspace = $Runspace
$job = $PSinstance.BeginInvoke()
}
#--- Mount install.wim ---#
function RunspaceMount {
param($syncHash,$wimpath,$mountpath,$index,$log,$edition)
$syncHash.Host = $host
$Runspace = [runspacefactory]::CreateRunspace()
$Runspace.ApartmentState = "STA"
$Runspace.ThreadOptions = "ReuseThread"
$Runspace.Open()
$Runspace.SessionStateProxy.SetVariable("syncHash",$syncHash)
$Runspace.SessionStateProxy.SetVariable("wimpath",$wimpath)
$Runspace.SessionStateProxy.SetVariable("mountpath",$mountpath)
$Runspace.SessionStateProxy.SetVariable("index",$index)
$Runspace.SessionStateProxy.SetVariable("log",$log)
$Runspace.SessionStateProxy.SetVariable("edition",$edition)
$code = {
$syncHash.Window.Dispatcher.invoke(
[action]{
$syncHash.btn_cancel_1.Visibility = "Hidden"
$syncHash.btn_next_1.Visibility = "Hidden"
$syncHash.txtb_mount.Text = "Mount $edition - Please wait ..."}
)
$mounterror = "True"
try{
Mount-WindowsImage -ImagePath $wimpath -Path $mountpath -Index $index
} catch {
if($_.Exception.Message -notmatch "A DismSession with open handles was attempted to be mounted."){
Write-Output $Message | Out-File $log -Append
$mounterror = $false
$errormessage = "TRAPPED: {0}: '{1}'" -f ($_.Exception.GetType().FullName), ($_.Exception.Message)
[System.Windows.Forms.MessageBox]::Show($errormessage,"Error",0,[System.Windows.Forms.MessageBoxIcon]::Exclamation) | Out-Null
$syncHash.Window.Dispatcher.invoke(
[action]{
$syncHash.btn_cancel_1.Visibility = "Visible"
$syncHash.btn_next_1.Visibility = "Visible"
$syncHash.grid_mount.Visibility = "Hidden"}
)
Write-Output $edition | Out-File $log -Append
$Message = "=== install.wim could not be provided ======================="
Write-Output $Message | Out-File $log -Append
$Message = "============================================================="
Write-Output $Message | Out-File $log -Append
}
}
if($mounterror -eq "True" -and $edition -notmatch "Windows 7"){
$syncHash.Window.Dispatcher.invoke(
[action]{
$syncHash.txtb_mount.Text = "Read APPX from $edition - Please wait ..."}
)
# Read appx and add to listbox
$appxList = Get-AppxProvisionedPackage -Path $mountpath | Select PackageName
foreach($appx in $appxList){
$syncHash.listbox_appx.Items.Add($appx.PackageName)
}
$syncHash.Window.Dispatcher.invoke(
[action]{ # Load new canvas
$syncHash.can_property.Visibility = "Hidden"
$syncHash.can_removeppx.Visibility = "Visible" }
)
Write-Output $edition | Out-File $log -Append
$Message = "=== install.wim was provided ================================"
Write-Output $Message | Out-File $log -Append
$Message = "============================================================="
Write-Output $Message | Out-File $log -Append
} else {
$syncHash.Window.Dispatcher.invoke(
[action]{ # Load new canvas
$syncHash.can_property.Visibility = "Hidden"
$syncHash.can_w7patch.Visibility = "Visible" }
)
Write-Output $edition | Out-File $log -Append
$Message = "=== install.wim was provided ================================"
Write-Output $Message | Out-File $log -Append
$Message = "============================================================="
Write-Output $Message | Out-File $log -Append
}
# Customize GUI for Windows 8/8.1
if($edition -match "Windows 8"){
# can_addppkg
$syncHash.Window.Dispatcher.Invoke(
[action]{
$syncHash.txt_patchpathie11.Visibility = "Hidden"
$syncHash.btn_patchie11.Visibility = "Hidden"
$syncHash.ch_ie11.Visibility = "Hidden"
$syncHash.btn_back_3_1.Visibility = "Visible"}
)
}
if($edition -match "Windows 7" -or $edition -match "Windows 8"){
# can_change
$syncHash.Window.Dispatcher.Invoke(
[action]{
$syncHash.txtb_5_1.Visibility = "Hidden"
$syncHash.txtb_5_2.Visibility = "Hidden"
$syncHash.txtb_5_3.Visibility = "Hidden"
$syncHash.txtb_5_4.Visibility = "Hidden"}
)
}
}
$PSinstance = [powershell]::Create().AddScript($Code)
$PSinstance.Runspace = $Runspace
$job = $PSinstance.BeginInvoke()
}
#--- Close Form ---#
function RunspaceUmountWim(){
param($syncHash,$mountpath,$commit,$wimPathCreated,$edition,$log)
$syncHash.Host = $host
$Runspace = [runspacefactory]::CreateRunspace()
$Runspace.ApartmentState = "STA"
$Runspace.ThreadOptions = "ReuseThread"
$Runspace.Open()
$Runspace.SessionStateProxy.SetVariable("syncHash",$syncHash)
$Runspace.SessionStateProxy.SetVariable("mountpath",$mountpath)
$Runspace.SessionStateProxy.SetVariable("commit",$commit)
$Runspace.SessionStateProxy.SetVariable("wimPathCreated",$wimPathCreated)
$Runspace.SessionStateProxy.SetVariable("edition",$edition)
$Runspace.SessionStateProxy.SetVariable("log",$log)
$code = {
If(Test-Path $mountPath) {
$MessageLine = "============================================================="
Write-Output $MessageLine | Out-File $log -Append
Write-Output $edition | Out-File $log -Append
$syncHash.Window.Dispatcher.Invoke(
[action]{
$syncHash.btn_save.Visibility = "Hidden"
$syncHash.btn_cancel_6.Visibility = "Hidden"
$syncHash.txtb_6.Visibility = "Hidden"
$syncHash.grid_finish.Visibility = "Visible"
$syncHash.txtb_finish.Text = "Unmount install.wim with changes - Please wait until program ends..."
$syncHash.listbox_result.Items.Add($MessageLine)
$syncHash.listbox_result.Items.Add($edition)
$syncHash.listbox_result.Items.MoveCurrentToLast()
$syncHash.listbox_result.ScrollIntoView($syncHash.listbox_result.Items.CurrentItem)}
)
if($commit -eq $true){
$Message = "=== Install.wim unmouted with changes. ======================"
Write-Output $Message | Out-File $log -Append
$syncHash.Window.Dispatcher.Invoke(
[action]{
$syncHash.listbox_result.Items.Add($Message)
$syncHash.listbox_result.Items.MoveCurrentToLast()
$syncHash.listbox_result.ScrollIntoView($syncHash.listbox_result.Items.CurrentItem)}
)
Dismount-WindowsImage -Path $mountpath -Save
$Message = "=== changes completed ======================================="
Write-Output $MessageLine | Out-File $log -Append
Write-Output $Message | Out-File $log -Append
Write-Output $MessageLine | Out-File $log -Append
} else {
$syncHash.Window.Dispatcher.invoke(
[action]{
$syncHash.can_property.Visibility = "Hidden"
$syncHash.can_removeppx.Visibility = "Hidden"
$syncHash.can_addppkg.Visibility = "Hidden"
$syncHash.can_w7patch.Visibility = "Hidden"
$syncHash.can_features.Visibility = "Hidden"
$syncHash.can_change.Visibility = "Hidden"
$syncHash.can_result.Visibility = "Visible"
$syncHash.pb_finish.Foreground = "Yellow"
$syncHash.txtb_finish.Foreground = "Red"
$syncHash.txtb_finish.Text = "The operation was canceled. Wait until program ends..." }
)
Dismount-WindowsImage -Path $mountpath -Discard
$Message = "=== Install.wim unmouted without changes. ==================="
Write-Output $Message | Out-File $log -Append
}
if($wimPathCreated){
$Message = "Delete $($mountPath)"
Write-Output $MessageLine | Out-File $log -Append
Write-Output $Message | Out-File $log -Append
Write-Output $MessageLine | Out-File $log -Append
Remove-Item -Path $mountPath
}
Write-Output $MessageLine | Out-File $log -Append
}
$syncHash.formClose = $true
$syncHash.Window.Dispatcher.invoke(
[action]{
$syncHash.Window.Close() }
)
}
$PSinstance = [powershell]::Create().AddScript($Code)
$PSinstance.Runspace = $Runspace
$job = $PSinstance.BeginInvoke()
}
###--- Create GUI for WIM change ---###
$dialogXML = @"
<Window x:Class="Powershell_Form.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Windows WIM Wizard Version 5.1" Height="600" Width="800">
<Grid>
<Canvas x:Name="can_property" Visibility="Visible" HorizontalAlignment="Left" Height="549" Margin="10,10,0,0" VerticalAlignment="Top" Width="772">
<Label Content="Basic settings for modification of Windows install.wim:" Canvas.Left="19" Canvas.Top="31" Width="743" FontWeight="ExtraBold" FontSize="20"/>
<TextBox x:Name="txt_adkpath" Height="23" Canvas.Left="19" TextWrapping="NoWrap" Text="" Width="549" Canvas.Top="112" IsEnabled="false"/>
<Button x:Name="btn_adkpath" Content="ADK 10 DISM Path ..." Canvas.Left="593" Canvas.Top="115" Width="169" ToolTip="Please select the path for DISM from ADK10, if it differs from the standard."/>
<TextBox x:Name="txt_wimpath" Height="23" Canvas.Left="19" TextWrapping="Wrap" Text="C:\" Canvas.Top="162" Width="549" IsEnabled="false"/>
<Button x:Name="btn_wimpath" Content="WIM File ..." Canvas.Left="593" Canvas.Top="165" Width="169" ToolTip="Please select the install.wim for modification."/>
<TextBox x:Name="txt_wimmountpath" Height="23" Canvas.Left="19" TextWrapping="Wrap" Text="C:\" Canvas.Top="210" Width="549" IsEnabled="false"/>
<Button x:Name="btn_wimmountpath" Content="WIM Mount Path ..." Canvas.Left="593" Canvas.Top="213" Width="169" ToolTip="Please select the temporary mount path for the install.wim."/>
<TextBox x:Name="txt_patchpath" Height="23" Canvas.Left="19" TextWrapping="Wrap" Text="C:\" Canvas.Top="255" Width="549" IsEnabled="false"/>
<Button x:Name="btn_patchpath" Content="Patches Path ..." Canvas.Left="593" Canvas.Top="258" Width="169" ToolTip="Please select the folder that contains the patches."/>
<TextBox x:Name="txt_startlayout" Height="23" Canvas.Left="19" TextWrapping="Wrap" Text="C:\" Canvas.Top="304" Width="549" IsEnabled="false"/>
<Button x:Name="btn_startlayout" Content="StartLayout Path ..." Canvas.Left="593" Canvas.Top="307" Width="169" ToolTip="Please select the LayoutModification.xml. If you use a link for Internet Explorer in the StartLayout, then the link for the Internet Explorer must be located in the same folder!" RenderTransformOrigin="0.491,2.9"/>
<TextBox x:Name="txt_fileassociation" Height="23" Canvas.Left="19" TextWrapping="Wrap" Text="C:\" Canvas.Top="354" Width="549" IsEnabled="false"/>
<Button x:Name="btn_fileassociation" Content="FileAccosiations Path ..." Canvas.Left="593" Canvas.Top="357" Width="169" ToolTip="Please select the FileAssociations.xml."/>
<Grid x:Name="grid_mount" Canvas.Left="20" Canvas.Top="410" Visibility="Hidden">
<ProgressBar x:Name="pb_proberty" Height="20" Width="550" IsIndeterminate="True"/>
<TextBlock x:Name="txtb_mount" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
<Button x:Name="btn_cancel_1" Content="Cancel" Canvas.Left="593" Canvas.Top="519" Width="169" IsEnabled="True"/>
<Button x:Name="btn_next_1" Content="Next" Canvas.Left="399" Canvas.Top="519" Width="169"/>
<TextBlock x:Name="txtb_1" Canvas.Left="20" TextWrapping="Wrap" Text=" If you click Next, the the install.wim will be provided in the specified folder. This may take a moment. " Canvas.Top="441" Height="65" Width="742" FontSize="14"/>
</Canvas>
<Canvas x:Name="can_removeppx" Visibility="Hidden" HorizontalAlignment="Left" Height="549" Margin="10,10,0,0" VerticalAlignment="Top" Width="772">
<Label Content="Remove selected APPX from install.wim:" Canvas.Left="19" Canvas.Top="31" Width="743" FontWeight="ExtraBold" FontSize="20"/>
<ListBox x:Name="listbox_appx" Height="355" Canvas.Left="10" Canvas.Top="89" Width="752" SelectionMode="Multiple"/>
<TextBlock x:Name="txtb_2" Canvas.Left="10" TextWrapping="Wrap" Canvas.Top="454" Height="60" Width="752" FontSize="14" Text="Please select the AppxPackage to remove from install.wim."/>
<Button x:Name="btn_next_2" Content="Next" Canvas.Left="399" Canvas.Top="519" Width="169"/>
<Button x:Name="btn_cancel_2" Content="Cancel" Canvas.Left="593" Canvas.Top="519" Width="169"/>
</Canvas>
<Canvas x:Name="can_addppkg" Visibility="Hidden" HorizontalAlignment="Left" Height="549" Margin="10,10,0,0" VerticalAlignment="Top" Width="772">
<Label Content="Integrate selected options in the install.wim:" Canvas.Left="19" Canvas.Top="31" Width="743" FontWeight="ExtraBold" FontSize="20"/>
<Button x:Name="btn_openppkg" Content="Open PPKG ..." Canvas.Left="593" Canvas.Top="91" Width="169"/>
<Button x:Name="btn_openppkg_del" Content="Delete selected PPKG" Canvas.Left="593" Canvas.Top="131" Width="169"/>
<ListBox x:Name="listbox_ppkg" Height="211" Canvas.Left="30" Canvas.Top="91" Width="538" SelectionMode="Multiple"/>
<TextBlock x:Name="txtb_3" Canvas.Left="30" TextWrapping="Wrap" Canvas.Top="303" Height="24" Width="732" FontSize="14" Text="Add ProvisioningPackages for integration."/>
<CheckBox x:Name="ch_patches" Content="Integrate Patches to install.wim?" Canvas.Left="30" Canvas.Top="342" Width="549" Height="20" IsChecked="False"/>
<CheckBox x:Name="ch_onedrive" Content="Deactivate OneDrive Setup for all users? (W10 only!)" Canvas.Left="30" Canvas.Top="363" Width="549" Height="20" IsChecked="False"/>
<CheckBox x:Name="ch_appx" Content="Deactivate APP-Advertising? (W10 Version 1511 only!)" Canvas.Left="30" Canvas.Top="384" Width="549" Height="20" IsChecked="False" Visibility="Visible" />
<CheckBox x:Name="ch_startlayout" Content="Integrate StartLayout? (W10 only!)" Canvas.Left="30" Canvas.Top="405" Width="549" Height="20" IsChecked="False" Visibility="Visible" ToolTip="Das StartLayout muss zur Version von W10 passen!" />
<CheckBox x:Name="ch_fileassociation" Content="Integrate FileAccosiation? (W10 only!)" Canvas.Left="30" Canvas.Top="426" Width="549" Height="20" IsChecked="False" Visibility="Visible" />
<Grid x:Name="grid_feature_3" Canvas.Left="20" Canvas.Top="470" Visibility="Hidden">
<ProgressBar Height="20" Width="550" IsIndeterminate="True"/>
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="Check features - Please wait..."/>
</Grid>
<Button x:Name="btn_back_3" Content="Back" Canvas.Left="205" Canvas.Top="519" Width="169"/>
<Button x:Name="btn_next_3" Content="Next" Canvas.Left="399" Canvas.Top="519" Width="169"/>
<Button x:Name="btn_cancel_3" Content="Cancel" Canvas.Left="593" Canvas.Top="519" Width="169"/>
</Canvas>
<Canvas x:Name="can_w7patch" Visibility="Hidden" HorizontalAlignment="Left" Height="549" Margin="10,10,0,0" VerticalAlignment="Top" Width="772">
<Label Content="Integrate selected options in the install.wim:" Canvas.Left="19" Canvas.Top="31" Width="743" FontWeight="ExtraBold" FontSize="20"/>
<CheckBox x:Name="ch_patches_w7" Content="Integrate Patches to install.wim?" Canvas.Left="30" Canvas.Top="91" Width="549" Height="20" IsChecked="False"/>
<CheckBox x:Name="ch_ie11" Content="Integrate IE11 to Install.wim?" Canvas.Left="30" Canvas.Top="112" Width="549" Height="20" IsChecked="False"/>
<TextBox x:Name="txt_patchpathie11" Height="23" Canvas.Left="30" TextWrapping="Wrap" Text="C:\" Canvas.Top="151" Width="549" IsEnabled="false"/>
<Button x:Name="btn_patchie11" Content="IE11 Patches Path ..." Canvas.Left="593" Canvas.Top="151" Width="169" ToolTip="Please select the folder that contains the IE11 patches."/>
<Grid x:Name="grid_feature_3_1" Canvas.Left="20" Canvas.Top="470" Visibility="Hidden">
<ProgressBar Height="20" Width="550" IsIndeterminate="True"/>
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="Check features - Please wait..."/>
</Grid>
<Button x:Name="btn_back_3_1" Content="Back" Canvas.Left="205" Canvas.Top="519" Width="169" Visibility="Hidden"/>
<Button x:Name="btn_next_3_1" Content="Next" Canvas.Left="399" Canvas.Top="519" Width="169"/>
<Button x:Name="btn_cancel_3_1" Content="Cancel" Canvas.Left="593" Canvas.Top="519" Width="169"/>
</Canvas>
<Canvas x:Name="can_features" Visibility="Hidden" HorizontalAlignment="Left" Height="549" Margin="10,10,0,0" VerticalAlignment="Top" Width="772">
<Label Content="Slected features activate/deactivate:" Canvas.Left="19" Canvas.Top="31" Width="743" FontWeight="ExtraBold" FontSize="20"/>
<Label Content="Activated features:" Canvas.Left="19" Canvas.Top="73"/>
<Label Content="Deactivated features:" Canvas.Left="408" Canvas.Top="73"/>
<ListBox x:Name="listbox_feature_a" Height="390" Canvas.Left="30" Canvas.Top="104" Width="330" SelectionMode="Multiple"/>
<ListBox x:Name="listbox_feature_d" Height="390" Canvas.Left="408" Canvas.Top="104" Width="330" SelectionMode="Multiple"/>
<Button x:Name="btn_back_4" Content="Back" Canvas.Left="205" Canvas.Top="519" Width="169"/>
<Button x:Name="btn_next_4" Content="Next" Canvas.Left="399" Canvas.Top="519" Width="169"/>
<Button x:Name="btn_cancel_4" Content="Cancel" Canvas.Left="593" Canvas.Top="519" Width="169"/>
</Canvas>
<Canvas x:Name="can_change" Visibility="Hidden" HorizontalAlignment="Left" Height="549" Margin="10,10,0,0" VerticalAlignment="Top" Width="772">
<Label Content="Changes overview:" Canvas.Left="19" Canvas.Top="10" Width="743" FontWeight="ExtraBold" FontSize="20"/>
<Label Content="AppxPackage: (Windows 8/8.1/10 only)" Canvas.Left="30" Canvas.Top="47" Width="743" FontWeight="Bold" FontSize="12"/>
<ListView x:Name="listview_appx" Height="112" Canvas.Left="30" Canvas.Top="72" Width="328"/>
<Label Content="ProvisioningPackages: (Windows 10 only)" Canvas.Left="30" Canvas.Top="185" Width="743" FontWeight="Bold" FontSize="12"/>
<ListView x:Name="listview_ppkg" Height="112" Canvas.Left="30" Canvas.Top="210" Width="328"/>
<Label Content="Features activate/deactivate:" Canvas.Left="30" Canvas.Top="324" Width="743" FontWeight="Bold" FontSize="12"/>
<ListView x:Name="listview_features" Height="112" Canvas.Left="30" Canvas.Top="349" Width="328"/>
<TextBlock x:Name="txtb_5" Canvas.Left="399" TextWrapping="Wrap" Text="" Canvas.Top="72" Height="24" Width="352" FontSize="14"/>
<TextBlock x:Name="txtb_5_1" Canvas.Left="399" TextWrapping="Wrap" Text="" Canvas.Top="101" Height="24" Width="352" FontSize="14"/>
<TextBlock x:Name="txtb_5_2" Canvas.Left="399" TextWrapping="Wrap" Text="" Canvas.Top="130" Height="24" Width="352" FontSize="14"/>
<TextBlock x:Name="txtb_5_3" Canvas.Left="399" TextWrapping="Wrap" Text="" Canvas.Top="159" Height="24" Width="352" FontSize="14"/>
<TextBlock x:Name="txtb_5_4" Canvas.Left="399" TextWrapping="Wrap" Text="" Canvas.Top="188" Height="24" Width="352" FontSize="14"/>
<TextBlock x:Name="txtb_5_7" Canvas.Left="30" TextWrapping="Wrap" Text="If you click Finish, the new install.wim will be prepared." Canvas.Top="468" Height="46" Width="732" FontSize="14"/>
<Button x:Name="btn_back_5" Content="Back" Canvas.Left="205" Canvas.Top="519" Width="169"/>
<Button x:Name="btn_finish" Content="Finish" Canvas.Left="399" Canvas.Top="519" Width="169"/>
<Button x:Name="btn_cancel_5" Content="Cancel" Canvas.Left="593" Canvas.Top="519" Width="169"/>
</Canvas>
<Canvas x:Name="can_result" Visibility="Hidden" HorizontalAlignment="Left" Height="549" Margin="10,10,0,0" VerticalAlignment="Top" Width="772">
<Label Content="Show result:" Canvas.Left="19" Canvas.Top="10" Width="743" FontWeight="ExtraBold" FontSize="20"/>
<ListBox x:Name="listbox_result" Height="400" Canvas.Left="30" Canvas.Top="50" Width="700" SelectionMode="Multiple"/>
<Grid x:Name="grid_finish" Canvas.Left="30" Canvas.Top="470" Visibility="Visible">
<ProgressBar x:Name="pb_finish" Height="30" Width="700" IsIndeterminate="True"/>
<TextBlock x:Name="txtb_finish" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
<TextBlock x:Name="txtb_6" Canvas.Left="30" TextWrapping="Wrap" Text="Click Save to apply the changes." Canvas.Top="470" Height="46" Width="732" FontSize="14" Visibility="Hidden"/>
<Button x:Name="btn_cancel_6" Content="Cancel" Canvas.Left="561" Canvas.Top="519" Width="169" Visibility="Hidden"/>
<Button x:Name="btn_save" Content="Save" Canvas.Left="367" Canvas.Top="519" Width="169" Visibility="Hidden"/>
</Canvas>
</Grid>
</Window>
"@
###--- XAML ---###
$dialogXML = $dialogXML -replace 'mc:Ignorable="d"','' -replace "x:N",'N' -replace '^<Win.*', '<Window'
[xml]$XAML = $dialogXML
$syncHash = [hashtable]::Synchronized(@{})
$reader=(New-Object System.Xml.XmlNodeReader $XAML)
$syncHash.Window=[Windows.Markup.XamlReader]::Load($reader)
###--- XAML objects ---###
foreach($wpfVar in $XAML.SelectNodes("//*[@Name]")){
$syncHash.$($wpfVar.Name) = $syncHash.Window.FindName($wpfVar.Name)
}
###--- Global Variables ---###
$syncHash.formClose = $Global:formClose
###--- loading OS edition ---###
$loadingXML = @"
<Window x:Class="OS_Edition.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="OS Edition" Height="225" Width="525">
<Grid>
<ComboBox x:Name="cb_os" HorizontalAlignment="Left" Margin="10,94,0,0" VerticalAlignment="Top" Width="497"/>
<Button x:Name="btn_os" Content="OK" HorizontalAlignment="Left" Margin="218,145,0,0" VerticalAlignment="Top" Width="75"/>
<Label Content=" Choose your OS edition!" HorizontalAlignment="Left" Margin="10,34,0,0" VerticalAlignment="Top" Width="497" Height="28"/>
</Grid>
</Window>
"@
###--- OS XAML ---###
$loadingXML = $loadingXML -replace 'mc:Ignorable="d"','' -replace "x:N",'N' -replace '^<Win.*', '<Window'
[xml]$loadingXAML = $loadingXML
$loadingreader=(New-Object System.Xml.XmlNodeReader $loadingXAML)
$loadingForm=[Windows.Markup.XamlReader]::Load($loadingreader)
foreach($wpfVar in $loadingXAML.SelectNodes("//*[@Name]")){
Set-Variable -Name "WPF$($wpfVar.Name)" -Value $loadingForm.FindName($wpfVar.Name)
}
###--- Create folder name ---###
$Global:FolderName = Get-RandomFolderName -length 8
$Global:wimmountPath = ("$Global:wimmountPath\$Global:FolderName").Replace("\\","\")
If(!(Test-Path -Path $Global:adkPath)){
$Global:adkPath = "$env:windir\system32"
}
$syncHash.txt_adkpath.Text = $global:adkPath
$syncHash.txt_wimmountpath.Text = $Global:wimmountPath
###--- Add Actions ---####
##--- Canvas 1 Start ---##
$syncHash.btn_adkpath.Add_Click({
$_adkPath = Read-FolderBrowserDialog -Message "Please select a directory" -InitialDirectory "" -NoNewFolderButton
if (![string]::IsNullOrEmpty($_adkPath)){
$Global:adkPath = $_adkPath
}
$syncHash.txt_adkpath.Text =$Global:adkPath
})
$syncHash.btn_wimpath.Add_Click({
$_wimPath = Read-OpenFileDialog -WindowTitle "Please select a install.wim" -InitialDirectory 'C:\' -Filter "Windows Image (install.wim)|install.wim"
if (![string]::IsNullOrEmpty($_wimPath)){
$Global:wimPath = $_wimPath
}
$syncHash.txt_wimpath.Text = $Global:wimPath
})
$syncHash.btn_wimmountpath.Add_Click({
$_wimmountPath = Read-FolderBrowserDialog -Message "Please select a directory" -InitialDirectory '' -NoNewFolderButton
if (![string]::IsNullOrEmpty($_wimmountPath)){
$Global:wimmountPath = $_wimmountPath
}
$syncHash.txt_wimmountpath.Text = ("$Global:wimmountPath\$Global:FolderName").Replace("\\","\")
})
$syncHash.btn_patchpath.Add_Click({
$_patchPath = Read-FolderBrowserDialog -Message "Please select a directory" -InitialDirectory '' -NoNewFolderButton
if (![string]::IsNullOrEmpty($_patchPath)){
$Global:patchPath = $_patchPath
}
$syncHash.txt_patchpath.Text = $Global:patchPath
})
$syncHash.btn_startlayout.Add_Click({
$_startlayoutPath = Read-OpenFileDialog -WindowTitle "Please select a LayoutModification.xml" -InitialDirectory 'C:\' -Filter "LayoutModification.xml File (LayoutModification.xml)|LayoutModification.xml"
if (![string]::IsNullOrEmpty($_startlayoutPath)){
$Global:startlayoutPath = $_startlayoutPath
$Global:startlayoutIELinkPath = Split-Path $Global:startlayoutPath
}
$syncHash.txt_startlayout.Text = $Global:startlayoutPath
})
$syncHash.btn_fileassociation.Add_Click({
$_fileassosiationPath = Read-OpenFileDialog -WindowTitle "Please Select a FileAssociation.xml" -InitialDirectory 'C:\' -Filter "FileAssociation File (*.xml)|*.xml"
if (![string]::IsNullOrEmpty($_fileassosiationPath)){
$Global:fileassociationPath = $_fileassosiationPath
}
$syncHash.txt_fileassociation.Text = $Global:fileassociationPath
})
$syncHash.btn_next_1.Add_Click({
try{
###--- env_var dism ---#
if ($Global:adkPath -match "DISM"){
Write-Host $Global:adkPath
if ($env:path -notmatch "DISM"){
Write-Host $env:path
$env:path = $Global:adkPath + ";" + $env:path
}
###--- Load Module ---###
Remove-Module -Name DiSM -ErrorAction SilentlyContinue
Import-Module $Global:adkPath
} else {
Remove-Module -Name DiSM -ErrorAction SilentlyContinue
Import-Module DISM
}
If(!([string]::IsNullOrWhiteSpace($syncHash.txt_wimpath.Text))){
# Create - change logfile
$Global:logFile = $Global:wimPath.Replace('install.wim', 'install_mod.log')
if (!(Test-Path $Global:logFile)){
New-Item $Global:logFile -type file
Write-LogFile "============================================================="
Write-LogFile "Logfile created $((get-date -Format dd/MM/yyyy))."
Write-LogFile "============================================================="
} else {
Write-LogFile "============================================================="
Write-LogFile "Logfile changed $((get-date -Format dd/MM/yyyy))."
Write-LogFile "============================================================="
}
# Create folder for mount DISM
$Global:wimmountPath = ($syncHash.txt_wimmountpath.Text).Replace("\\","\")
If((Test-Path $Global:wimmountPath) -eq $false){
New-Item -ItemType directory -Path $Global:wimmountPath
$Global:wimmountPathCreated = $true
}
# Mount install.wim
Write-LogFile "============================================================="
Write-LogFile "=== mount Install.wim ======================================="
Write-LogFile "Image: $Global:wimPath"
Write-LogFile "Path : $Global:wimmountPath"
$_mountedWim = Get-WindowsImage -Mounted
If($_mountedWim){
Write-LogFile "Image is mounted! Unmount in process ..."
Foreach($_image in $_mountedWim){
Dismount-WindowsImage -Path $_image.MountPath -Discard | Write-LogFile
}
}
### Multisource Index ermitteln ###
$osedition = dism /get-wiminfo /wimfile:$($syncHash.txt_wimpath.Text)
$WPFcb_os.Items.Clear()
for($i = 0; $i -lt $osedition.length; $i=$i+1){
if($osedition[$i] -match "Name"){
$osed = $osedition[$i]
#$WPFcb_os.Items.Add($osed.split(":")[1].trim()) | OUT-NULL
$WPFcb_os.Items.Add($osed.split(":")[1].trim()) | OUT-NULL}
}
$WPFcb_os.SelectedIndex = 0
if($WPFcb_os.Items.Count -gt 1){
$loadingForm.Owner = $Form
$loadingForm.Show()
$WPFbtn_os.Add_Click({
$edition = $WPFcb_os.SelectedIndex + 1
$Global:edition = $WPFcb_os.SelectedValue
$syncHash.grid_mount.Visibility = "Visible"
RunspaceMount -syncHash $syncHash -wimpath $syncHash.txt_wimpath.Text -mountpath $syncHash.txt_wimmountpath.Text -index $edition -log $Global:logFile -edition $Global:edition
Write-Host $Global:edition
Write-Host "============================================================="
$loadingForm.Visibility = "hidden"
})
} else {
$Global:edition = $WPFcb_os.SelectedValue
$edition = $WPFcb_os.SelectedIndex + 1
$syncHash.grid_mount.Visibility = "Visible"
RunspaceMount -syncHash $syncHash -wimpath $syncHash.txt_wimpath.Text -mountpath $syncHash.txt_wimmountpath.Text -index $edition -log $Global:logFile -edition $Global:edition
Write-Host $Global:edition
Write-Host "============================================================="
}
} else {
Show-ErrMsg -message "Not all field are filled correctly!"
}
} catch {
Write-Host $_.Exception
Write-Host $_.ScriptStackTrace
Write-Host ""
Show-ErrMsg -message $_.Exception
} finally {
# tbd
}
})
$syncHash.btn_cancel_1.Add_Click({
$syncHash.Window.Add_Closing({$_.Cancel = $false})
$syncHash.Window.Close()
})
###--- Canvas 1 End ---###
###--- Canvas 2 Start ---###
# selected appx to remove list
$syncHash.btn_next_2.Add_Click({
$Global:appxselectedList = @()
foreach ($appxItem in $syncHash.listbox_appx.SelectedItems){
$Global:appxselectedList += $appxItem
}
# Load new canvas
$syncHash.can_removeppx.Visibility = "Hidden"
if($Global:edition -match "Windows 8"){
$syncHash.can_w7patch.Visibility = "Visible"
} else {
$syncHash.can_addppkg.Visibility = "Visible"
}
})
$syncHash.btn_cancel_2.Add_Click({
$syncHash.Window.Add_Closing({$_.Cancel = $false})
RunspaceUmountWim -syncHash $syncHash -mountpath $syncHash.txt_wimmountpath.Text -commit $false -wimPathCreated $Global:wimmountPathCreated -edition $Global:edition -log $Global:logFile
})
###--- Canvas 2 End ---###
###--- Canvas 3 Start ---###
$syncHash.btn_openppkg.Add_Click({
$ppkgpath = Read-OpenFileDialog -WindowTitle "Select ProvisioningPackages" -InitialDirectory 'C:\' -Filter "ProvisioningPackages (*.ppkg)|*.ppkg"
if (![string]::IsNullOrEmpty($ppkgpath)) {
$syncHash.listbox_ppkg.Items.Add($ppkgpath)
}
})
$syncHash.btn_openppkg_del.Add_Click({
While ($syncHash.listbox_ppkg.SelectedItems.count -gt 0) {
$syncHash.listbox_ppkg.Items.RemoveAt($syncHash.listbox_ppkg.SelectedIndex)
}
})
$syncHash.btn_back_3.Add_Click({
$syncHash.can_removeppx.Visibility = "Visible"
$syncHash.can_addppkg.Visibility = "Hidden"
})
$syncHash.btn_next_3.Add_Click({
RunspaceCheckFeatures -syncHash $syncHash -mountpath $syncHash.txt_wimmountpath.Text
})
$syncHash.btn_cancel_3.Add_Click({
$syncHash.Window.Add_Closing({$_.Cancel = $false})
RunspaceUmountWim -syncHash $syncHash -mountpath $syncHash.txt_wimmountpath.Text -commit $false -wimPathCreated $Global:wimmountPathCreated -edition $Global:edition -log $Global:logFile
})
###--- Canvas 3 End ---###
###--- Canvas 3.1 Start ---###
$syncHash.btn_patchie11.Add_Click({
$_patchie11Path = Read-FolderBrowserDialog -Message "Please select a directory" -InitialDirectory '' -NoNewFolderButton
if (![string]::IsNullOrEmpty($_patchie11Path)){
$Global:patchie11path = $_patchie11Path
}
$syncHash.txt_patchpathie11.Text = $Global:patchie11Path
})
$syncHash.btn_back_3_1.Add_Click({
$syncHash.can_removeppx.Visibility = "Visible"
$syncHash.can_w7patch.Visibility = "Hidden"
})
$syncHash.btn_next_3_1.Add_Click({
RunspaceCheckFeatures -syncHash $syncHash -mountpath $syncHash.txt_wimmountpath.Text
})
$syncHash.btn_cancel_3_1.Add_Click({
$syncHash.Window.Add_Closing({$_.Cancel = $false})
RunspaceUmountWim -syncHash $syncHash -mountpath $syncHash.txt_wimmountpath.Text -commit $false -wimPathCreated $Global:wimmountPathCreated -edition $Global:edition -log $Global:logFile
})
###--- Canvas 3.1 End ---###
###--- Canvas 4 Start ---###
$syncHash.btn_back_4.Add_Click({
$syncHash.listbox_feature_a.Items.Clear()
$syncHash.listbox_feature_d.Items.Clear()
if($Global:edition -match "Windows 7" -or $Global:edition -match "Windows 8"){
$syncHash.can_w7patch.Visibility = "Visible"
$syncHash.grid_feature_3_1.Visibility = "Hidden"
$syncHash.can_features.Visibility = "Hidden"
} else {
$syncHash.can_addppkg.Visibility = "Visible"
$syncHash.grid_feature_3.Visibility = "Hidden"
$syncHash.can_features.Visibility = "Hidden"
}
if($Global:edition -match "Windows 7"){
$syncHash.txtb_5_1.Visibility = "Hidden"
}
})
$syncHash.btn_next_4.Add_Click({
# Create PPKG List
$Global:ppkgList = @()
foreach ($ppkgItem in $syncHash.listbox_ppkg.Items){
$Global:ppkgList += $ppkgItem
}
# Create PPKG ListView
foreach($ppkg in $Global:ppkgList)
{
$syncHash.listview_ppkg.Items.Add($ppkg)
}
# Create appx ListView
foreach($appx in $Global:appxselectedList)
{
$syncHash.listview_appx.Items.Add($appx)
}
# Create feature ListView
$syncHash.listview_features.Items.Add("deactivate:")
foreach($featureitema in $syncHash.listbox_feature_a.SelectedItems){
$Global:selectedFeaturesDisable += $featureitema
$syncHash.listview_features.Items.Add($featureitema)
}
$syncHash.listview_features.Items.Add("activate:")
foreach($featureitemd in $syncHash.listbox_feature_d.SelectedItems){
$Global:selectedFeaturesEnable += $featureitemd
$syncHash.listview_features.Items.Add($featureitemd)
}
# Check Patchintall
if($Global:edition -match "Windows 7" -or $edition -match "Windows 8"){
$Global:patchesCheck = $syncHash.ch_patches_w7.IsChecked
$Global:patchie11 = $syncHash.ch_ie11.IsChecked
} else {
$Global:patchesCheck = $syncHash.ch_patches.IsChecked
}
IF ($Global:patchesCheck -eq "True"){
$syncHash.txtb_5.Text = "Integrate Windows patches"
} Else {
$syncHash.txtb_5.Text = "Do not integrate Windows patches"
}
# Check OnDrive
$Global:ondriveCheck = $syncHash.ch_onedrive.IsChecked
IF ($Global:ondriveCheck -eq "True"){
$syncHash.txtb_5_1.Text = "OneDrive Setup will be removed for all users"
} Else {
$syncHash.txtb_5_1.Text = "OneDrive Setup will not be removed"
}
# Use textbox for IE11 info
if($Global:patchie11 -eq "True" -and $Global:edition -match "Windows 7"){
$syncHash.txtb_5_1.Text = "Integrate IE11"
$syncHash.txtb_5_1.Visibility = "Visible"
}
# Check APP-advertising
$Global:appxAdvertisingCheck = $syncHash.ch_appx.IsChecked
IF ($Global:appxAdvertisingCheck -eq "True"){
$syncHash.txtb_5_2.Text = "Remove APPX-advertising"
} Else {
$syncHash.txtb_5_2.Text = "Do not remove APPX-advertising"
}
# Check StartLayout
$Global:starlayoutCheck = $syncHash.ch_startlayout.IsChecked
IF ($Global:starlayoutCheck -eq "True") {
$syncHash.txtb_5_3.Text = "Integrate StartLayout"
} Else {
$syncHash.txtb_5_3.Text = "Do not integrate StartLayout"
}
# Check FileAssociation
$Global:fileassociationCheck = $syncHash.ch_fileassociation.IsChecked
IF ($Global:fileassociationCheck -eq "True") {
$syncHash.txtb_5_4.Text = "Integrate FileAssociation"
} Else {
$syncHash.txtb_5_4.Text = "Do not integrate FileAssociation"
}
# Load new canvas
$syncHash.can_features.Visibility = "Hidden"
$syncHash.can_change.Visibility = "Visible"
})
$syncHash.btn_cancel_4.Add_Click({
$syncHash.Window.Add_Closing({$_.Cancel = $false})
RunspaceUmountWim -syncHash $syncHash -mountpath $syncHash.txt_wimmountpath.Text -commit $false -wimPathCreated $Global:wimmountPathCreated -edition $Global:edition -log $Global:logFile
})
###--- Canvas 4 End ---###
###--- Canvas 5 Start ---###
$syncHash.btn_back_5.Add_Click({
$Global:appxselectedList = @()
$syncHash.listview_appx.Items.Clear()
$Global:ppkgList = @()
$Global:selectedFeaturesEnable = @()
$Global:selectedFeaturesDisable = @()
$syncHash.listview_features.Items.Clear()
$syncHash.listview_ppkg.Items.Clear()
$syncHash.can_features.Visibility = "Visible"
$syncHash.can_change.Visibility = "Hidden"
})
# Finsh to save changes to install.wim
$syncHash.btn_finish.Add_Click({
try {
$syncHash.can_change.Visibility = "Hidden"
$syncHash.can_result.Visibility = "Visible"
# Deactivate OneDrive Setup in default User Profile
if ($Global:ondriveCheck -eq "True"){
reg load HKU\TEMP $Global:wimmountPath\Users\Default\NTUSER.DAT
New-PSDrive -PSProvider registry -Root HKEY_USERS -Name HKU
Remove-ItemProperty -Name 'OneDriveSetup' -Path 'HKU:\TEMP\SOFTWARE\Microsoft\Windows\CurrentVersion\Run' | Write-LogFile
reg unload HKU\TEMP
Remove-PSDrive -Name HKU -Force
Write-LogFile "============================================================="
Write-LogFile "OneDrive Setup was disabled for all users."
Write-LogFile "============================================================="
$syncHash.listbox_result.Items.Add("=============================================================")
$syncHash.listbox_result.Items.Add("OneDrive Setup was disabled for all users.")
$syncHash.listbox_result.Items.Add("=============================================================")
}
# deactivate APPX advertising
if ($Global:appxAdvertisingCheck -eq "True"){
reg load HKU\TEMP $Global:wimmountPath\Users\Default\NTUSER.DAT
New-PSDrive -PSProvider registry -Root HKEY_USERS -Name HKU
Set-ItemProperty -Path 'HKU:\TEMP\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -Name SystemPaneSuggestionsEnabled -Value 0
Set-ItemProperty -Path 'HKU:\TEMP\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -Name OemPreInstalledAppsEnabled -Value 0
Set-ItemProperty -Path 'HKU:\TEMP\SOFTWARE\Microsoft\Windows\CurrentVersion\ContentDeliveryManager' -Name PreInstalledAppsEnabled -Value 0
reg unload HKU\TEMP
Remove-PSDrive -Name HKU -Force
Write-LogFile "============================================================="
Write-LogFile "APPX-advertising was disabled for all users."
Write-LogFile "============================================================="
$syncHash.listbox_result.Items.Add("=============================================================")
$syncHash.listbox_result.Items.Add("APPX-advertising was disabled for all users.")
$syncHash.listbox_result.Items.Add("=============================================================")
}
# StartLayout integration
if ($Global:starlayoutCheck -eq "True") {
Write-LogFile "============================================================="
Write-LogFile "=== Integrate StartLayout: =================================="
$syncHash.listbox_result.Items.Add("=============================================================")
$syncHash.listbox_result.Items.Add("=== Integrate StartLayout: ==================================")
$_link = Get-ChildItem -Path $Global:startlayoutIELinkPath -Filter *.lnk
if ($_link.Exists) {
Copy-Item -Force $_link.FullName "$Global:wimmountPath\ProgramData\Microsoft\Windows\Start Menu\Programs\Internet Explorer.lnk" -Verbose | Write-LogFile
}
Copy-Item -Force $Global:startlayoutPath "$Global:wimmountPath\Users\Default\AppData\Local\Microsoft\Windows\Shell\LayoutModification.xml" -Verbose | Write-LogFile
Write-LogFile "============================================================="
$syncHash.listbox_result.Items.Add("=============================================================")
}
# Integrate FileAssociation
if ($Global:fileassociationCheck -eq "True") {
Write-LogFile "============================================================="
Write-LogFile "=== Integrate FileAssociation: =============================="
$syncHash.listbox_result.Items.Add("=============================================================")
$syncHash.listbox_result.Items.Add("=== Integrate FileAssociation: ==============================")
Dism.exe /Image:$Global:wimmountPath /Import-DefaultAppAssociations:$Global:fileassociationPath | Write-LogFile
Write-LogFile "============================================================="
$syncHash.listbox_result.Items.Add("=============================================================")
}
# Finalize - APXX|PPKG|patches|features
RunspaceFinalize -synchash $syncHash -mountpath $syncHash.txt_wimmountpath.Text -appxlist $Global:appxselectedList -ppkglist $Global:ppkgList -patchcheck $Global:patchesCheck -patchpath $syncHash.txt_patchpath.Text -patchie11 $Global:patchie11 -patchie11path $Global:patchie11path -featuresenable $Global:selectedFeaturesEnable -wimpath $Global:wimPath -featuresdisable $Global:selectedFeaturesDisable -log $Global:logFile
} catch {
Write-Host $_.Exception
Write-Host $_.ScriptStackTrace
Write-Host ""
Show-ErrMsg -message $_.Exception
} finally {
#$loadingForm.Close()
#$syncHash.Window.Close()
}
})
$syncHash.btn_cancel_5.Add_Click({
$syncHash.Window.Add_Closing({$_.Cancel = $false})
RunspaceUmountWim -syncHash $syncHash -mountpath $syncHash.txt_wimmountpath.Text -commit $false -wimPathCreated $Global:wimmountPathCreated -edition $Global:edition -log $Global:logFile
})
###--- Canvas 5 End ---###
###--- Canvas 6 Start ---###
$syncHash.btn_save.Add_Click({
$syncHash.Window.Add_Closing({$_.Cancel = $false})
RunspaceUmountWim -syncHash $syncHash -mountpath $syncHash.txt_wimmountpath.Text -commit $true -wimPathCreated $Global:wimmountPathCreated -edition $Global:edition -log $Global:logFile
})
$syncHash.btn_cancel_6.Add_Click({
$syncHash.Window.Add_Closing({$_.Cancel = $false})
RunspaceUmountWim -syncHash $syncHash -mountpath $syncHash.txt_wimmountpath.Text -commit $false -wimPathCreated $Global:wimmountPathCreated -edition $Global:edition -log $Global:logFile
})
###--- Canvas 6 End ---###
### Disable "X" ###
$syncHash.Window.Add_Closing({$_.Cancel = $true})
$syncHash.Window.ShowDialog()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment