WIMWitch.ps1

<#PSScriptInfo
 
.VERSION 3.2.1
 
.GUID ee1ba506-ac68-45f8-9f37-4555f1902353
 
.AUTHOR Donna Ryan
 
.COMPANYNAME @TheNotoriousDRR
 
.COPYRIGHT
 
.TAGS WIM,Servicing,Offline Image Servicing
 
.LICENSEURI
 
.PROJECTURI
 
.ICONURI
 
.EXTERNALMODULEDEPENDENCIES
 
.REQUIREDSCRIPTS
 
.EXTERNALSCRIPTDEPENDENCIES
 
.RELEASENOTES
 
.PRIVATEDATA
 
#>


<#
.DESCRIPTION
 WIM Witch is a GUI driven tool used to update and customize Windows
 Image (WIM) files and ISOs. It can also create WIM configuration templates and
 apply them either with the GUI or programatically for bulk creation. WIM Witch
 works as a stand alone tool, as well as integrating with Configuration Manager
  
 Version 3.2.1
 
 -Fixed bug for download Server 2019/2022 and Win11 with OSDSUS
 
 Version 3.2.0.
 
 -Adds support for Windows 11 and Server 2022
 -Adds functionality to better handle SSUs with certain win10 versions
 -Adds functionality to select XML or JSON for Windows 11 Start Menu
 -Improves Windows Type and version during runtime
  
 #>



#===========================================================================
# WIM Witch
#===========================================================================
#
# Written and maintained by: Donna Ryan
# Twitter: @TheNotoriousDRR
# www.TheNotoriousDRR.com
# www.MSEndpointMgr.com
#
# Current WIM Witch Doc (v3.2.0)
# https://msendpointmgr.com/2021/10/22/wim-witch-v3-2-0-windows-11-and-server-2022-support/
#
# Previous WIM Witch Doc (v3.1.0)
# https://msendpointmgr.com/2021/06/08/wim-witch-v3-1-21h1-support-some-fixes-some-bugs/
#
# Previous WIM Witch Doc (v3.0.0)
# https://msendpointmgr.com/2021/02/03/wim-witch-v3-0-0-configuration-manager-console-extension/
#
# Previous WIM Witch Doc (v2.3.0)
# https://msendpointmgr.com/2020/08/19/wim-witch-v2-3-0-iso-creation-upgrade-packages-optional-and-dynamic-updates-boot-wim-updating/
#
# Previous WIM Witch Doc (v2.2.0)
# https://msendpointmgr.com/2020/07/30/wim-witch-v2-2-0-start-menu-default-app-association-and-reg-file-support/
#
# Previous WIM Witch Doc (v2.1.0)
# https://msendpointmgr.com/2020/06/05/wim-witch-v2-1-minor-yet-major-updates-to-configmgr-integration-plus-windows-10-2004/
#
# Previous WIM Witch Doc (v2.0.0)
# https://www.scconfigmgr.com/2020/04/13/wim-witch-2-0-configmgr-integration/
#
# Previous WIM Witch Doc (v1.5.0)
# https://www.scconfigmgr.com/2020/03/04/deploying-autopilot-with-mdt-on-usb-a-wim-witch-use-case/
#
# Previous WIM Witch Doc (v1.4.0)
# https://www.scconfigmgr.com/2020/02/05/wim-witch-v1-4-0-language-packs-features-on-demand-and-local-experience-packs/
#
# Previous WIM Witch Doc (v1.3.0):
# https://www.scconfigmgr.com/2019/12/08/wim-witch-v1-3-0-server-support-onedrive-and-command-line/
#
# Previous WIM Witch Doc (v1.0):
# https://www.scconfigmgr.com/2019/10/04/wim-witch-a-gui-driven-solution-for-image-customization/
#
#===========================================================================
#
#
#
#################################################
#
# Community Contributions to WIM Witch
#################################################
#
# Mykael Niestrom - Update function stolen with pride from one
# his projects. I'm pretty sure it was a hydration kit...
#
# Dave Segura - OneDrive download function copied
# from OSDBuilder. Most importantly, the OSDSUS and OSDUPDATE functions.
# WIM Witch wouldn't be where she is today without them. Thank you, David!
#
# Nickolaj Andersen - WIM Witch assimilated his ConfigMgr Software
# Update catalog functions, adding their biological and technical
# distinctiveness to her own.
#
# Bryan Dam and Jordan Benzing - Sanity checks and stuPID
# questions.
#
# Michael Mardahl - Creating the ESD coversion process, and improvements
# to the whole ISO import function
#
# Thanks to all of WIM Witch users who gave feed back, tested bugs,
# provided encouragement, and/or found WIM Witch usefull and
# spread the word.
#
###################################################


#============================================================================================================
Param( 
   [parameter(mandatory = $false, HelpMessage = "enable auto")] 
    [switch]$auto,

    [parameter(mandatory = $false, HelpMessage = "config file")] 
    [string]$autofile,

    [parameter(mandatory = $false, HelpMessage = "config path")] 
    [string]$autopath,
    
    [parameter(mandatory = $false, HelpMessage = "Update Modules")] 
    [Switch]$UpdatePoShModules,

    [parameter(mandatory = $false, HelpMessage = "Enable Downloading Updates")] 
    [switch]$DownloadUpdates,
  
    [parameter(mandatory = $false, HelpMessage = "Win10 Version")] 
    [ValidateSet("all", "1809", "1909","2004","20H2","21H1")] 
    [string]$Win10Version = "none",

    [parameter(mandatory = $false, HelpMessage = "Win11 Version")] 
    [ValidateSet("all","21H2")] 
    [string]$Win11Version = "none",

    [parameter(mandatory = $false, HelpMessage = "Windows Server 2016")] 
    [switch]$Server2016,

    [parameter(mandatory = $false, HelpMessage = "Windows Server 2019")] 
    [switch]$Server2019,

    [parameter(mandatory = $false, HelpMessage = "Windows Server 2022")] 
    [switch]$Server2022,

    [parameter(mandatory = $false, HelpMessage = "This is not helpful")]
    [switch]$HiHungryImDad,

    [parameter(mandatory = $false, HelpMessage = "CM Option")] 
    [ValidateSet("New", "Edit")] 
    [string]$CM = "none",

    [parameter(mandatory = $false, HelpMessage ="Skip free space check")]
    [switch]$SkipFreeSpaceCheck
 
)

$WWScriptVer = "3.2.1"

#Your XAML goes here :)
$inputXML = @"
<Window x:Class="WIM_Witch_Tabbed.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WIM_Witch_Tabbed"
        mc:Ignorable="d"
        Title="WIM Witch - $WWScriptVer" Height="500" Width="800" Background="#FF610536">
    <Grid>
        <TabControl x:Name="TabControl" Margin="-3,-1,3,1" Background="#FFACACAC" BorderBrush="#FF610536" >
            <TabItem Header="Import WIM + .Net" Height="20" MinWidth="100">
                <Grid>
                    <TextBox x:Name="ImportISOTextBox" HorizontalAlignment="Left" Height="42" Margin="26,85,0,0" Text="ISO to import from..." VerticalAlignment="Top" Width="500" IsEnabled="False" HorizontalScrollBarVisibility="Visible"/>
                    <TextBlock HorizontalAlignment="Left" Margin="26,56,0,0" TextWrapping="Wrap" Text="Select a Windows 10 ISO:" VerticalAlignment="Top" Height="26" Width="353"/>
                    <Button x:Name="ImportImportSelectButton" Content="Select" HorizontalAlignment="Left" Margin="553,85,0,0" VerticalAlignment="Top" Width="75"/>
                    <TextBlock HorizontalAlignment="Left" Margin="26,149,0,0" TextWrapping="Wrap" Text="Select the item(s) to import:" VerticalAlignment="Top" Width="263"/>
                    <CheckBox x:Name="ImportWIMCheckBox" Content="Install.wim" HorizontalAlignment="Left" Margin="44,171,0,0" VerticalAlignment="Top"/>
                    <CheckBox x:Name="ImportDotNetCheckBox" Content=".Net Binaries" HorizontalAlignment="Left" Margin="44,191,0,0" VerticalAlignment="Top"/>
                    <TextBlock HorizontalAlignment="Left" Margin="26,240,0,0" TextWrapping="Wrap" Text="New name for the imported WIM:" VerticalAlignment="Top" Width="311"/>
                    <TextBox x:Name="ImportNewNameTextBox" HorizontalAlignment="Left" Height="23" Margin="26,261,0,0" TextWrapping="Wrap" Text="Name for the imported WIM" VerticalAlignment="Top" Width="500" IsEnabled="False"/>
                    <Button x:Name="ImportImportButton" Content="Import" HorizontalAlignment="Left" Margin="553,261,0,0" VerticalAlignment="Top" Width="75" IsEnabled="False"/>
                    <CheckBox x:Name="ImportISOCheckBox" Content="ISO / Upgrade Package Files" HorizontalAlignment="Left" Margin="44,212,0,0" VerticalAlignment="Top"/>
                </Grid>
            </TabItem>
            <TabItem Header="Import LP+FOD" Margin="0" MinWidth="100">
                <Grid>
                    <TextBox x:Name="ImportOtherTBPath" HorizontalAlignment="Left" Height="23" Margin="49,92,0,0" TextWrapping="Wrap" Text="path to source" VerticalAlignment="Top" Width="339" IsEnabled="False"/>
                    <Button x:Name="ImportOtherBSelectPath" Content="Select" HorizontalAlignment="Left" Margin="413,94,0,0" VerticalAlignment="Top" Width="75"/>
                    <TextBlock HorizontalAlignment="Left" Margin="49,130,0,0" TextWrapping="Wrap" Text="Selected items" VerticalAlignment="Top"/>
                    <ComboBox x:Name="ImportOtherCBWinOS" HorizontalAlignment="Left" Margin="228,51,0,0" VerticalAlignment="Top" Width="120"/>
                    <ComboBox x:Name="ImportOtherCBWinVer" HorizontalAlignment="Left" Margin="371,50,0,0" VerticalAlignment="Top" Width="120"/>
                    <Button x:Name="ImportOtherBImport" Content="Import" HorizontalAlignment="Left" Margin="417,317,0,0" VerticalAlignment="Top" Width="75"/>
                    <ComboBox x:Name="ImportOtherCBType" HorizontalAlignment="Left" Margin="51,51,0,0" VerticalAlignment="Top" Width="160"/>
                    <TextBlock HorizontalAlignment="Left" Margin="51,26,0,0" TextWrapping="Wrap" Text="Object Type" VerticalAlignment="Top"/>
                    <TextBlock HorizontalAlignment="Left" Margin="230,32,0,0" TextWrapping="Wrap" Text="Windows OS" VerticalAlignment="Top"/>
                    <TextBlock HorizontalAlignment="Left" Margin="372,31,0,0" TextWrapping="Wrap" Text="Version" VerticalAlignment="Top"/>
                    <ListBox x:Name="ImportOtherLBList" HorizontalAlignment="Left" Height="149" Margin="49,151,0,0" VerticalAlignment="Top" Width="442"/>
 
                </Grid>
 
            </TabItem>
            <TabItem x:Name="CustomTab" Header="Pause + Scripts" MinWidth="100">
                <Grid>
                    <TextBox x:Name="CustomTBFile" HorizontalAlignment="Left" Height="23" Margin="49,157,0,0" TextWrapping="Wrap" Text="PowerShell Script" VerticalAlignment="Top" Width="501" IsEnabled="False"/>
                    <TextBox x:Name="CustomTBParameters" HorizontalAlignment="Left" Height="23" Margin="49,207,0,0" TextWrapping="Wrap" Text="Parameters" VerticalAlignment="Top" Width="501" IsEnabled="False"/>
                    <Button x:Name="CustomBSelectPath" Content="Select" HorizontalAlignment="Left" Margin="566,158,0,0" VerticalAlignment="Top" Width="75" IsEnabled="False"/>
                    <CheckBox x:Name="CustomCBRunScript" Content="Run Script" HorizontalAlignment="Left" Margin="49,102,0,0" VerticalAlignment="Top"/>
                    <ComboBox x:Name="CustomCBScriptTiming" HorizontalAlignment="Left" Margin="163,102,0,0" VerticalAlignment="Top" Width="172" IsEnabled="False"/>
                    <CheckBox x:Name="MISCBPauseMount" Content="Pause after mounting" HorizontalAlignment="Left" Margin="49,42,0,0" VerticalAlignment="Top"/>
                    <CheckBox x:Name="MISCBPauseDismount" Content="Pause before dismounting" HorizontalAlignment="Left" Margin="49,71,0,0" VerticalAlignment="Top"/>
                </Grid>
            </TabItem>
            <TabItem Header="Drivers" Height="20" MinWidth="100">
                <Grid>
                    <TextBox x:Name="DriverDir1TextBox" HorizontalAlignment="Left" Height="25" Margin="26,144,0,0" TextWrapping="Wrap" Text="Select Driver Source Folder" VerticalAlignment="Top" Width="500" IsEnabled="False"/>
                    <Label x:Name="DirverDirLabel" Content="Driver Source" HorizontalAlignment="Left" Height="25" Margin="26,114,0,0" VerticalAlignment="Top" Width="100"/>
                    <Button x:Name="DriverDir1Button" Content="Select" HorizontalAlignment="Left" Height="25" Margin="562,144,0,0" VerticalAlignment="Top" Width="75" IsEnabled="False"/>
                    <TextBlock HorizontalAlignment="Left" Margin="26,20,0,0" TextWrapping="Wrap" Text="Select the path to the driver source(s) that contains the drivers that will be injected." VerticalAlignment="Top" Height="42" Width="353"/>
                    <CheckBox x:Name="DriverCheckBox" Content="Enable Driver Injection" HorizontalAlignment="Left" Margin="26,80,0,0" VerticalAlignment="Top"/>
                    <TextBox x:Name="DriverDir2TextBox" HorizontalAlignment="Left" Height="25" Margin="26,189,0,0" TextWrapping="Wrap" Text="Select Driver Source Folder" VerticalAlignment="Top" Width="500" IsEnabled="False"/>
                    <Button x:Name="DriverDir2Button" Content="Select" HorizontalAlignment="Left" Height="25" Margin="562,189,0,0" VerticalAlignment="Top" Width="75" IsEnabled="False"/>
                    <TextBox x:Name="DriverDir3TextBox" HorizontalAlignment="Left" Height="25" Margin="26,234,0,0" TextWrapping="Wrap" Text="Select Driver Source Folder" VerticalAlignment="Top" Width="500" IsEnabled="False"/>
                    <Button x:Name="DriverDir3Button" Content="Select" HorizontalAlignment="Left" Height="25" Margin="562,234,0,0" VerticalAlignment="Top" Width="75" IsEnabled="False"/>
                    <TextBox x:Name="DriverDir4TextBox" HorizontalAlignment="Left" Height="25" Margin="26,281,0,0" TextWrapping="Wrap" Text="Select Driver Source Folder" VerticalAlignment="Top" Width="500" IsEnabled="False"/>
                    <Button x:Name="DriverDir4Button" Content="Select" HorizontalAlignment="Left" Height="25" Margin="562,281,0,0" VerticalAlignment="Top" Width="75" IsEnabled="False"/>
                    <TextBox x:Name="DriverDir5TextBox" HorizontalAlignment="Left" Height="25" Margin="26,328,0,0" TextWrapping="Wrap" Text="Select Driver Source Folder" VerticalAlignment="Top" Width="500" IsEnabled="False"/>
                    <Button x:Name="DriverDir5Button" Content="Select" HorizontalAlignment="Left" Height="25" Margin="562,328,0,0" VerticalAlignment="Top" Width="75" IsEnabled="False"/>
                </Grid>
            </TabItem>
            <TabItem x:Name="AutopilotTab" Header="Autopilot" MinWidth="100">
                <Grid>
                    <TextBox x:Name="JSONTextBox" HorizontalAlignment="Left" Height="25" Margin="26,130,0,0" TextWrapping="Wrap" Text="Select JSON File" VerticalAlignment="Top" Width="500" IsEnabled="False"/>
                    <Label x:Name="JSONLabel" Content="Source JSON" HorizontalAlignment="Left" Height="25" Margin="26,104,0,0" VerticalAlignment="Top" Width="100"/>
                    <Button x:Name="JSONButton" Content="Select" HorizontalAlignment="Left" Height="25" Margin="451,165,0,0" VerticalAlignment="Top" Width="75" IsEnabled="False"/>
                    <TextBlock HorizontalAlignment="Left" Margin="26,20,0,0" TextWrapping="Wrap" Text="Select a JSON file for use in deploying Autopilot systems. The file will be copied to processing folder during the build" VerticalAlignment="Top" Height="42" Width="353"/>
                    <CheckBox x:Name="JSONEnableCheckBox" Content="Enable Autopilot " HorizontalAlignment="Left" Margin="26,80,0,0" VerticalAlignment="Top" ClickMode="Press"/>
                    <TextBox x:Name="ZtdCorrelationId" HorizontalAlignment="Left" Height="23" Margin="129,176,0,0" TextWrapping="Wrap" Text="Select JSON File..." VerticalAlignment="Top" Width="236" IsEnabled="False"/>
                    <TextBox x:Name="CloudAssignedTenantDomain" HorizontalAlignment="Left" Height="23" Margin="129,204,0,0" TextWrapping="Wrap" Text="Select JSON File..." VerticalAlignment="Top" Width="236" IsEnabled="False"/>
                    <TextBox x:Name="Comment_File" HorizontalAlignment="Left" Height="23" Margin="129,232,0,0" TextWrapping="Wrap" Text="Select JSON File..." VerticalAlignment="Top" Width="236" IsEnabled="False"/>
                    <TextBlock HorizontalAlignment="Left" Margin="24,178,0,0" TextWrapping="Wrap" Text="ZTD ID#" VerticalAlignment="Top"/>
                    <TextBlock HorizontalAlignment="Left" Margin="24,204,0,0" TextWrapping="Wrap" Text="Tenant Name" VerticalAlignment="Top"/>
                    <TextBlock HorizontalAlignment="Left" Margin="24,233,0,0" TextWrapping="Wrap" Text="Deployment Profile" VerticalAlignment="Top"/>
                    <TextBox x:Name="JSONTextBoxSavePath" HorizontalAlignment="Left" Height="23" Margin="26,345,0,0" TextWrapping="Wrap" Text="$PSScriptRoot\Autopilot" VerticalAlignment="Top" Width="499" IsEnabled="False"/>
                    <TextBlock HorizontalAlignment="Left" Margin="26,275,0,0" TextWrapping="Wrap" Text="To download a new Autopilot profile from Intune, click select to choose the folder to save the file to. Then click Retrieve Profile." VerticalAlignment="Top" Height="48" Width="331"/>
                    <TextBlock HorizontalAlignment="Left" Margin="27,328,0,0" TextWrapping="Wrap" Text="Path to save file:" VerticalAlignment="Top"/>
                    <Button x:Name="JSONButtonSavePath" Content="Select" HorizontalAlignment="Left" Margin="450,373,0,0" VerticalAlignment="Top" Width="75"/>
                    <Button x:Name="JSONButtonRetrieve" Content="Retrieve Profile" HorizontalAlignment="Left" Margin="382,275,0,0" VerticalAlignment="Top" Width="130"/>
                </Grid>
            </TabItem>
            <TabItem Header="Save/Load" Height="20" MinWidth="102">
                <Grid>
                    <TextBox x:Name="SLSaveFileName" HorizontalAlignment="Left" Height="25" Margin="26,85,0,0" TextWrapping="Wrap" Text="Name for saved configuration..." VerticalAlignment="Top" Width="500"/>
                    <TextBlock HorizontalAlignment="Left" Margin="26,38,0,0" TextWrapping="Wrap" Text="Provide a name for the saved configuration" VerticalAlignment="Top" Height="42" Width="353"/>
                    <Button x:Name="SLSaveButton" Content="Save" HorizontalAlignment="Left" Margin="451,127,0,0" VerticalAlignment="Top" Width="75"/>
                    <Border BorderBrush="Black" BorderThickness="1" HorizontalAlignment="Left" Height="1" Margin="0,216,0,0" VerticalAlignment="Top" Width="785"/>
                    <TextBox x:Name="SLLoadTextBox" HorizontalAlignment="Left" Height="23" Margin="26,308,0,0" TextWrapping="Wrap" Text="Select configuration file to load" VerticalAlignment="Top" Width="500"/>
                    <Button x:Name="SLLoadButton" Content="Load" HorizontalAlignment="Left" Margin="451,351,0,0" VerticalAlignment="Top" Width="75"/>
                    <TextBlock HorizontalAlignment="Left" Margin="26,279,0,0" TextWrapping="Wrap" Text="Select configuration file to load" VerticalAlignment="Top" Width="353"/>
                </Grid>
            </TabItem>
            <TabItem Header="Source WIM" Margin="0" MinWidth="100">
                <Grid>
                    <TextBox x:Name="SourceWIMSelectWIMTextBox" HorizontalAlignment="Left" Height="25" Margin="26,98,0,0" TextWrapping="Wrap" Text="Select WIM File" VerticalAlignment="Top" Width="500" IsEnabled="False" Grid.ColumnSpan="2"/>
                    <Label Content="Source Wim " HorizontalAlignment="Left" Height="25" Margin="26,70,0,0" VerticalAlignment="Top" Width="100"/>
                    <TextBlock HorizontalAlignment="Left" Margin="26,20,0,0" TextWrapping="Wrap" Text="Select the WIM file, and then Edition, that will serve as the base for the custom WIM." VerticalAlignment="Top" Height="42" Width="353" Grid.ColumnSpan="2"/>
                    <Button x:Name="SourceWIMSelectButton" Content="Select" HorizontalAlignment="Left" Height="25" Margin="450,153,0,0" VerticalAlignment="Top" Width="75"/>
                    <TextBox x:Name="SourceWIMImgDesTextBox" HorizontalAlignment="Left" Height="23" Margin="94,155,0,0" TextWrapping="Wrap" Text="ImageDescription" VerticalAlignment="Top" Width="339" IsEnabled="False"/>
                    <TextBox x:Name="SourceWimArchTextBox" HorizontalAlignment="Left" Height="23" Margin="94,183,0,0" TextWrapping="Wrap" Text="Architecture" VerticalAlignment="Top" Width="225" IsEnabled="False"/>
                    <TextBox x:Name="SourceWimVerTextBox" HorizontalAlignment="Left" Height="23" Margin="94,211,0,0" TextWrapping="Wrap" Text="Build" VerticalAlignment="Top" Width="225" IsEnabled="False"/>
                    <TextBox x:Name="SourceWimSPBuildTextBox" HorizontalAlignment="Left" Height="23" Margin="94,239,0,0" TextWrapping="Wrap" Text="SPBuild" VerticalAlignment="Top" Width="225" IsEnabled="False"/>
                    <TextBox x:Name="SourceWimLangTextBox" HorizontalAlignment="Left" Height="23" Margin="94,267,0,0" TextWrapping="Wrap" Text="Languages" VerticalAlignment="Top" Width="225" IsEnabled="False"/>
                    <Label Content="Edition" HorizontalAlignment="Left" Height="30" Margin="22,151,0,0" VerticalAlignment="Top" Width="68"/>
                    <Label Content="Arch" HorizontalAlignment="Left" Height="30" Margin="22,183,0,0" VerticalAlignment="Top" Width="68"/>
                    <Label Content="Build" HorizontalAlignment="Left" Height="30" Margin="22,211,0,0" VerticalAlignment="Top" Width="68"/>
                    <Label Content="Patch Level" HorizontalAlignment="Left" Height="30" Margin="22,239,0,0" VerticalAlignment="Top" Width="68"/>
                    <Label Content="Languages" HorizontalAlignment="Left" Height="30" Margin="22,267,0,0" VerticalAlignment="Top" Width="68"/>
                    <TextBox x:Name="SourceWimIndexTextBox" HorizontalAlignment="Left" Height="23" Margin="94,297,0,0" TextWrapping="Wrap" Text="Index" VerticalAlignment="Top" Width="225" IsEnabled="False"/>
                    <Label Content="Index" HorizontalAlignment="Left" Height="30" Margin="22,297,0,0" VerticalAlignment="Top" Width="68"/>
                    <TextBox x:Name="SourceWimTBVersionNum" HorizontalAlignment="Left" Height="23" Margin="94,325,0,0" TextWrapping="Wrap" Text="Version Number" VerticalAlignment="Top" Width="225" IsEnabled="False"/>
                    <Label Content="Version" HorizontalAlignment="Left" Height="30" Margin="22,321,0,0" VerticalAlignment="Top" Width="68"/>
                </Grid>
            </TabItem>
            <TabItem Header="Update Catalog" Height="20" MinWidth="100" Margin="-2,0,-2,0" VerticalAlignment="Top">
                <Grid>
                    <ComboBox x:Name="USCBSelectCatalogSource" HorizontalAlignment="Left" Margin="26,48,0,0" VerticalAlignment="Top" Width="160" />
                    <TextBlock HorizontalAlignment="Left" Margin="91,275,0,0" TextWrapping="Wrap" Text="Installed version " VerticalAlignment="Top"/>
                    <TextBox x:Name="UpdatesOSDBVersion" HorizontalAlignment="Left" Height="23" Margin="91,297,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" IsEnabled="False"/>
                    <Button x:Name="UpdateOSDBUpdateButton" Content="Install / Update" HorizontalAlignment="Left" Margin="218,362,0,0" VerticalAlignment="Top" Width="120"/>
                    <TextBlock HorizontalAlignment="Left" Height="42" Margin="31,85,0,0" TextWrapping="Wrap" Text="Select which versions of Windows to download current patches for. Downloading will also purge superseded updates." VerticalAlignment="Top" Width="335"/>
                    <CheckBox x:Name="UpdatesW10_1903" Content="1903" HorizontalAlignment="Left" Margin="67,183,0,0" VerticalAlignment="Top" IsEnabled="False" Visibility="Hidden"/>
                    <CheckBox x:Name="UpdatesW10_1809" Content="1809" HorizontalAlignment="Left" Margin="163,191,0,0" VerticalAlignment="Top" IsEnabled="False"/>
                    <CheckBox x:Name="UpdatesW10_1803" Content="1803" HorizontalAlignment="Left" Margin="194,182,0,0" VerticalAlignment="Top" IsEnabled="False" Visibility="Hidden"/>
                    <CheckBox x:Name="UpdatesW10_1709" Content="1709" HorizontalAlignment="Left" Margin="251,182,0,0" VerticalAlignment="Top" IsEnabled="False" Visibility="Hidden"/>
                    <Button x:Name="UpdatesDownloadNewButton" Content="Download" HorizontalAlignment="Left" Margin="291,239,0,0" VerticalAlignment="Top" Width="75"/>
                    <TextBox x:Name="UpdatesOSDBCurrentVerTextBox" HorizontalAlignment="Left" Height="23" Margin="218,296,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" IsEnabled="False"/>
                    <TextBlock HorizontalAlignment="Left" Margin="218,275,0,0" TextWrapping="Wrap" Text="Current Version" VerticalAlignment="Top"/>
                    <TextBlock x:Name="UpdatesOSDBOutOfDateTextBlock" HorizontalAlignment="Left" Margin="417,364,0,0" TextWrapping="Wrap" Text="A software update module is out of date. Please click the &quot;Install / Update&quot; button to update it." VerticalAlignment="Top" RenderTransformOrigin="0.493,0.524" Width="321" Visibility="Hidden" />
                    <TextBlock x:Name="UpdatesOSDBSupercededExistTextBlock" HorizontalAlignment="Left" Margin="417,328,0,0" TextWrapping="Wrap" Text="Superceded updates discovered. Please select the versions of Windows 10 you are supporting and click &quot;Update&quot;" VerticalAlignment="Top" Width="375" Visibility="Hidden" />
                    <TextBlock x:Name="UpdatesOSDBClosePowerShellTextBlock" HorizontalAlignment="Left" Margin="417,292,0,0" TextWrapping="Wrap" Text="Please close all PowerShell windows, including WIM Witch, then relaunch app to continue" VerticalAlignment="Top" RenderTransformOrigin="0.493,0.524" Width="321" Visibility="Hidden"/>
                    <TextBlock HorizontalAlignment="Left" Margin="24,297,0,0" TextWrapping="Wrap" Text="OSDUpdate" VerticalAlignment="Top"/>
                    <TextBlock HorizontalAlignment="Left" Margin="26,334,0,0" TextWrapping="Wrap" Text="OSDSUS" VerticalAlignment="Top"/>
                    <TextBox x:Name="UpdatesOSDSUSVersion" HorizontalAlignment="Left" Height="23" Margin="91,330,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" IsEnabled="False"/>
                    <TextBox x:Name="UpdatesOSDSUSCurrentVerTextBox" HorizontalAlignment="Left" Height="23" Margin="218,330,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" IsEnabled="False"/>
                    <CheckBox x:Name="UpdatesW10Main" Content="Windows 10" HorizontalAlignment="Left" Margin="46,157,0,0" VerticalAlignment="Top"/>
                    <CheckBox x:Name="UpdatesS2016" Content="Windows Server 2016" HorizontalAlignment="Left" Margin="44,251,0,0" VerticalAlignment="Top"/>
                    <CheckBox x:Name="UpdatesS2019" Content="Windows Server 2019" HorizontalAlignment="Left" Margin="44,232,0,0" VerticalAlignment="Top"/>
                    <CheckBox x:Name="UpdatesW10_1909" Content="1909" HorizontalAlignment="Left" Margin="105,191,0,0" VerticalAlignment="Top" IsEnabled="False"/>
                    <TextBlock x:Name="UpdatesOSDBClosePowerShellTextBlock_Copy" HorizontalAlignment="Left" Margin="26,27,0,0" TextWrapping="Wrap" Text="Select Update Catalog Source" VerticalAlignment="Top" RenderTransformOrigin="0.493,0.524" Width="321"/>
                    <ListBox x:Name="UpdatesOSDListBox" HorizontalAlignment="Left" Height="107" Margin="391,275,0,0" VerticalAlignment="Top" Width="347"/>
                    <CheckBox x:Name="UpdatesW10_2004" Content="2004" HorizontalAlignment="Left" Margin="193,175,0,0" VerticalAlignment="Top" IsEnabled="False"/>
                    <TextBlock HorizontalAlignment="Left" Margin="391,35,0,0" TextWrapping="Wrap" Text="Download Additional Update Types" VerticalAlignment="Top"/>
                    <CheckBox x:Name="UpdatesCBEnableOptional" Content="Optional Updates" HorizontalAlignment="Left" Margin="421,55,0,0" VerticalAlignment="Top"/>
                    <CheckBox x:Name="UpdatesCBEnableDynamic" Content="Dynamic Updates" HorizontalAlignment="Left" Margin="421,77,0,0" VerticalAlignment="Top"/>
                    <CheckBox x:Name="UpdatesW10_20H2" Content="20H2" HorizontalAlignment="Left" Margin="127,175,0,0" VerticalAlignment="Top" IsEnabled="False"/>
                    <CheckBox x:Name="UpdatesW10_21h1" Content="21H1" HorizontalAlignment="Left" Margin="67,175,0,0" VerticalAlignment="Top" IsEnabled="False"/>
                    <CheckBox x:Name="UpdatesW11Main1" Content="Windows 11" HorizontalAlignment="Left" Margin="46,135,0,0" VerticalAlignment="Top"/>
                    <CheckBox x:Name="UpdatesS2022" Content="Windows Server 2022" HorizontalAlignment="Left" Margin="44,215,0,0" VerticalAlignment="Top"/>
                </Grid>
            </TabItem>
            <TabItem Header="Customizations" Height="20" MinWidth="100">
                <Grid>
                    <CheckBox x:Name="CustomCBLangPacks" Content="Inject Language Packs" HorizontalAlignment="Left" Margin="29,37,0,0" VerticalAlignment="Top"/>
                    <Button x:Name="CustomBLangPacksSelect" Content="Select" HorizontalAlignment="Left" Margin="251,27,0,0" VerticalAlignment="Top" Width="132" IsEnabled="False"/>
                    <ListBox x:Name="CustomLBLangPacks" HorizontalAlignment="Left" Height="135" Margin="29,74,0,0" VerticalAlignment="Top" Width="355"/>
                    <TextBlock HorizontalAlignment="Left" Margin="32,55,0,0" TextWrapping="Wrap" Text="Selected LP's" VerticalAlignment="Top" Width="206"/>
                    <CheckBox x:Name="CustomCBFOD" Content="Inject Features on Demand" HorizontalAlignment="Left" Margin="419,126,0,0" VerticalAlignment="Top"/>
                    <Button x:Name="CustomBFODSelect" Content="Select" HorizontalAlignment="Left" Margin="625,120,0,0" VerticalAlignment="Top" Width="133" IsEnabled="False"/>
                    <ListBox x:Name="CustomLBFOD" HorizontalAlignment="Left" Height="224" Margin="419,171,0,0" VerticalAlignment="Top" Width="340"/>
                    <TextBlock HorizontalAlignment="Left" Margin="421,147,0,0" TextWrapping="Wrap" Text="Select from imported Features" VerticalAlignment="Top" Width="206"/>
                    <CheckBox x:Name="CustomCBLEP" Content="Inject Local Experience Packs" HorizontalAlignment="Left" Margin="32,217,0,0" VerticalAlignment="Top"/>
                    <Button x:Name="CustomBLEPSelect" Content="Select" HorizontalAlignment="Left" Margin="251,212,0,0" VerticalAlignment="Top" Width="132" IsEnabled="False"/>
                    <ListBox x:Name="CustomLBLEP" HorizontalAlignment="Left" Height="137" Margin="29,258,0,0" VerticalAlignment="Top" Width="355"/>
                    <TextBlock HorizontalAlignment="Left" Margin="32,237,0,0" TextWrapping="Wrap" Text="Selected LXP's" VerticalAlignment="Top" Width="206"/>
                    <CheckBox x:Name="MISDotNetCheckBox" Content="Inject .Net 3.5" HorizontalAlignment="Left" Margin="418,49,0,0" VerticalAlignment="Top"/>
                    <CheckBox x:Name="MISOneDriveCheckBox" Content="Update OneDrive client" HorizontalAlignment="Left" Margin="418,74,0,0" VerticalAlignment="Top"/>
                    <CheckBox x:Name="UpdatesEnableCheckBox" Content="Enable Updates" HorizontalAlignment="Left" Margin="580,49,0,0" VerticalAlignment="Top" ClickMode="Press"/>
                    <Button x:Name="CustomBLangPacksRemove" Content="Remove" HorizontalAlignment="Left" Margin="251,49,0,0" VerticalAlignment="Top" Width="132" IsEnabled="False"/>
                    <Button x:Name="CustomBLEPSRemove" Content="Remove" HorizontalAlignment="Left" Margin="251,235,0,0" VerticalAlignment="Top" Width="132" IsEnabled="False"/>
                    <Button x:Name="CustomBFODRemove" Content="Remove" HorizontalAlignment="Left" Margin="625,144,0,0" VerticalAlignment="Top" Width="133" IsEnabled="False"/>
                    <CheckBox x:Name="UpdatesOptionalEnableCheckBox" Content="Include Optional" HorizontalAlignment="Left" Margin="596,65,0,0" VerticalAlignment="Top" ClickMode="Press" IsEnabled="False"/>
                </Grid>
            </TabItem>
            <TabItem Header="Other Custom" Height="20" MinWidth="100">
                <Grid>
                    <ListBox x:Name="CustomLBRegistry" HorizontalAlignment="Left" Height="100" Margin="31,247,0,0" VerticalAlignment="Top" Width="440" IsEnabled="False"/>
                    <Button x:Name="CustomBRegistryAdd" Content="Add" HorizontalAlignment="Left" Margin="296,362,0,0" VerticalAlignment="Top" Width="75" IsEnabled="False"/>
                    <Button x:Name="CustomBRegistryRemove" Content="Remove" HorizontalAlignment="Left" Margin="391,362,0,0" VerticalAlignment="Top" Width="75" IsEnabled="False"/>
                    <CheckBox x:Name="CustomCBEnableRegistry" Content="Enable Registry Files" HorizontalAlignment="Left" Margin="31,227,0,0" VerticalAlignment="Top"/>
                    <TextBox x:Name="CustomTBStartMenu" HorizontalAlignment="Left" Height="23" Margin="31,174,0,0" TextWrapping="Wrap" Text="Select Start Menu file" VerticalAlignment="Top" Width="440" IsEnabled="False"/>
                    <Button x:Name="CustomBStartMenu" Content="Select" HorizontalAlignment="Left" Margin="396,202,0,0" VerticalAlignment="Top" Width="75" IsEnabled="False"/>
                    <CheckBox x:Name="CustomCBEnableStart" Content="Enable Start Menu Layout" HorizontalAlignment="Left" Margin="30,152,0,0" VerticalAlignment="Top"/>
                    <TextBox x:Name="CustomTBDefaultApp" HorizontalAlignment="Left" Height="23" Margin="31,92,0,0" TextWrapping="Wrap" Text="Select Default App XML" VerticalAlignment="Top" Width="440" IsEnabled="False"/>
                    <Button x:Name="CustomBDefaultApp" Content="Select" HorizontalAlignment="Left" Margin="396,120,0,0" VerticalAlignment="Top" Width="75" IsEnabled="False"/>
                    <CheckBox x:Name="CustomCBEnableApp" Content="Enable Default App Association" HorizontalAlignment="Left" Margin="30,70,0,0" VerticalAlignment="Top"/>
                </Grid>
            </TabItem>
            <TabItem x:Name="AppTab" Header ="App Removal" Height="20" MinWidth="100">
                <Grid>
                    <TextBox x:Name="AppxTextBox" TextWrapping="Wrap" Text="Select the apps to remove..." Margin="21,85,252.2,22.8" VerticalScrollBarVisibility="Visible"/>
                    <TextBlock HorizontalAlignment="Left" Margin="21,65,0,0" TextWrapping="Wrap" Text="Selected app packages to remove:" VerticalAlignment="Top" Height="15" Width="194"/>
                    <CheckBox x:Name="AppxCheckBox" Content="Enable app removal" HorizontalAlignment="Left" Margin="21,33,0,0" VerticalAlignment="Top"/>
                    <Button x:Name="AppxButton" Content="Select" HorizontalAlignment="Left" Margin="202,33,0,0" VerticalAlignment="Top" Width="75"/>
                </Grid>
            </TabItem>
            <TabItem Header="ConfigMgr" Height="20" MinWidth="102">
                <Grid>
                    <ComboBox x:Name="CMCBImageType" HorizontalAlignment="Left" Margin="39,37,0,0" VerticalAlignment="Top" Width="165"/>
                    <TextBox x:Name="CMTBPackageID" HorizontalAlignment="Left" Height="23" Margin="39,80,0,0" TextWrapping="Wrap" Text="Package ID" VerticalAlignment="Top" Width="120"/>
                    <TextBox x:Name="CMTBImageName" HorizontalAlignment="Left" Height="23" Margin="39,111,0,0" TextWrapping="Wrap" Text="Image Name" VerticalAlignment="Top" Width="290"/>
                    <ListBox x:Name="CMLBDPs" HorizontalAlignment="Left" Height="100" Margin="444,262,0,0" VerticalAlignment="Top" Width="285"/>
                    <TextBox x:Name="CMTBWinBuildNum" HorizontalAlignment="Left" Height="23" Margin="40,142,0,0" TextWrapping="Wrap" Text="Window Build Number" VerticalAlignment="Top" Width="290"/>
                    <TextBox x:Name="CMTBImageVer" HorizontalAlignment="Left" Height="23" Margin="41,187,0,0" TextWrapping="Wrap" Text="Image Version" VerticalAlignment="Top" Width="290"/>
                    <TextBox x:Name="CMTBDescription" HorizontalAlignment="Left" Height="91" Margin="41,216,0,0" TextWrapping="Wrap" Text="Description" VerticalAlignment="Top" Width="290"/>
                    <CheckBox x:Name="CMCBBinDirRep" Content="Enable Binary Differential Replication" HorizontalAlignment="Left" Margin="39,313,0,0" VerticalAlignment="Top"/>
                    <Button x:Name="CMBSelectImage" Content="Select Image" HorizontalAlignment="Left" Margin="230,80,0,0" VerticalAlignment="Top" Width="99"/>
                    <TextBox x:Name="CMTBSitecode" HorizontalAlignment="Left" Height="23" Margin="444,119,0,0" TextWrapping="Wrap" Text="Site Code" VerticalAlignment="Top" Width="120"/>
                    <TextBox x:Name="CMTBSiteServer" HorizontalAlignment="Left" Height="23" Margin="444,146,0,0" TextWrapping="Wrap" Text="Site Server" VerticalAlignment="Top" Width="228"/>
                    <Button x:Name="CMBAddDP" Content="Add" HorizontalAlignment="Left" Margin="444,370,0,0" VerticalAlignment="Top" Width="75"/>
                    <Button x:Name="CMBRemoveDP" Content="Remove" HorizontalAlignment="Left" Margin="532,370,0,0" VerticalAlignment="Top" Width="75"/>
                    <ComboBox x:Name="CMCBDPDPG" HorizontalAlignment="Left" Margin="444,234,0,0" VerticalAlignment="Top" Width="228"/>
                    <CheckBox x:Name="CMCBDeploymentShare" Content="Enable Package Share" HorizontalAlignment="Left" Margin="39,333,0,0" VerticalAlignment="Top"/>
                    <CheckBox x:Name="CMCBImageVerAuto" Content="Auto Fill" HorizontalAlignment="Left" Margin="336,187,0,0" VerticalAlignment="Top"/>
                    <CheckBox x:Name="CMCBDescriptionAuto" Content="Auto Fill" HorizontalAlignment="Left" Margin="336,217,0,0" VerticalAlignment="Top"/>
                    <Button x:Name="CMBInstallExtensions" Content="Install" HorizontalAlignment="Left" Margin="444,55,0,0" VerticalAlignment="Top" Width="75"/>
                    <TextBlock HorizontalAlignment="Left" Margin="445,37,0,0" TextWrapping="Wrap" Text="Click to install CM Console Extension" VerticalAlignment="Top"/>
 
                </Grid>
            </TabItem>
            <TabItem Header="Make It So" Height="20" MinWidth="100">
                <Grid>
                    <CheckBox x:Name="MISCBCheckForUpdates" Margin="544,19,15,376" Content="Check for updates when running" />
                    <Button x:Name="MISFolderButton" Content="Select" HorizontalAlignment="Left" Margin="444,144,0,0" VerticalAlignment="Top" Width="75" RenderTransformOrigin="0.39,-2.647"/>
                    <TextBox x:Name="MISWimNameTextBox" HorizontalAlignment="Left" Height="25" Margin="20,85,0,0" TextWrapping="Wrap" Text="Enter Target WIM Name" VerticalAlignment="Top" Width="500"/>
                    <TextBox x:Name="MISDriverTextBox" HorizontalAlignment="Left" Height="23" Margin="658,345,0,0" TextWrapping="Wrap" Text="Driver Y/N" VerticalAlignment="Top" Width="120" IsEnabled="False"/>
                    <Label Content="Driver injection?" HorizontalAlignment="Left" Height="30" Margin="551,343,0,0" VerticalAlignment="Top" Width="101"/>
                    <TextBox x:Name="MISJSONTextBox" HorizontalAlignment="Left" Height="23" Margin="658,374,0,0" TextWrapping="Wrap" Text="JSON Select Y/N" VerticalAlignment="Top" Width="120" IsEnabled="False"/>
                    <Label Content="JSON injection?" HorizontalAlignment="Left" Margin="551,372,0,0" VerticalAlignment="Top" Width="102"/>
                    <TextBox x:Name="MISWimFolderTextBox" HorizontalAlignment="Left" Height="23" Margin="20,115,0,0" TextWrapping="Wrap" Text="$PSScriptRoot\CompletedWIMs" VerticalAlignment="Top" Width="500"/>
                    <TextBlock HorizontalAlignment="Left" Margin="20,20,0,0" TextWrapping="Wrap" Text="Enter a name, and select a destination forlder, for the image to be created. Once complete, and build parameters verified, click &quot;Make it so!&quot; to start the build." VerticalAlignment="Top" Height="60" Width="353"/>
                    <Button x:Name="MISMakeItSoButton" Content="Make it so!" HorizontalAlignment="Left" Margin="400,20,0,0" VerticalAlignment="Top" Width="120" Height="29" FontSize="16"/>
                    <TextBox x:Name="MISMountTextBox" HorizontalAlignment="Left" Height="25" Margin="19,191,0,0" TextWrapping="Wrap" Text="$PSScriptRoot\Mount" VerticalAlignment="Top" Width="500" IsEnabled="False"/>
                    <Label Content="Mount Path" HorizontalAlignment="Left" Margin="19,166,0,0" VerticalAlignment="Top" Height="25" Width="100"/>
                    <Button x:Name="MISMountSelectButton" Content="Select" HorizontalAlignment="Left" Margin="444,221,0,0" VerticalAlignment="Top" Width="75" Height="25"/>
                    <Label Content="Update injection?" HorizontalAlignment="Left" Margin="551,311,0,0" VerticalAlignment="Top" Width="109"/>
                    <TextBox x:Name="MISUpdatesTextBox" HorizontalAlignment="Left" Height="23" Margin="658,314,0,0" TextWrapping="Wrap" Text="Updates Y/N" VerticalAlignment="Top" Width="120" RenderTransformOrigin="0.171,0.142" IsEnabled="False"/>
                    <Label Content="App removal?" HorizontalAlignment="Left" Margin="551,280,0,0" VerticalAlignment="Top" Width="109"/>
                    <TextBox x:Name="MISAppxTextBox" HorizontalAlignment="Left" Height="23" Margin="658,283,0,0" TextWrapping="Wrap" Text="Updates Y/N" VerticalAlignment="Top" Width="120" RenderTransformOrigin="0.171,0.142" IsEnabled="False"/>
                    <CheckBox x:Name="MISCBDynamicUpdates" Margin="544,40,15,355" Content="Apply Dynamic Update" IsEnabled="False" />
                    <CheckBox x:Name="MISCBBootWIM" Margin="544,62,15,337" Content="Update Boot.WIM" IsEnabled="False" />
                    <TextBox x:Name="MISTBISOFileName" HorizontalAlignment="Left" Height="23" Margin="21,268,0,0" TextWrapping="Wrap" Text="ISO File Name" VerticalAlignment="Top" Width="498" IsEnabled="False"/>
                    <TextBox x:Name="MISTBFilePath" HorizontalAlignment="Left" Height="23" Margin="21,296,0,0" TextWrapping="Wrap" Text="ISO File Path" VerticalAlignment="Top" Width="498" IsEnabled="False"/>
                    <CheckBox x:Name="MISCBISO" Content="Create ISO" HorizontalAlignment="Left" Margin="21,248,0,0" VerticalAlignment="Top"/>
                    <CheckBox x:Name="MISCBNoWIM" Margin="544,85,15,312" Content="Do Not Create Stand Alone WIM" IsEnabled="False"/>
                    <TextBox x:Name="MISTBUpgradePackage" HorizontalAlignment="Left" Height="23" Margin="23,368,0,0" TextWrapping="Wrap" Text="Upgrade Package Path" VerticalAlignment="Top" Width="494" IsEnabled="False"/>
                    <CheckBox x:Name="MISCBUpgradePackage" Content="Upgrade Package Path" HorizontalAlignment="Left" Margin="22,347,0,0" VerticalAlignment="Top"/>
                    <Button x:Name="MISISOSelectButton" Content="Select" HorizontalAlignment="Left" Margin="444,324,0,0" VerticalAlignment="Top" Width="75" Height="25" IsEnabled="False"/>
                </Grid>
            </TabItem>
        </TabControl>
    </Grid>
    <Window.TaskbarItemInfo>
        <TaskbarItemInfo/>
    </Window.TaskbarItemInfo>
</Window>
 
"@
 
 
$inputXML = $inputXML -replace 'mc:Ignorable="d"', '' -replace "x:N", 'N' -replace '^<Win.*', '<Window'
[void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework')
[void][System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") 
[xml]$XAML = $inputXML
#Read XAML
 
$reader = (New-Object System.Xml.XmlNodeReader $xaml)
try {
    $Form = [Windows.Markup.XamlReader]::Load( $reader )
}
catch {
    Write-Warning "Unable to parse XML, with error: $($Error[0])`n Ensure that there are NO SelectionChanged or TextChanged properties in your textboxes (PowerShell cannot process them)"
    throw
}
 
#===========================================================================
# Load XAML Objects In PowerShell
#===========================================================================
  
$xaml.SelectNodes("//*[@Name]") | % { "trying item $($_.Name)" | out-null;
    try { Set-Variable -Name "WPF$($_.Name)" -Value $Form.FindName($_.Name) -ErrorAction Stop }
    catch { throw }
}

#Section to do the icon magic
###################################################
$base64 = "iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAHYcAAB2HAY/l8WUAABtaSURBVHhe7VoHWFTXtk5iij5L7I0mIFJUpHcYht4Zeu8wOErvgtJ7FekoghRFEEGqYsEeCyIgiNJsMZY0701iclVYb+3DYNCbe6MGc/Ped9f37W8GPbPP+df6V9lrnQ/+K/+V6ZHB7OzPRgID9W+xPKPvBAXtvhsWdnmUyRwZsbYeuaGlOdInJTV8TVL8dK+wUFG/rPTWUVdXowfl5bMB4EP2Fv/3pDQqan76xo3imQ4OYbG6ug2JJiYX02xsuuL19c+mMBjfxuvqQpi0NASKikK4nCzEKShAsSoNThkawGVJceiXEPvluphox5CurtdDFosPampmsLf+60tzVdWCoqgorTwmk35GR8e1V0YmuUdEuL2Hj3fo6splX3dzrXzay88L1wT4oVtQAC4KC8FRIUEo5eOFqMWLwX/lSoiVlIB6NTpco9PGb64V/mZIUqxk1NRI5S+vCIiK+mjI2YqrV1w8q4ef7+aVxYuedy2YD10L58PVhQuge9FC6F68EHoWL4KeJYugd+liuLZsCbX6li+FvhXLoBM/m/CalM/ngR8nFxQqK0O/vi4MrhX+cUReru6Wg4PwX849ohB4p63t+l5F+eKu5ct++k3QCHgqaAowe/Uj8Osrl1NrgGMF3OBcSa2r+H0P7hGydAmUaqjDNTVVGF4v8rdROi3hQWDgUvbt/7PS6u29pE1SMukC58rvJkDjWoTAEXT3JGgCVEQIulSUoF1eDg5IS0E1rv2y0nBIQR5O0VWhX1cbhhXkYHA1Hwxyc04sHi4YXMUF3fi9DPeLRDdpJdfJy4yPSohevOdoS/9PsuHDKjU1mQY+3qsXFy8cfwl6kt5o5avo520K8i8y5WV/8F23bmizpGQXU1KyyUVEZJ/7etEWFyGhHvOlS2/bcXC8sFu+HDy5uCBRQhyaDfShX1sThkXXwhD/Klw81OclHk5Iwb1z5GVhQEcTRsVFv71nqO9HMg37mf4cIZQvV1U1q1m8+NtONvBJehPg3UKCz47pal9L1NfNjLO318nCrLBzZ/nq2IRs820xaZHxSdm7ElJyjiSm5J5N317UXbK7arwgKw+2OLiCh4w8mC9aDFZzZkMysqVdRwuGaEowIiwAI2v4YAhXDbpMnMBquGSoD3ckNjz/UoNeuMs7QDw0NPlz9iO+PyGUK1dSsihdtOBvnQic8mn0UcqvOVaM3ZCRrjvn7q5dkZ09r7W19bOU9Hyj8MiU2tCIxEfBW+LH8RO2bEuGiKhU2BqdBpGxGRAdnwWxidshLikbUDEQF5kIwQ5u4CYuBZbz5kEYZok2PR0YVVWG2yICcBuVcQpdI5aTAzoM9OCujCRUiUv9Q1darcHAwGYx+1Hfj5QqKSlmz5374Dxafmowu87D9cOwqkrIrdLSmR0dHR+npxcpIcgTIeHxvxDQYVuTABXxEnRUfCbEJEyATkrLg4ztxbAjdzfsyCuFvMI9ULizEgqKyiEjIQP8NHXAcdEiiBQRgU5TY7grLQF31wpClwAfJC5fBseQCfdkJKBSeN2Yroxmi79/1EL2406v1Li4LMlcsqT/0OdzX4neA6u4fxwxNnBHdnyUmJG7OjImrRQB//w66GgEHcsGnZiaA8kIPCQsfpy5MeRHMwv3J4rKRk/EJTWfiEuo/6igaDBmYuoCmzZvgcjodMhO3g4hWrrghrXCXk0NuK2lDvc3rIU+ZEPisqVwApnwQF4aKteKjhsrG9S6uflPrxII9XP4+VOyZ82Eq1NS1gA354sROi2sr6bm04jIJIugLfG3XrF0HLF01kt6J6XlQlpmwc/RMek9rM2hOdr6NtpmZq7iDIaDsIMDS5hh5SZsbOEkpq1tqWFu7hpLo5uelJXT/ZuyijHYWHtChMsm2LiKD5JF18OQsQE8kNwA10TWQDK6w0VkwgN0h6L1Es8ttS3TMFbNZD/+H5dKPT2xxNmzv29Af3+Zq7k4xkcV5WoHUlLm+gdGBvsGRv60LSZ9CujtEJ+8A5JScyE5PR9SMgp+yc7dVdHc3C6MD/c/uO3vpjC87tP4+AwOI4ZDgKqqSZesnP5zI3XGz05Llv0SxsMDPSZG8Ajpf0lwNSSt4oFBhiHcRxdJFZf7hzXD1YOwkr3VuwuJ+hlcXLmJn3wC3ZjabnJxTORpYcG7w842Al7+WwNZ3lueEYpTlkbQiRToPEjNLACM9JC5Y+fT/OI9iTU1NbPInjV9fZ9irJhP3eANJSMjY5atw2YDV1dv8Vg63ch9zpz7wVg695gy4Gs5KTjCtwpyxcTgoa4WxgQpCJBWfejjE6H0h2uFOhOTFUkLFtzOx6qOKk5w3eTlHrulqxUYHBZr5OTm+/eouIwJvyagMyZBF8P23BLIzts9ll9UsbuoqIhY/YO07fnrinfvjWluPspH3eAdhICKkpHRcp89+04oBwcMoBIeoxJ2rlgOLZrq8B1dGbpkZWCjruXF7OxiTvbP3k3yxcWtIz/6EKq50Oq83DCEa0RS7MuKqBQJR2fvoaCwOEJvBF1ILA1ZObsIaMgpKIM8jOSFJZUXm5ublxd1dn6yNSrVOT276GHF3oPJJFuwb/FOQpQQJyen4zl37uNYfn64jTFhGGNCCsdKuGmoB0+U5KBaTnnM28UntRPvzf7Z20sqN3fetg8/hA4x0YnKbPWq8RENtVQmKygbrU/R/HXQBTsroHBXFRSX7v22Yt9BrWys1gJCY8LQTX7Gvx/X1TVKsLf/Q0Lcc6uoqKPnZ589LZCSgMd62tCKJXOZjDR8r60Oj5QVIFLD4El2dhGN/ZO3k46oqI/T+fhGI2fMgG6s3YcFeGF4rdBPLbEJDBv7Td8HBMewQe/5FfTufbCrrBpK9uwfL99XV9zaOviZj3+km29Q1NM9ew9AzcGW00eOdM9m3+IPS42FxacRgoJZmz/77EW7rg58haAzsD64zjCCp6pKcEZJGQKZAS19fX1z2D95czmTlLQg8pNPfomdORP6xNbDqCA/3JKRuMxi+qVb2W2EtKyiV0DvLq+BssoDsGdvHVRW139TXdcqF7YtUd7F3f+73MIyOHCoDQ41t2ewt582KcEaJWDxko7QhYtgxIwBR9eshjIpSfjJQAeeqqlAopr+D6GhcUrsy99cdmtoCGxD68dhbd6/ThhuYeEx7Mm84uLud5/Qn4AnoEsra2FPVR0gvaFqfwPsrT0E+w82t+Tnly91YwacCAyJgfqmI9DUemys6fBxV/b20yppioqq3rNmfbcbgd/VVMOD02IYNdKHZxqqcFGVPu5sZJ+FgfjtYkGugoJYOPp/7Nw5MCAqAndxdRYUgjVaf7NvBGXpcgRdub+eAl1d1wQ19S1QW9/yvL6x3d3LZ4ubrePmZzn5u6HtyAk40t4xdvz4SVv29tMqnQgugocnJ3g2GgvpX43Z6rA6HZ7ra8MPqJBwNf2BgIAILvblbyYVZmZaoaiAaFTADQlRuCcrCRWxSWBi4UrlfAr0AQR9sBlqG1qhrvEwNDS3w6GWo08OHmyTd3b3O+/i4Q/NrUfhRMcZ6Dh5duz0uQvm7O2nXfIYDOEArA8K1opAO7pBBlaId5UU4BspcaiSVRpjufoFVVU1L2Bf/vtSbmnJIArY9j+zYFBJHu6pKEKEpy+YmLtANuZ4AvogBfoINLYeg+a242jpDjhy9OSNLVuTTa1sPV8EhsQi8HNw5uwFOHf+0otLl66YsrefdsGAOCOSmzsrbN688SMS4pD0+Tw4uX4dXJo7F+qXLANPG+aLjd5hB/39/amC7Hel0sxMNwRT7paPP4ZBXW0YVVMFL1cvSgEk6qOloQlBt1L0PglHj52C4yfOwMmTZ/cxWcE5FtYekIY1wvkLnXDh4hW4eKlr7MqVa2bs7d+L7FBTkwmZNevrCmRB1pw5UL9BFDoXzIdzCxaAP90QPL1CH3gHRfCzL//3UkijSREFhHz0EXSiAvpVaeBo6wEMc2fYvacaLd0BR49PgEZ6w6nT5ylLHzt++oCDi/eAhQ0TyjBIdl7pga6r1+Bqd99Yb/8NS/b270XKNTVnRyxc2JrCxQVFPNxQxM0FV5YuBtKrjBSRgE1eYWM+gVsD36hE3kGjCQUh+EBUQjOWll2KimBm6kgpoBID4FTQSG84/8VlytKXO7vB0cUbLFEBBxvaoKf3Olzru4H/3jNWW9fsz97+vUm6pCQrbObM5zuRBTl4aOrG4og0aAuFRMHbOxwDeFjtG50W28LDVwR+/PHzAFRA6bq1cEVBHkyMbMEIlbC3+iCcPXfxJehLl6++tDSJ+BY2HmBpy4TWwx1w9vxl6pygY2QPdB3L83goeq89/jw1NdHwWbO+LUXGZq9ZA13CgtCDabFxgziwNgaDb9C2/rS0/N/vLEeJiHy6benSvxMFpHByQh9WWuaG1mDIsIe9mP4mQV+ZoPdLS++pqEWWuICZlRv4BGwDKUU9WC+lDqLSGiCvanTPOyjuzXzwHeXsrl1zoxctupIrLfVjOj//2GURIaqDdVFWFnxYweAfHP1TXFKmGvvyfy2k1o7j4yOchRCsBrsszMFO3wL0kAUVVQdeAd1/fRCu3xiGAVy5BaXIEidKCQYmTiAmqwXictogqaALsioGP9o4sN6tNn8LyZGXT82Tl9+UxLHy0SVhIaqDNUBTgcDNIaiAmLGI6GQn9qX/XqJ5eOJ8UQG+mA6bMQu465qBjoE11bPr678J1weG4MbNERgcuoX07wNyNNbStwEDZImxmRNY2HqClJIeyKgYgBzNEBToxmNWDhsT2du/N6nBVLeLThdM4+S43ym0huPIDeNROcwvAkLCE0jHagvC+v1AmEWjMXwwEHrj1QXiYuBrYgtaelYQvjWJAj08cgetPoKHn2rQ0LcGcXltpLkhxRISKxzcfAhoUFRngJKGCahomYG2kd05Zmjoe29j58nKCufwrnrcgwq4wcUBN4TWnPNw9e0kbbv4lJxiwnD2pf9adtna8gQvmP/ICxUQjrl0i6kNaOpaghvTHy0/ijm+C1g+4YTabEvrU4B1DW1A39gO3DwDQVXHApc50PF36qgkHYb9E7+gbYrsW7w3SeXlFS1cueLbAfbE6aaMZCuT6d9F+pUxidv3v5ECOmi0j4MXLGgkCvDCg1GMgQlo6ViCmYUbFO2qBH0TBwo0obc8sbQaA5Q1TUEb3YS4iiszALRREZqGyBwjOwTvAHqmjuMOrt6ZGRkZCwODY1MSE/Ok2bebVtmjp+1QycXxy81V3NSY7bqy/A5v77C++ORsZMCO9jduyiTLyHiyZswY24hKYHJwgxbSmCjBY1MwKKi9Sm9ibTW0tJa+FWijq1jZeYIppkQEDYYYE4wtXMDEyhUwDnzPZIX2Orr6jm+NTL2I54q17NtNi5Bp9Q4RobR23lUwyMcDw4L8z646OnqFhifcptp2WYXHsRh6MwXkaWlxec2c9dB//vyvmDTN/eqa5uNqGmZg5+SFlLYCmvav9NZE6qOPIwMmXMXYzJk6OTIsXcHU2g2DogelFGuHjWDv7AX2Tt4US9IyCy8mJWW+c5/wdSml0WYWcHGeuIrgSSdrZJ3wtTyWr1V0XPovGdlFkJlTXIMKeLOuMfGVVCWliDwzM1F7Z28FVMBPquqmYGnNBGvHTRS9CWiK3iYTljZA19DQtgAtVMJm3/CXoG0dWQh8Mzi6eoMTBkg8LoO1PQuCw+LGI2PT2ouKKlawb/uHpEJHR66Ri+PJ4GpeYv2x25pqSV5eIV6JqTljpH1XUFy+841iwOsSFZU9T9/A7jaNbgJq6ubA3Bz6Kr3ZljbFIkiDuAMyxY0ZiFb2p0A7u/uCi4cfBscA8GAFoRJ8sWL0BDtURGxC1nj4tuSjuaWly9m3eychlq0WFszt5eOmhqq3pMX77/ix+LZFp1XlFk6073aX18S+0XngdSFawwC4XUWVASo0BniyQijLmiFoc1L+2iEr8G8btLQ+lr6EKabmbhAYGvMSNBNjx0avUGB5h1HLxmETmFq6Ud9j4lEJkcltSZn57+wOHWZmUp1CAo+pFp7khh/vONgab41NFk7JyL9TvHsv7CzdN4aHNCYZ4LJ/8nbCYoVpIfhxMrLS0rYGb/+tv0FvXyDHYVU2U0hfYBIwcQnyG1Im+wVFAZ7RqSYLOWRFYI6Oic8ci4rL7MzKLZF9Wyvd9ffkGFGQOTYqLADXpcXHO5wcijpKS2fmFJT5Ivh/lGKZXlp14LucvFLvqKikd1NyYGDgbF09ux5FJSNQUjYGb9+taF1/it6uzAl6u7MCqU9NbStQVmGAo5MPVYH5BkZSoANCYpAVsRC8JZ76d2d3P6weHSglpKTnQ2xiNllfb88rcSsvL//dLjIUFX3y0NZW466y3NUheWlokpUai6UpNwaamCxtOnaMY0/VgS/K8QRbgYc4zDidadsL/CMi4t6uRTYpxCq2tqwQVMC4gqIhGBo5QggCeZ3exNKEBURJGppWEB2bCWSQQkC/OjZPpb6T0yMpoPCsAFnZO6m5Iq6fMWpXl+2tFf2toAUffPBhrIWFZL6JcUaFpvoPCXhq3Sgg8MxOUDA3CsG3tp5esq/20L7KmoYX+2obJ/uWJQlJ230rWlvnsbd5e3F13cRDUzW5I69gAEQJPn6RSOmtU+g9YelNWCXS6KbUNa5uAdQLEQQ0eUliYpj660sShAmGmD00scZwdvXFQ1UZNWbLyC4ez84teVi4qyqxoqJGcEoB82EAjWZgMHfeI7UZM8Z15sz5gbFyZctGZWW1moyaWY2tR6WrDza17atrekGatQcaWuFAY9vfD9S3WBUUVWxCQ777dGoiGHrEycnrj8vK6YGmliVEYYn5Or2Jpa3tWIDXUUEzPnEH9a4AmSAT0PGTo3P2QJUESy1dK6CT7OEegNVmFTV8IdE7v7gCCkuq/l5aXltTua/eoaqsStJdQiLcXkgoPlBHh7knOUu4/vAprkPNh3XqGtp21dQ3PyGgSbOWtOVJC6+59fjh/OJytZKSvebvlAWmiqenP4eKqsktGVldIMudGUS9F/D6WyFBoXFAVzejrrGxZVFvhEyCJv4+ZYpMLW+/ragAc1BGhbl5BEFJ2X5q+LKzlJo4YQrDQFZRO44+/W3l/vq+qppDF/YdaPpi/8HmK2jp+wj6GQW6eQJ0U9sxaDl8gjRqnh7tOG2wv/aQzZEjp2XZMN5diAYtLNw3S8vojEtJayPNDSAKaU2UMJXexNpuHgEgK6dLMSE8IpnQ+p8GqjvySylLkykSUQK6GOU6RGklpfup4cu/nEW8ZulJ0IfbO6D96Ek4dvwUHDtxuqW1tYOzqelISG9v75u3x/+dbNoUNUdd0+KkpJQWkIXZgRqRx2EUn0pvMkcwNHakrqGrmUEmBjkC+BV64+GqqITk6WqSq4HMHkkAJczR1rGh3iFCK0+Axk9Cb9KWr5+YRVAd6pegjxHQp6l5xMlT50jj9uvW9hPqJ0+epZ87dzH0j06nXxEbm83ycvJ634hLaICEpCY4ufjC9pwS6s2QqfSOjE0HRSVDINeRd4B2oVXJeG0S9AS9f50vYuqi6gISO8i+hD0+ftugpq6ZzBgRdPuEpY9MtfSvoE+dmWjYHj12aqygaE8RFj7zLnV2RV7q7hZnP/r0iIWFxQxzS48QCUmt52Li6viwGuAfEE1ZduronPztFxhNsWCDmBq4ewTCnso6yqcnQU+dLxJL78e1I68EDAztqd+sF1XF2GAM26LSUAlHKdDHT0wBPaVLTZq21fsbxn18tzYmJGxfdvVqn11XV29kX1/fp+xHnz7BrPCphoZ5hZi4GohuoAOJCeQNL2LhSXqTMpT8TeIBAUOuJRbdW9OAPj0F9OSo7VAb26fbKUX4+EWADMYRYRElEBRWBClZHXBw9IZsZNs+/P3B+lZoOHQYag80QV5+GdjYsZ5hkN6bmpq7vKfvuk3vtYGb/f2D02v9qeLkFLQcy+OzxEpkoVtAYnIORevJ6E0sTRRhbbsR1q6nUYrwQ7bUkQcneXoKaDJuazlMxm0nyLgNrd0Be8r3I3MCYB3uzy8gB7z8MrAK12pBeRBeqwxCuPgEZMn3ETUNc/esrNL5CJrVf33ocf/AYOK0+v5viaurr6CiosE1Am7tOhWQltGG5NR88r4ARe/J6F1WWUt1lUTwgdeuo1HlNKH0lJRFTZ5I9J46eTp95gtcF6AeFRWH2YUoUg1TrLSczndKKsYDNDojV9/I1qKpqV1gYGCIPnBjpOXGzZFnNwdHzw4PD/85b5k7OW0Sw+LoJgFHrEJ8PiYuC2qRoi/p3dhGKcXabiNSGq/D5eTsAw2NR6hAdnximvwS9OQQ5osLnWTGSE2frnT1Uq353mvXob//Zn/f9cH66wPDDQM3ho/eHBy5Pzg4+oI0bXE9HR6+a/KHC5+3ETwdisvK6l4TQn8VElYCUTE6+PpHQWPLMSplTdK7rqEFmJ5BICikCAKCClhRWkEl5nsC+LdAT06fugnwKTMJMo+YbM8T0KOjd+HW7S/h9u0vxzu7eqsvXLjw7nX/uwqTGcSPqesEBqzxNYKKCFIJae8B1TWN1CR5kt7kcxumuw2YQfhWy2L8oENIWAL+39lXQff0vzqImTKToEDfukeBvnP3K7h37wH+213YX3OoOywscTX7kf58IS8vY0lbJLxW5ZnAGnlYjYucHeITsjF1Tbw3QCxN0tZuLH60dayBlw8DG580VQpnZhUjC678M+jB0d8A/RC+vP8I7n/1GH/TBdEx6Vft7b02sB/lPyeYImfq6dm7YXp8wL9aDsgSWKMAxgxnKMPscOHir/Q+eeo8hODZQWS9CnDySAA3rxRgcIOw8ERkzRlqCDMySe879ylLT4K+9+UjVGYnXps0Zmzq3Gzrwpq2JusfFhKAQkOjuBWUDKsEhZWeTlqZpDJDYyfYVbIPfb2LsjQZuR3vOAubvcNh3QZV4OASgxWcosCFChHHIsvZ1R9iYrOA9Ax25OzGLJMHXj4RgHuP4fU3NLWtfYjS2bf+awkZjRsa2mvKyus18q+R+4VYmHuVJPDgpwrdFIKC47CgacPo3g9Dw7fRopchFUtqQ4YTVfws5xCFJcvXvlwrOTeMcfNKPl6/QfWoEo3BSkjIXsK+1V9bSktLZ1paeirKKxpUrBFS+I6TWxw4yEJrk0BIqjzSTI3F9FlaVgM1tc3oLrWQll4AXt4RpFcwYuvgZaGmZiLh4xPKjYqd/vL2T5IPAwPTZhsbO7lJymhWrhej30KL/oiKeEFov2zl+lcWYQAy54a7u58y+/f/v4Q0QC0s3CWRzgYyMnoOBgzHWCOG4y48Shdr61pvkZLVtEYX4mVf/l+Zfvngg/8FzXHZ9OzWWpAAAAAASUVORK5CYII="
# Create a streaming image by streaming the base64 string to a bitmap streamsource
$bitmap = New-Object System.Windows.Media.Imaging.BitmapImage
$bitmap.BeginInit()
$bitmap.StreamSource = [System.IO.MemoryStream][System.Convert]::FromBase64String($base64)
$bitmap.EndInit()
$bitmap.Freeze()

# This is the icon in the upper left hand corner of the app
$form.Icon = $bitmap
# This is the toolbar icon and description
$form.TaskbarItemInfo.Overlay = $bitmap
$form.TaskbarItemInfo.Description = "WIM Witch - $wwscirptver"
###################################################

Function Get-FormVariables {
    if ($global:ReadmeDisplay -ne $true) { Write-host "If you need to reference this display again, run Get-FormVariables" -ForegroundColor Yellow; $global:ReadmeDisplay = $true }
    #write-host "Found the following interactable elements from our form" -ForegroundColor Cyan
    get-variable WPF*
}
 
#Get-FormVariables

#===========================================================================
# Functions for Controls
#===========================================================================

#Funtion to select mounting directory
Function SelectMountDir {

    Add-Type -AssemblyName System.Windows.Forms
    $browser = New-Object System.Windows.Forms.FolderBrowserDialog
    $browser.Description = "Select the mount folder"
    $null = $browser.ShowDialog()
    $MountDir = $browser.SelectedPath
    $WPFMISMountTextBox.text = $MountDir 
    check-mountpath -path $WPFMISMountTextBox.text
    update-log -Data "Mount directory selected" -Class Information
}

#Function to select Source WIM
Function SelectSourceWIM {

    $SourceWIM = New-Object System.Windows.Forms.OpenFileDialog -Property @{ 
        #InitialDirectory = [Environment]::GetFolderPath('Desktop')
        InitialDirectory = "$PSScriptRoot\imports\wim"
        Filter           = 'WIM (*.wim)|'
    }
    $null = $SourceWIM.ShowDialog()
    $WPFSourceWIMSelectWIMTextBox.text = $SourceWIM.FileName


    if ($SourceWIM.FileName -notlike "*.wim") {
        update-log -Data "A WIM file not selected. Please select a valid file to continue." -Class Warning
        return
    }
    
    
    #Select the index
    $ImageFull = @(get-windowsimage -ImagePath $WPFSourceWIMSelectWIMTextBox.text)
    $a = $ImageFull | Out-GridView -Title "Choose an Image Index" -Passthru
    $IndexNumber = $a.ImageIndex
    #write-host $IndexNumber
    if ($indexnumber -eq $null) {
        update-log -Data "Index not selected. Reselect the WIM file to select an index" -Class Warning
        return
    }

    import-wiminfo -IndexNumber $IndexNumber
}

function import-wiminfo($IndexNumber) {
    Update-Log -Data "Importing Source WIM Info" -Class Information
    try {
        #Gets WIM metadata to populate fields on the Source tab.
        $ImageInfo = get-windowsimage -ImagePath $WPFSourceWIMSelectWIMTextBox.text -index $IndexNumber -ErrorAction Stop
    }
    catch {
        Update-Log -data $_.Exception.Message -class Error
        Update-Log -data "The WIM file selected may be borked. Try a different one" -Class Warning
        Return
    }
    $text = "WIM file selected: " + $SourceWIM.FileName
   # $text = "WIM file selected: " + $ImageInfo.FileName
    Update-Log -data $text -Class Information
    $text = "Edition selected: " + $ImageInfo.ImageName

    Update-Log -data $text -Class Information
    $ImageIndex = $IndexNumber

    $WPFSourceWIMImgDesTextBox.text = $ImageInfo.ImageName
    $WPFSourceWimVerTextBox.Text = $ImageInfo.Version
    $WPFSourceWimSPBuildTextBox.text = $ImageInfo.SPBuild
    $WPFSourceWimLangTextBox.text = $ImageInfo.Languages
    $WPFSourceWimIndexTextBox.text = $ImageIndex
    if ($ImageInfo.Architecture -eq 9) {
        $WPFSourceWimArchTextBox.text = 'x64'
    }
    Else {
        $WPFSourceWimArchTextBox.text = 'x86'
    }
   if ($WPFSourceWIMImgDesTextBox.text -like "Windows Server*"){ 
        $WPFJSONEnableCheckBox.IsChecked = $False
        $WPFAppxCheckBox.IsChecked = $False
        $WPFAppTab.IsEnabled = $False
        $WPFAutopilotTab.IsEnabled = $False
        $WPFMISAppxTextBox.text = "False"
        $WPFMISJSONTextBox.text = "False"
        $WPFMISOneDriveCheckBox.IsChecked = $False
        $WPFMISOneDriveCheckBox.IsEnabled = $False
        }
      Else{
        $WPFAppTab.IsEnabled = $True
        $WPFAutopilotTab.IsEnabled = $True
        $WPFMISOneDriveCheckBox.IsEnabled = $True
        }
}
 
#Function to Select JSON File
Function SelectJSONFile {

    $JSON = New-Object System.Windows.Forms.OpenFileDialog -Property @{ 
        InitialDirectory = [Environment]::GetFolderPath('Desktop') 
        Filter           = 'JSON (*.JSON)|'
    }
    $null = $JSON.ShowDialog()
    $WPFJSONTextBox.Text = $JSON.FileName

    $text = "JSON file selected: " + $JSON.FileName
    update-log -Data $text -Class Information
    Parse-JSON -file $JSON.FileName
}

#Function to parse the JSON file for user valuable info
Function Parse-JSON($file) {
    try {
        Update-Log -Data "Attempting to parse JSON file..." -Class Information
        $autopilotinfo = Get-Content $WPFJSONTextBox.Text | ConvertFrom-Json
        Update-Log -Data "Successfully parsed JSON file" -Class Information
        $WPFZtdCorrelationId.Text = $autopilotinfo.ZtdCorrelationId
        $WPFCloudAssignedTenantDomain.Text = $autopilotinfo.CloudAssignedTenantDomain
        $WPFComment_File.text = $autopilotinfo.Comment_File

    }
    catch {
        $WPFZtdCorrelationId.Text = "Bad file. Try Again."
        $WPFCloudAssignedTenantDomain.Text = "Bad file. Try Again."
        $WPFComment_File.text = "Bad file. Try Again."
        Update-Log -Data "Failed to parse JSON file. Try another"
        return

    }
}

#Function to select the paths for the driver fields
Function SelectDriverSource($DriverTextBoxNumber) {
    Add-Type -AssemblyName System.Windows.Forms
    $browser = New-Object System.Windows.Forms.FolderBrowserDialog
    $browser.Description = "Select the Driver Source folder"
    $null = $browser.ShowDialog()
    $DriverDir = $browser.SelectedPath
    $DriverTextBoxNumber.Text = $DriverDir
    update-log -Data "Driver path selected: $DriverDir" -Class Information
}

#Function for the Make it So button
Function MakeItSo ($appx) {

    #Check if new file name is valid, also append file extension if neccessary

    ###Starting MIS Preflight###
    check-mountpath -path $WPFMISMountTextBox.Text -clean True

    if (($WPFMISWimNameTextBox.Text -eq "") -or ($WPFMISWimNameTextBox.Text -eq "Enter Target WIM Name")) {
        update-log -Data "Enter a valid file name and then try again" -Class Error
        return 
    }

   
     if (($auto -eq $false) -and ($WPFCMCBImageType.SelectedItem -ne  "Update Existing Image" )) {

        $checkresult = (check-name) 
        if ($checkresult -eq "stop") { return }
    }


    #check for working directory, make if does not exist, delete files if they exist
    $FolderExist = Test-Path $PSScriptRoot\Staging -PathType Any
    update-log -Data "Checking to see if the staging path exists..." -Class Information

    try {
        if ($FolderExist = $False) {
            New-Item -ItemType Directory -Force -Path $PSScriptRoot\Staging -ErrorAction Stop
            update-log -Data "Path did not exist, but it does now :)" -Class Information -ErrorAction Stop
        }
        Else {
            Remove-Item –path $PSScriptRoot\Staging\* -Recurse -ErrorAction Stop
            update-log -Data "The path existed, and it has been purged." -Class Information -ErrorAction Stop
        }
    }
    catch {
        Update-Log -data $_.Exception.Message -class Error
        Update-Log -data "Something is wrong with folder $PSScriptRoot\Staging. Try deleting manually if it exists" -Class Error
        return
    }

    if ($WPFJSONEnableCheckBox.IsChecked -eq $true) {
        Update-Log -Data "Validating existance of JSON file..." -Class Information
        $APJSONExists = (Test-Path $WPFJSONTextBox.Text)
        if ($APJSONExists -eq $true) { Update-Log -Data "JSON exists. Continuing..." -Class Information }
        else {
            Update-Log -Data "The Autopilot file could not be verified. Check it and try again." -Class Error
            return
        }

    }

    if ($WPFMISDotNetCheckBox.IsChecked -eq $true) {
        if ((check-dotnetexists) -eq $False) { return }
    }


    #Check for free space
    if ($SkipFreeSpaceCheck -eq $false){
        if (check-freespace -eq 1){
        Update-Log -Data "Insufficient free space. Delete some files and try again" -Class Error
        return}
            else{
        update-log -Data "There is sufficient free space." -Class Information}
    }
    #####End of MIS Preflight###################################################################

    #Copy source WIM
    update-log -Data "Copying source WIM to the staging folder" -Class Information

    try {
        Copy-Item $WPFSourceWIMSelectWIMTextBox.Text -Destination "$PSScriptRoot\Staging" -ErrorAction Stop
    }
    catch {
        Update-Log -data $_.Exception.Message -class Error
        Update-Log -Data "The file couldn't be copied. No idea what happened" -class Error
        return
    }

    update-log -Data "Source WIM has been copied to the source folder" -Class Information

    #Rename copied source WiM

    try {
        $wimname = Get-Item -Path $PSScriptRoot\Staging\*.wim -ErrorAction Stop
        Rename-Item -Path $wimname -NewName $WPFMISWimNameTextBox.Text -ErrorAction Stop
        update-log -Data "Copied source WIM has been renamed" -Class Information
    }
    catch {
        Update-Log -data $_.Exception.Message -class Error
        Update-Log -data "The copied source file couldn't be renamed. This shouldn't have happened." -Class Error
        Update-Log -data "Go delete the WIM from $PSScriptRoot\Staging\, then try again" -Class Error
        return
    }

    #Remove the unwanted indexes
    remove-indexes

    #Mount the WIM File

    $wimname = Get-Item -Path $PSScriptRoot\Staging\*.wim
    update-log -Data "Mounting source WIM $wimname" -Class Information
    update-log -Data "to mount point:" -Class Information
    update-log -data $WPFMISMountTextBox.Text -Class Information

    try {
         Mount-WindowsImage -Path $WPFMISMountTextBox.Text -ImagePath $wimname -Index 1 -ErrorAction Stop | Out-Null
         }
    catch {
        Update-Log -data $_.Exception.Message -class Error
        Update-Log -data "The WIM couldn't be mounted. Make sure the mount directory is empty" -Class Error
        Update-Log -Data "and that it isn't an active mount point" -Class Error
        return
    }

    #checks to see if the iso binaries exist. Cancel and discard WIM if they are not present.
        If (($WPFMISCBISO.IsChecked -eq $true) -or ($WPFMISCBUpgradePackage.IsChecked -eq $true)){

            if ((check-isobinariesexist) -eq $False) {
                update-log -Data "Discarding WIM and not making it so" -Class Error
                Dismount-WindowsImage -Path $WPFMISMountTextBox.Text -discard -ErrorAction Stop | Out-Null
            return}
        }

    #Get Mounted WIM version and save it to a variable for useage later in the function
    $MISWinVer = (get-winvernum)
    

    #Pause after mounting
    If ($WPFMISCBPauseMount.IsChecked -eq $True){
        update-log -Data "Pausing image building. Waiting on user to continue..." -Class Warning
        $Pause = pause-makeitso  
            if ($Pause -eq "Yes"){update-log -data "Continuing on with making it so..." -Class Information }
            if ($Pause -eq "No"){update-log -data "Discarding build..." -Class Error
                update-log -Data "Discarding mounted WIM" -Class Warning
                Dismount-WindowsImage -Path $WPFMISMountTextBox.Text -discard -ErrorAction Stop | Out-Null
                update-log -Data "WIM has been discarded. Better luck next time." -Class Warning
                return
                }
    }

    #Run Script after mounting
    if (($WPFCustomCBRunScript.IsChecked -eq $True) -and ($WPFCustomCBScriptTiming.SelectedItem -eq "After image mount")){
        update-log -data "Running PowerShell script..." -Class Information
        run-script -file $WPFCustomTBFile.text -parameter $WPFCustomTBParameters.text
        Update-Log -data "Script completed." -Class Information
        }
       

    #Language Packs and FOD
    if ($WPFCustomCBLangPacks.IsChecked -eq $true){
        apply-LanguagePacks }
        else{
        update-log -Data "Language Packs Injection not selected. Skipping..."}

    if ($WPFCustomCBLEP.IsChecked -eq $true){
        apply-localexperiencepack}
        else{
        update-log -Data "Local Experience Packs not selected. Skipping..."}

    if ($WPFCustomCBFOD.IsChecked -eq $true){
        apply-FODs}
        else{
        update-log -Data "Features On Demand not selected. Skipping..."}


    #Inject .Net Binaries
    if ($WPFMISDotNetCheckBox.IsChecked -eq $true) { inject-dotnet }
    
    #Inject Autopilot JSON file
    if ($WPFJSONEnableCheckBox.IsChecked -eq $true) {

        update-log -Data "Injecting JSON file" -Class Information

        try {
            $autopilotdir = $WPFMISMountTextBox.Text + "\windows\Provisioning\Autopilot"
            Copy-Item $WPFJSONTextBox.Text -Destination $autopilotdir -ErrorAction Stop
        }
        catch {
            Update-Log -data $_.Exception.Message -class Error
            Update-Log -data "JSON file couldn't be copied. Check to see if the correct SKU" -Class Error
            Update-Log -Data "of Windows has been selected" -Class Error
            Update-log -Data "The WIM is still mounted. You'll need to clean that up manually until" -Class Error
            Update-Log -data "I get around to handling that error more betterer" -Class Error
            Update-Log -data "- <3 Donna" -Class Error
            return  
        }

    }
    else {
        update-log -Data "JSON not selected. Skipping JSON Injection" -Class Information
    }

    #Inject Drivers

    If ($WPFDriverCheckBox.IsChecked -eq $true) {

        DriverInjection -Folder $WPFDriverDir1TextBox.text
        DriverInjection -Folder $WPFDriverDir2TextBox.text
        DriverInjection -Folder $WPFDriverDir3TextBox.text
        DriverInjection -Folder $WPFDriverDir4TextBox.text
        DriverInjection -Folder $WPFDriverDir5TextBox.text
    }
    Else {
        update-log -Data "Drivers were not selected for injection. Skipping." -Class Information 
    }

    #Inject default application association XML
    if ($WPFCustomCBEnableApp.IsChecked -eq $true){apply-defaultapp}
        else
        {
        Update-Log -Data "Default Application Association not selected. Skipping..." -Class Information
        } 

    #Inject start menu layout
    if ($WPFCustomCBEnableStart.IsChecked -eq $true){apply-startlayout}
        else
        {
        Update-Log -Data "Start Menu Layout injection not selected. Skipping..." -Class Information
        } 

    #apply registry files
    if ($WPFCustomCBEnableRegistry.IsChecked -eq $true){apply-regfiles}
        else
        {
        Update-Log -Data "Registry file injection not selected. Skipping..." -Class Information
        } 

    #Check for updates when ConfigMgr source is selected
    if ($WPFMISCBCheckForUpdates.IsChecked -eq $true){
        invoke-MISUpdates
        if ( $WPFSourceWIMImgDesTextBox.text -like "*Windows 10*"){download-onedrive}
        }



    #Apply Updates
    If ($WPFUpdatesEnableCheckBox.IsChecked -eq $true) {

        Apply-Updates -class "SSU" 
        Apply-Updates -class "LCU"
        Apply-Updates -class "AdobeSU"
        Apply-Updates -class "DotNet"
        Apply-Updates -class "DotNetCU"
        #if ($WPFUpdatesCBEnableDynamic.IsChecked -eq $True){Apply-Updates -class "Dynamic"}
        if ($WPFUpdatesOptionalEnableCheckBox.IsChecked -eq $True){Apply-Updates -class "Optional"}

    }
    Else {
        Update-Log -Data "Updates not enabled" -Class Information
    }

    #Copy the current OneDrive installer
    if ($WPFMISOneDriveCheckBox.IsChecked -eq $true) {
        copy-onedrive
        }
    else{
        update-log -data "OneDrive agent update skipped as it was not selected" -Class Information
    }

    #Remove AppX Packages
    if ($WPFAppxCheckBox.IsChecked -eq $true) { remove-appx -array $appx }
    Else {
        Update-Log -Data "App removal not enabled" -Class Information
    }

    #Run Script before dismount
    if (($WPFCustomCBRunScript.IsChecked -eq $True) -and ($WPFCustomCBScriptTiming.SelectedItem -eq "Before image dismount")){
        run-script -file $WPFCustomTBFile.text -parameter $WPFCustomTBParameters.text
        }

    #Pause before dismounting
    If ($WPFMISCBPauseDismount.IsChecked -eq $True){
        update-log -Data "Pausing image building. Waiting on user to continue..." -Class Warning
        $Pause = pause-makeitso  
            if ($Pause -eq "Yes"){update-log -data "Continuing on with making it so..." -Class Information }
            if ($Pause -eq "No"){update-log -data "Discarding build..." -Class Error
                update-log -Data "Discarding mounted WIM" -Class Warning
                Dismount-WindowsImage -Path $WPFMISMountTextBox.Text -discard -ErrorAction Stop | Out-Null
                update-log -Data "WIM has been discarded. Better luck next time." -Class Warning
                return
                }
    }

    #Copy log to mounted WIM
    try {
        update-log -Data "Attempting to copy log to mounted image" -Class Information 
        $mountlogdir = $WPFMISMountTextBox.Text + "\windows\"
        Copy-Item $PSScriptRoot\logging\WIMWitch.log -Destination $mountlogdir -ErrorAction Stop
        $CopyLogExist = Test-Path $mountlogdir\WIMWitch.log -PathType Leaf
        if ($CopyLogExist -eq $true) { update-log -Data "Log filed copied successfully" -Class Information }
    }
    catch {
        Update-Log -data $_.Exception.Message -class Error
        update-log -data "Coudn't copy the log file to the mounted image." -class Error
    }

    #Dismount, commit, and move WIM

    update-log -Data "Dismounting WIM file, committing changes" -Class Information 
    try {
       Dismount-WindowsImage -Path $WPFMISMountTextBox.Text -save -ErrorAction Stop | Out-Null
    }
    catch {
        Update-Log -data $_.Exception.Message -class Error
        Update-Log -data "The WIM couldn't save. You will have to manually discard the" -Class Error
        Update-Log -data "mounted image manually" -Class Error
        return
    }
    
    update-log -Data "WIM dismounted" -Class Information 
    
    #Display new version number
     
        $WimInfo = (get-windowsimage -ImagePath $wimname -Index 1)
        $text = "New image version number is " + $WimInfo.Version
        update-log -data $text -Class Information 
   # }

     if (($auto -eq $true) -or ($WPFCMCBImageType.SelectedItem -eq "Update Existing Image")){
        Update-Log -Data "Backing up old WIM file..." -Class Information
        $checkresult = (check-name -conflict append)
        if ($checkresult -eq "stop") { return }
    }
    
    #stage media if check boxes are selected
    if (($WPFMISCBUpgradePackage.IsChecked -eq $true) -or ($WPFMISCBISO.IsChecked -eq $true)){
            stage-isomedia
            update-log -Data "Exporting install.wim to media staging folder..." -Class Information
            Export-WindowsImage -SourceImagePath $wimname -SourceIndex 1 -DestinationImagePath ($PSScriptRoot + '\staging\media\sources\install.wim') -DestinationName ('WW - ' + $WPFSourceWIMImgDesTextBox.text) |Out-Null
            } 

    #Export the wim file to various locations
   # if ($WPFMISCBNoWIM.IsChecked -eq $false){
    if ($WPFMISCBNoWIM.IsChecked -ne $true){
        try {
        update-log -Data "Exporting WIM file" -Class Information
        Export-WindowsImage -SourceImagePath $wimname -SourceIndex 1 -DestinationImagePath ($WPFMISWimFolderTextBox.Text + '\' + $WPFMISWimNameTextBox.Text) -DestinationName ('WW - ' + $WPFSourceWIMImgDesTextBox.text) |Out-Null
    }
        catch {
        Update-Log -data $_.Exception.Message -class Error
        Update-Log -data "The WIM couldn't be exported. You can still retrieve it from staging path." -Class Error
        Update-Log -data "The file will be deleted when the tool is rerun." -Class Error
        return
    }
        update-log -Data "WIM successfully exported to target folder" -Class Information 
    }

    #ConfigMgr Itegration
    if ($WPFCMCBImageType.SelectedItem -ne "Disabled"){
      # "New Image","Update Existing Image"
        if ($WPFCMCBImageType.SelectedItem -eq "New Image"){
            update-log -data "Creating a new image in ConfigMgr..." -class Information
            create-CMImagePackage }

        if ($WPFCMCBImageType.SelectedItem -eq "Update Existing Image"){
            update-log -data "Updating the existing image in ConfigMgr..." -class Information
            update-CMImage}

    }

    #Apply Dynamic Update to media
    if ($WPFMISCBDynamicUpdates.IsChecked -eq $true){Apply-Updates -class "Dynamic"}
        else{
        update-log -data "Dynamic Updates skipped or not applicable" -Class Information
        }

    #Apply updates to the boot.wim file
    if ($WPFMISCBBootWIM.IsChecked -eq $true){update-bootwim}
        else{
        update-log -data "Updating Boot.WIM skipped or not applicable" -Class Information
        }
    
    #Copy upgrade package binaries if selected
    if ($WPFMISCBUpgradePackage.IsChecked -eq $true){copy-upgradepackage}
        else{
            Update-Log -Data "Upgrade Package skipped or not applicable" -Class Information
            }

    #Create ISO if selected
    if($WPFMISCBISO.IsChecked -eq $true){create-iso}
        else{
            update-log -Data "ISO Creation skipped or not applicable" -Class Information
            }

    #Run Script when build complete
    if (($WPFCustomCBRunScript.IsChecked -eq $True) -and ($WPFCustomCBScriptTiming.SelectedItem -eq "On build completion")){
        run-script -file $WPFCustomTBFile.text -parameter $WPFCustomTBParameters.text
        }


    #Clear out staging folder
    try{
        update-log -Data "Clearing staging folder..." -Class Information
        remove-item $PSScriptRoot\staging\* -Force -Recurse -ErrorAction Stop
    }
    catch
    {
        Update-Log -Data "Could not clear staging folder" -Class Warning
        Update-Log -data $_.Exception.Message -class Error
    }

    #Copy log here
    try {
        update-log -Data "Copying build log to target folder" -Class Information 
        Copy-Item -Path $PSScriptRoot\logging\WIMWitch.log -Destination $WPFMISWimFolderTextBox.Text -ErrorAction Stop
        $logold = $WPFMISWimFolderTextBox.Text + "\WIMWitch.log"
        $lognew = $WPFMISWimFolderTextBox.Text + "\" + $WPFMISWimNameTextBox.Text + ".log"
        #Put log detection code here
        if ((test-path -Path $lognew) -eq $true) {
            Update-Log -Data "A preexisting log file contains the same name. Renaming old log..." -Class Warning
            replace-name -file $lognew -extension ".log"
        }
     

        #Put log detection code here
 
        Rename-Item $logold -NewName $lognew -Force -ErrorAction Stop
        Update-Log -Data "Log copied successfully" -Class Information
    }
    catch {
        Update-Log -data $_.Exception.Message -class Error
        Update-Log -data "The log file couldn't be copied and renamed. You can still snag it from the source." -Class Error
        update-log -Data "Job's done." -Class Information 
        return
    }
    update-log -Data "Job's done." -Class Information 
}

#Function to assign the target directory
Function SelectTargetDir {

    Add-Type -AssemblyName System.Windows.Forms
      
    $browser = New-Object System.Windows.Forms.FolderBrowserDialog
    $browser.Description = "Select the target folder"
    $null = $browser.ShowDialog()
    $TargetDir = $browser.SelectedPath
    
    $WPFMISWimFolderTextBox.text = $TargetDir #I SCREWED UP THIS VARIABLE
    update-log -Data "Target directory selected" -Class Information 
}

#Function to enable logging and folder check
Function Update-Log {
    Param(
        [Parameter(
            Mandatory = $true, 
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true,
            Position = 0
        )]
        [string]$Data,

        [Parameter(
            Mandatory = $false, 
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true,
            Position = 0
        )]
        [string]$Solution = $Solution,

        [Parameter(
            Mandatory = $false, 
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true,
            Position = 1
        )]
        [validateset('Information', 'Warning', 'Error')]
        [string]$Class = "Information"

    )
    
    $global:ScriptLogFilePath = $Log
    $LogString = "$(Get-Date) $Class - $Data"
    $HostString = "$(Get-Date) $Class - $Data"

    
    Add-Content -Path $Log -Value $LogString
    switch ($Class) {
        'Information' {
            Write-Host $HostString -ForegroundColor Gray
        }
        'Warning' {
            Write-Host $HostString -ForegroundColor Yellow
        }
        'Error' {
            Write-Host $HostString -ForegroundColor Red
        }
        Default { }
    }
    #The below line is for a logging tab that was removed. If it gets put back in, reenable the line
    # $WPFLoggingTextBox.text = Get-Content -Path $Log -Delimiter "\n"
}

#Removes old log and creates all folders if does not exist
Function Set-Logging {

    #logging folder
    $FileExist = Test-Path -Path $PSScriptRoot\logging\WIMWitch.Log -PathType Leaf
    if ($FileExist -eq $False) {
        New-Item -ItemType Directory -Force -Path $PSScriptRoot\Logging | Out-Null
        New-Item -Path $PSScriptRoot\logging -Name "WIMWitch.log" -ItemType "file" -Value "***Logging Started***" | Out-Null
       
    }
    Else {
        Remove-Item -Path $PSScriptRoot\logging\WIMWitch.log
        New-Item -Path $PSScriptRoot\logging -Name "WIMWitch.log" -ItemType "file" -Value "***Logging Started***" | Out-Null
       
    }
   

    #updates folder
    $FileExist = Test-Path -Path $PSScriptRoot\updates #-PathType Leaf
    if ($FileExist -eq $False) {
        Update-Log -Data "Updates folder does not exist. Creating..." -Class Warning
        New-Item -ItemType Directory -Force -Path $PSScriptRoot\updates | Out-Null
        Update-Log -Data "Updates folder created" -Class Information
    }
   
    if ($FileExist -eq $True) { Update-Log -Data "Updates folder exists" -Class Information }

    #staging folder
    $FileExist = Test-Path -Path $PSScriptRoot\Staging #-PathType Leaf
    if ($FileExist -eq $False) {
        Update-Log -Data "Staging folder does not exist. Creating..." -Class Warning
        New-Item -ItemType Directory -Force -Path $PSScriptRoot\Staging | Out-Null
        Update-Log -Data "Staging folder created" -Class Information
    }

    if ($FileExist -eq $True) { Update-Log -Data "Staging folder exists" -Class Information }

    #Mount folder
    $FileExist = Test-Path -Path $PSScriptRoot\Mount #-PathType Leaf
    if ($FileExist -eq $False) {
        Update-Log -Data "Mount folder does not exist. Creating..." -Class Warning
        New-Item -ItemType Directory -Force -Path $PSScriptRoot\Mount | Out-Null
        Update-Log -Data "Mount folder created" -Class Information
    }

    if ($FileExist -eq $True) { Update-Log -Data "Mount folder exists" -Class Information }

    #Completed WIMs folder
    $FileExist = Test-Path -Path $PSScriptRoot\CompletedWIMs #-PathType Leaf
    if ($FileExist -eq $False) {
        Update-Log -Data "CompletedWIMs folder does not exist. Creating..." -Class Warning
        New-Item -ItemType Directory -Force -Path $PSScriptRoot\CompletedWIMs | Out-Null
        Update-Log -Data "CompletedWIMs folder created" -Class Information
    }

    if ($FileExist -eq $True) { Update-Log -Data "CompletedWIMs folder exists" -Class Information }

    #Configurations XML folder
    $FileExist = Test-Path -Path $PSScriptRoot\Configs #-PathType Leaf
    if ($FileExist -eq $False) {
        Update-Log -Data "Configs folder does not exist. Creating..." -Class Warning
        New-Item -ItemType Directory -Force -Path $PSScriptRoot\Configs | Out-Null
        Update-Log -Data "Configs folder created" -Class Information
    }

    if ($FileExist -eq $True) { Update-Log -Data "Configs folder exists" -Class Information }

}

#Function for injecting drivers into the mounted WIM
Function DriverInjection($Folder) {

    Function ApplyDriver($drivertoapply) {
        try {
            add-windowsdriver -Path $WPFMISMountTextBox.Text -Driver $drivertoapply -ErrorAction Stop | Out-Null
            Update-Log -Data "Applied $drivertoapply" -Class Information
        }
        catch {
            update-log -Data "Couldn't apply $drivertoapply" -Class Warning
        }

    }
 
    #This filters out invalid paths, such as the default value
    $testpath = Test-Path $folder -PathType Container
    If ($testpath -eq $false) { return }

    If ($testpath -eq $true) {

        update-log -data "Applying drivers from $folder" -class Information

        Get-ChildItem $Folder -Recurse -Filter "*inf" | ForEach-Object { applydriver $_.FullName }
        update-log -Data "Completed driver injection from $folder" -Class Information 
    }
}

#Function to retrieve OSDUpdate Version
Function Get-OSDBInstallation {
    update-log -Data "Getting OSD Installation information" -Class Information
    try {
        Import-Module -name OSDUpdate -ErrorAction Stop
    }
    catch {
        $WPFUpdatesOSDBVersion.Text = "Not Installed"
        Update-Log -Data "OSD Update is not installed" -Class Warning
        Return
    }
    try {
        $OSDBVersion = get-module -name OSDUpdate -ErrorAction Stop
        $WPFUpdatesOSDBVersion.Text = $OSDBVersion.Version
        $text = $osdbversion.version
        Update-Log -data "Installed version of OSD Update is $text" -Class Information
        Return
    }
    catch {
        Update-Log -Data "Whatever you were hoping for, you didn’t get :)" -Class Error
        Return
    }
}

#Function to retrieve OSDSUS Version
Function Get-OSDSUSInstallation {
    update-log -Data "Getting OSDSUS Installation information" -Class Information
    try {
        Import-Module -name OSDSUS -ErrorAction Stop
    }
    catch {
        $WPFUpdatesOSDSUSVersion.Text = "Not Installed"
        Update-Log -Data "OSDSUS is not installed" -Class Warning
        Return
    }
    try {
        $OSDSUSVersion = get-module -name OSDSUS -ErrorAction Stop
        $WPFUpdatesOSDSUSVersion.Text = $OSDSUSVersion.Version
        $text = $osdsusversion.version
        Update-Log -data "Installed version of OSDSUS is $text" -Class Information
        Return
    }
    catch {
        Update-Log -Data "Whatever you were hoping for, you didn’t get :)" -Class Error
        Return
    }
}

#Function to retrieve current OSDUpdate Version
Function Get-OSDBCurrentVer {
    Update-Log -Data "Checking for the most current OSDUpdate version available" -Class Information
    try {
        $OSDBCurrentVer = find-module -name OSDUpdate -ErrorAction Stop
        $WPFUpdatesOSDBCurrentVerTextBox.Text = $OSDBCurrentVer.version
        $text = $OSDBCurrentVer.version
        update-log -data "$text is the most current version" -class Information
        Return
    }
    catch {
        $WPFUpdatesOSDBCurrentVerTextBox.Text = "Network Error"
        Return
    }
}

#Function to retrieve current OSDUSUS Version
Function Get-OSDSUSCurrentVer {
    Update-Log -Data "Checking for the most current OSDSUS version available" -Class Information
    try {
        $OSDSUSCurrentVer = find-module -name OSDSUS -ErrorAction Stop
        $WPFUpdatesOSDSUSCurrentVerTextBox.Text = $OSDSUSCurrentVer.version
        $text = $OSDSUSCurrentVer.version
        update-log -data "$text is the most current version" -class Information
        Return
    }
    catch {
        $WPFUpdatesOSDSUSCurrentVerTextBox.Text = "Network Error"
        Return
    }
}

#Function to update or install OSDUpdate
Function update-OSDB {
    if ($WPFUpdatesOSDBVersion.Text -eq "Not Installed") {
        Update-Log -Data "Attempting to install and import OSD Update" -Class Information
        try {
            Install-Module OSDUpdate -Force -ErrorAction Stop
            #Write-Host "Installed module"
            Update-Log -data "OSD Update module has been installed" -Class Information
            Import-Module -Name OSDUpdate -Force -ErrorAction Stop
            #Write-Host "Imported module"
            Update-Log -Data "OSD Update module has been imported" -Class Information
            Update-Log -Data "****************************************************************************" -Class Warning
            Update-Log -Data "Please close WIM Witch and all PowerShell windows, then rerun to continue..." -Class Warning
            Update-Log -Data "****************************************************************************" -Class Warning
            #$WPFUpdatesOSDBClosePowerShellTextBlock.visibility = "Visible"
            $WPFUpdatesOSDListBox.items.add("Please close all PowerShell windows, including WIM Witch, then relaunch app to continue")
            Return
        }
        catch {
            $WPFUpdatesOSDBVersion.Text = "Inst Fail"
            Update-Log -Data "Couldn't install OSD Update" -Class Error
            Update-Log -data $_.Exception.Message -class Error
            Return
        }
    }

    If ($WPFUpdatesOSDBVersion.Text -gt "1.0.0") {
        Update-Log -data "Attempting to update OSD Update" -class Information
        try {
            Update-ModuleOSDUpdate -ErrorAction Stop
            Update-Log -Data "Updated OSD Update" -Class Information
            Update-Log -Data "****************************************************************************" -Class Warning
            Update-Log -Data "Please close WIM Witch and all PowerShell windows, then rerun to continue..." -Class Warning
            Update-Log -Data "****************************************************************************" -Class Warning
            #$WPFUpdatesOSDBClosePowerShellTextBlock.visibility = "Visible"
            $WPFUpdatesOSDListBox.items.add("Please close all PowerShell windows, including WIM Witch, then relaunch app to continue")

            get-OSDBInstallation
            return
        }
        catch {
            $WPFUpdatesOSDBCurrentVerTextBox.Text = "OSDB Err"
            Return
        }
    }
}

#Function to update or install OSDSUS
Function update-OSDSUS {
    if ($WPFUpdatesOSDSUSVersion.Text -eq "Not Installed") {
        Update-Log -Data "Attempting to install and import OSDSUS" -Class Information
        try {
            Install-Module OSDUpdate -Force -ErrorAction Stop
            Update-Log -data "OSDSUS module has been installed" -Class Information
            Import-Module -Name OSDUpdate -Force -ErrorAction Stop
            Update-Log -Data "OSDSUS module has been imported" -Class Information
            Update-Log -Data "****************************************************************************" -Class Warning
            Update-Log -Data "Please close WIM Witch and all PowerShell windows, then rerun to continue..." -Class Warning
            Update-Log -Data "****************************************************************************" -Class Warning
            #$WPFUpdatesOSDBClosePowerShellTextBlock.visibility = "Visible"
            $WPFUpdatesOSDListBox.items.add("Please close all PowerShell windows, including WIM Witch, then relaunch app to continue")
            Return
        }
        catch {
            $WPFUpdatesOSDSUSVersion.Text = "Inst Fail"
            Update-Log -Data "Couldn't install OSDSUS" -Class Error
            Update-Log -data $_.Exception.Message -class Error
            Return
        }
    }

    If ($WPFUpdatesOSDSUSVersion.Text -gt "1.0.0") {
        Update-Log -data "Attempting to update OSDSUS" -class Information
        try {
            uninstall-module -Name osdsus -AllVersions -force
            install-module -name osdsus -force
            Update-Log -Data "Updated OSDSUS" -Class Information
            Update-Log -Data "****************************************************************************" -Class Warning
            Update-Log -Data "Please close WIM Witch and all PowerShell windows, then rerun to continue..." -Class Warning
            Update-Log -Data "****************************************************************************" -Class Warning
            #$WPFUpdatesOSDBClosePowerShellTextBlock.visibility = "Visible"
            $WPFUpdatesOSDListBox.items.add("Please close all PowerShell windows, including WIM Witch, then relaunch app to continue")
            get-OSDSUSInstallation
            return
        }
        catch {
            $WPFUpdatesOSDSUSCurrentVerTextBox.Text = "OSDSUS Err"
            Return
        }
    }
}

#Function to compare OSDBuilder Versions
Function compare-OSDBuilderVer {
    Update-Log -data "Comparing OSD Update module versions" -Class Information
    if ($WPFUpdatesOSDBVersion.Text -eq "Not Installed") {
        Return
    }
    If ($WPFUpdatesOSDBVersion.Text -eq $WPFUpdatesOSDBCurrentVerTextBox.Text) {
        Update-Log -Data "OSD Update is up to date" -class Information
        Return
    }
    #$WPFUpdatesOSDBOutOfDateTextBlock.Visibility = "Visible"
     $WPFUpdatesOSDListBox.items.add("A software update module is out of date. Please click the Install / Update button to update it.")
    Update-Log -Data "OSD Update appears to be out of date. Run the upgrade function from within WIM Witch to resolve" -class Warning

    Return
}

#Function to compare OSDSUS Versions
Function compare-OSDSUSVer {
    Update-Log -data "Comparing OSDSUS module versions" -Class Information
    if ($WPFUpdatesOSDSUSVersion.Text -eq "Not Installed") {
        Return
    }
    If ($WPFUpdatesOSDSUSVersion.Text -eq $WPFUpdatesOSDSUSCurrentVerTextBox.Text) {
        Update-Log -Data "OSDSUS is up to date" -class Information
        Return
    }
    #$WPFUpdatesOSDBOutOfDateTextBlock.Visibility = "Visible"
    $WPFUpdatesOSDListBox.items.add("A software update module is out of date. Please click the Install / Update button to update it.") | out-null
    Update-Log -Data "OSDSUS appears to be out of date. Run the upgrade function from within WIM Witch to resolve" -class Warning

    Return
}

#Function to check for superceded updates
Function check-superceded($action, $OS, $Build) {
    Update-Log -Data "Checking WIM Witch Update store for superseded updates" -Class Information
    $path = $PSScriptRoot + '\updates\' + $OS + '\' + $Build + '\' #sets base path

    if ((Test-Path -Path $path) -eq $false){
        update-log -Data "No updates found, likely not yet downloaded. Skipping supersedense check..." -Class Warning
        return}

    $Children = Get-ChildItem -Path $path  #query sub directories

    foreach ($Children in $Children) {
        $path1 = $path + $Children  
        $sprout = Get-ChildItem -Path $path1

        
            foreach ($sprout in $sprout) {
                $path3 = $path1 + '\' + $sprout
                $fileinfo = get-childitem -path $path3
                foreach ($file in $fileinfo){
                    $StillCurrent = Get-OSDUpdate | Where-Object { $_.FileName -eq $file }   
                    If ($StillCurrent -eq $null) {
                       update-log -data "$file no longer current" -Class Warning
                       if ($action -eq 'delete') {
                            Update-Log -data "Deleting $path3" -class Warning
                            remove-item -path $path3 -Recurse -Force
                        }
                    if ($action -eq 'audit') {
                       
                       # $WPFUpdatesOSDBSupercededExistTextBlock.Visibility = "Visible"
                        $WPFUpdatesOSDListBox.items.add("Superceded updates discovered. Please select the versions of Windows 10 you are supporting and click Update")

                        Return
                    }
                    }   
                     else {
                    Update-Log -data "$file is stil current" -Class Information
                }    
                 }
            }
            }
        Update-Log -data "Supersedense check complete." -Class Information
    }

#Function to download new patches with OSDSUS
Function download-patches($build,$OS) {
    Update-Log -Data "Downloading SSU updates for $OS $build" -Class Information
    try{
    Get-OSDUpdate -ErrorAction Stop| Where-Object { $_.UpdateOS -eq $OS -and $_.UpdateArch -eq 'x64' -and $_.UpdateBuild -eq $build -and $_.UpdateGroup -eq 'SSU' } | Get-DownOSDUpdate -DownloadPath $PSScriptRoot\updates\$OS\$build\SSU
    }
    catch
    {
    update-log -data "Failed to download SSU update" -Class Error
    update-log -data $_.Exception.Message -class Error
    }
    
    Update-Log -Data "Downloading AdobeSU updates for $OS $build" -Class Information
    try
    {
    Get-OSDUpdate -ErrorAction Stop| Where-Object { $_.UpdateOS -eq $OS -and $_.UpdateArch -eq 'x64' -and $_.UpdateBuild -eq $build -and $_.UpdateGroup -eq 'AdobeSU' } | Get-DownOSDUpdate -DownloadPath $PSScriptRoot\updates\$OS\$build\AdobeSU
    }
    catch
    {
    update-log -data "Failed to download AdobeSU update" -Class Error
    update-log -data $_.Exception.Message -class Error
    }

    Update-Log -Data "Downloading LCU updates for $OS $build" -Class Information
    try
    {
    Get-OSDUpdate -ErrorAction Stop| Where-Object { $_.UpdateOS -eq $OS -and $_.UpdateArch -eq 'x64' -and $_.UpdateBuild -eq $build -and $_.UpdateGroup -eq 'LCU' } | Get-DownOSDUpdate -DownloadPath $PSScriptRoot\updates\$OS\$build\LCU
    }
    catch
    {
    update-log -data "Failed to download LCU update" -Class Error
    update-log -data $_.Exception.Message -class Error
    }
    Update-Log -Data "Downloading .Net updates for $OS $build" -Class Information
    try
    {
    Get-OSDUpdate -ErrorAction Stop| Where-Object { $_.UpdateOS -eq $OS -and $_.UpdateArch -eq 'x64' -and $_.UpdateBuild -eq $build -and $_.UpdateGroup -eq 'DotNet' } | Get-DownOSDUpdate -DownloadPath $PSScriptRoot\updates\$OS\$build\DotNet
    }
    catch
    {
    update-log -data "Failed to download .Net update" -Class Error
    update-log -data $_.Exception.Message -class Error
    }
    
    Update-Log -Data "Downloading .Net CU updates for $OS $build" -Class Information
    try
    {
    Get-OSDUpdate -ErrorAction Stop| Where-Object { $_.UpdateOS -eq $OS -and $_.UpdateArch -eq 'x64' -and $_.UpdateBuild -eq $build -and $_.UpdateGroup -eq 'DotNetCU' } | Get-DownOSDUpdate -DownloadPath $PSScriptRoot\updates\$OS\$build\DotNetCU
    }
    catch
    {
    update-log -data "Failed to download .Net CU update" -Class Error
    update-log -data $_.Exception.Message -class Error
    }
 
    if ($WPFUpdatesCBEnableOptional.IsChecked -eq $True){
        try{
            Update-Log -Data "Downloading optional updates for $OS $build" -Class Information
            Get-OSDUpdate -ErrorAction Stop| Where-Object { $_.UpdateOS -eq $OS -and $_.UpdateArch -eq 'x64' -and $_.UpdateBuild -eq $build -and $_.UpdateGroup -eq 'Optional' } | Get-DownOSDUpdate -DownloadPath $PSScriptRoot\updates\$OS\$build\Optional
        }
        catch
        {
            update-log -data "Failed to download optional update" -Class Error
            update-log -data $_.Exception.Message -class Error
        }
    } 

    if ($WPFUpdatesCBEnableDynamic.IsChecked -eq $True){
        try{
            Update-Log -Data "Downloading dynamic updates for $OS $build" -Class Information
            Get-OSDUpdate -ErrorAction Stop| Where-Object { $_.UpdateOS -eq $OS -and $_.UpdateArch -eq 'x64' -and $_.UpdateBuild -eq $build -and $_.UpdateGroup -eq 'SetupDU' } | Get-DownOSDUpdate -DownloadPath $PSScriptRoot\updates\$OS\$build\Dynamic
        }
        catch
        {
            update-log -data "Failed to download dynamic update" -Class Error
            update-log -data $_.Exception.Message -class Error
        }
    } 


    Update-Log -Data "Downloading completed for $OS $build" -Class Information
    

}
 
#Function to remove superceded updates and initate new patch download
Function update-patchsource {

    Update-Log -Data "attempting to start download function" -Class Information
    if ($WPFUSCBSelectCatalogSource.SelectedItem -eq "OSDSUS"){   
        if ($WPFUpdatesW10Main.IsChecked -eq $true){
            if ($WPFUpdatesW10_21H1.IsChecked -eq $true){
                check-superceded -action delete -build 21H1 -OS "Windows 10"
                download-patches -build 21H1 -OS "Windows 10"}
            if ($WPFUpdatesW10_20H2.IsChecked -eq $true){
                check-superceded -action delete -build 20H2 -OS "Windows 10"
                download-patches -build 20H2 -OS "Windows 10"}
            if ($WPFUpdatesW10_2004.IsChecked -eq $true){
                check-superceded -action delete -build 2004 -OS "Windows 10"
                download-patches -build 2004 -OS "Windows 10"}
            if ($WPFUpdatesW10_1909.IsChecked -eq $true){
                check-superceded -action delete -build 1909 -OS "Windows 10"
                download-patches -build 1909 -OS "Windows 10"}
            if ($WPFUpdatesW10_1903.IsChecked -eq $true){
        check-superceded -action delete -build 1903 -OS "Windows 10"
        download-patches -build 1903 -OS "Windows 10"}
            if ($WPFUpdatesW10_1809.IsChecked -eq $true){
        check-superceded -action delete -build 1809 -OS "Windows 10"
        download-patches -build 1809 -OS "Windows 10"}
            if ($WPFUpdatesW10_1803.IsChecked -eq $true){
        check-superceded -action delete -build 1803 -OS "Windows 10"
        download-patches -build 1803 -OS "Windows 10"}
            if ($WPFUpdatesW10_1709.IsChecked -eq $true){
        check-superceded -action delete -build 1709 -OS "Windows 10"
        download-patches -build 1709 -OS "Windows 10"}
        download-onedrive
        }
        if ($WPFUpdatesS2019.IsChecked -eq $true){
    check-superceded -action delete -build 1809 -OS "Windows Server"
    download-patches -build 1809 -OS "Windows Server"}
        if ($WPFUpdatesS2016.IsChecked -eq $true){
            check-superceded -action delete -build 1607 -OS "Windows Server"
            download-patches -build 1607 -OS "Windows Server"}

        if ($WPFUpdatesS2022.IsChecked -eq $true){
            check-superceded -action delete -build 21H2 -OS "Windows Server"
            download-patches -build 21H2 -OS "Windows Server"}

        if ($WPFUpdatesW11Main1.IsChecked -eq $true){

            check-superceded -action delete -build 21H2 -OS "Windows 11"
            download-patches -build 21H2 -OS "Windows 11"}


    }

     if ($WPFUSCBSelectCatalogSource.SelectedItem -eq "ConfigMgr"){   
        if ($WPFUpdatesW10Main.IsChecked -eq $true){
            if ($WPFUpdatesW10_21H1.IsChecked -eq $true){
                invoke-MEMCMUpdateSupersedence -prod "Windows 10" -Ver "21H1"
                invoke-MEMCMUpdatecatalog -prod "Windows 10" -ver "21H1"}
            if ($WPFUpdatesW10_20H2.IsChecked -eq $true){
                invoke-MEMCMUpdateSupersedence -prod "Windows 10" -Ver "20H2"
                invoke-MEMCMUpdatecatalog -prod "Windows 10" -ver "20H2"}
            if ($WPFUpdatesW10_2004.IsChecked -eq $true){
                invoke-MEMCMUpdateSupersedence -prod "Windows 10" -Ver "2004"
                invoke-MEMCMUpdatecatalog -prod "Windows 10" -ver "2004"}
            if ($WPFUpdatesW10_1909.IsChecked -eq $true){
                invoke-MEMCMUpdateSupersedence -prod "Windows 10" -Ver "1909"
                invoke-MEMCMUpdatecatalog -prod "Windows 10" -ver "1909"}
            if ($WPFUpdatesW10_1903.IsChecked -eq $true){
                invoke-MEMCMUpdateSupersedence -prod "Windows 10" -Ver "1903"
                invoke-MEMCMUpdatecatalog -prod "Windows 10" -ver "1903"}
            if ($WPFUpdatesW10_1809.IsChecked -eq $true){
                invoke-MEMCMUpdateSupersedence -prod "Windows 10" -Ver "1809"
                invoke-MEMCMUpdatecatalog -prod "Windows 10" -ver "1809"}
            if ($WPFUpdatesW10_1803.IsChecked -eq $true){
                invoke-MEMCMUpdateSupersedence -prod "Windows 10" -Ver "1803"
                invoke-MEMCMUpdatecatalog -prod "Windows 10" -ver "1803"}
            if ($WPFUpdatesW10_1709.IsChecked -eq $true){
                invoke-MEMCMUpdateSupersedence -prod "Windows 10" -Ver "1709"
                invoke-MEMCMUpdatecatalog -prod "Windows 10" -ver "1709"}
        download-onedrive
        }
        if ($WPFUpdatesS2019.IsChecked -eq $true){
                invoke-MEMCMUpdateSupersedence -prod "Windows Server" -Ver "1809"
                invoke-MEMCMUpdatecatalog -prod "Windows Server" -Ver "1809"}
        if ($WPFUpdatesS2016.IsChecked -eq $true){
                invoke-MEMCMUpdateSupersedence -prod "Windows Server" -Ver "1607"
                invoke-MEMCMUpdatecatalog -prod "Windows Server" -Ver "1607"}
        if ($WPFUpdatesS2022.IsChecked -eq $true){
            invoke-MEMCMUpdateSupersedence -prod "Windows Server" -Ver "21H2"
            invoke-MEMCMUpdatecatalog -prod "Windows Server" -Ver "21H2"}
        if ($WPFUpdatesW11Main1.IsChecked -eq $true){
            invoke-MEMCMUpdateSupersedence -prod "Windows 11" -Ver "21H2"
            invoke-MEMCMUpdatecatalog -prod "Windows 11" -Ver "21H2"}

    }
        update-log -data "All downloads complete" -class Information
}

#Function to apply updates to mounted WIM
Function Apply-Updates($class) {
   function Apply-LCU($packagepath){
    
    $executable = "$env:windir\system32\expand.exe"
    $filename = (get-childitem $packagepath).name
    
    
    Update-Log -Data "Extracting LCU Package content to staging folder..." -Class Information
    Start-Process $executable -args @("`"$packagepath\$filename`"",'/f:*.CAB',"`"$PSScriptRoot\staging`"") -wait -ErrorAction Stop
    $cabs = (Get-Item $PSScriptRoot\staging\*.cab)


    update-log  -data "Applying SSU..." -class information
    foreach ($cab in $cabs){
        
        if ($cab -like "*SSU*"){
            update-log -data $cab -class Information
            Add-WindowsPackage -path $WPFMISMountTextBox.Text -PackagePath $cab -erroraction stop| Out-Null}}
    
    update-log -data "Applying LCU..." -class information
    foreach ($cab in $cabs){
        if ($cab -notlike "*SSU*"){
            update-log -data $cab -class information
            Add-WindowsPackage -path $WPFMISMountTextBox.Text -PackagePath $cab -erroraction stop| Out-Null}}

   }
   
   
   
   if (($class -eq 'AdobeSU') -and ($WPFSourceWIMImgDesTextBox.text -like "Windows Server 20*") -and ($WPFSourceWIMImgDesTextBox.text -notlike "*(Desktop Experience)")){
    update-log -Data "Skipping Adobe updates for Server Core build" -Class Information
    return}

    $OS = get-windowstype
    $buildnum = get-winvernum
    if ($buildnum -eq "2009"){$buildnum = "20H2"}

  
    If (($WPFSourceWimVerTextBox.text -like "10.0.18362.*") -and (($class -ne "Dynamic") -and ($class -notlike "PE*"))){ 
        $mountdir = $WPFMISMountTextBox.Text
        reg LOAD HKLM\OFFLINE $mountdir\Windows\System32\Config\SOFTWARE | Out-Null
        $regvalues = (Get-ItemProperty -Path "Registry::HKEY_LOCAL_MACHINE\OFFLINE\Microsoft\Windows NT\CurrentVersion\" )
        $buildnum = $regvalues.ReleaseId
        reg UNLOAD HKLM\OFFLINE | Out-Null}


    If (($WPFSourceWimVerTextBox.text -like "10.0.18362.*") -and (($class -eq "Dynamic") -or ($class -like 'PE*'))) {
        $windowsver = Get-WindowsImage -ImagePath ($PSScriptRoot + '\staging\' + $WPFMISWimNameTextBox.text) -Index 1
        $Vardate = (Get-Date -Year 2019 -Month 10 -Day 01)
        if ($windowsver.CreatedTime -gt $vardate){$buildnum = 1909}
           else
           {$buildnum = 1903}
        } 

    if ($class -eq 'PESSU'){
        $IsPE = $true
        $class = 'SSU'
        }

    if ($class -eq 'PELCU'){
        $IsPE = $true
        $class = 'LCU'
        }
            
    $path = $PSScriptRoot + '\updates\' + $OS + '\' + $buildnum + '\' + $class + '\'
    
    if ((Test-Path $path) -eq $False){
        update-log -data "$path does not exist. There are no updates of this class to apply" -class Warning
        return
        }

    $Children = Get-ChildItem -Path $path
    foreach ($Children in $Children) {
        $compound = $path + $Children
        update-log -Data "Applying $Children" -Class Information
    try{
        if ($class -eq 'Dynamic'){
            #update-log -data "Applying Dynamic to media" -Class Information
            $mediafolder = $PSScriptRoot + '\staging\media\sources'
            #write-host $compound
            #write-host $mediafolder
            $DynUpdates = (get-childitem -path $compound -name)
            foreach ($DynUpdate in $DynUpdates){
        
                $text = $compound + '\' + $DynUpdate
                #write-host $text
                start-process -filepath c:\windows\system32\expand.exe -args @("`"$text`"",'-F:*',"`"$mediafolder`"") -wait
                }
        }
        elseif($IsPE -eq $true){Add-WindowsPackage -path ($PSScriptRoot + '\staging\mount') -PackagePath $compound -erroraction stop| Out-Null}
        else{
            if ($class -eq "LCU"){
                if (($os -eq "Windows 10") -and (($buildnum -eq "2004") -or ($buildnum -eq "2009") -or ($buildnum -eq "20H2") -or ($buildnum -eq "21H1"))) {
                    update-log -data "Processing the LCU package to retrieve SSU..." -class information
                    Apply-LCU -packagepath $compound
                }
                else{
               
                Add-WindowsPackage -path $WPFMISMountTextBox.Text -PackagePath $compound -erroraction stop| Out-Null}
           } 
            
            else{Add-WindowsPackage -path $WPFMISMountTextBox.Text -PackagePath $compound -erroraction stop| Out-Null}
            
        }
    }
    catch
        {
        update-log -data "Failed to apply update" -class Warning
        update-log -data $_.Exception.Message -class Warning
        }    
    }
}


#Function to select AppX packages to yank
Function Select-Appx {
    $appx1903 = @("Microsoft.BingWeather_4.25.20211.0_neutral_~_8wekyb3d8bbwe"
        "Microsoft.DesktopAppInstaller_2019.125.2243.0_neutral_~_8wekyb3d8bbwe"
        "Microsoft.GetHelp_10.1706.13331.0_neutral_~_8wekyb3d8bbwe"
        "Microsoft.Getstarted_7.3.20251.0_neutral_~_8wekyb3d8bbwe"
        "Microsoft.HEIFImageExtension_1.0.13472.0_x64__8wekyb3d8bbwe"
        "Microsoft.Messaging_2019.125.32.0_neutral_~_8wekyb3d8bbwe"
        "Microsoft.Microsoft3DViewer_5.1902.20012.0_neutral_~_8wekyb3d8bbwe"
        "Microsoft.MicrosoftOfficeHub_18.1901.1141.0_neutral_~_8wekyb3d8bbwe"
        "Microsoft.MicrosoftSolitaireCollection_4.2.11280.0_neutral_~_8wekyb3d8bbwe"
        "Microsoft.MicrosoftStickyNotes_3.1.53.0_neutral_~_8wekyb3d8bbwe"
        "Microsoft.MixedReality.Portal_2000.19010.1151.0_neutral_~_8wekyb3d8bbwe"
        "Microsoft.MSPaint_2019.213.1858.0_neutral_~_8wekyb3d8bbwe"
        "Microsoft.Office.OneNote_16001.11126.20076.0_neutral_~_8wekyb3d8bbwe"
        "Microsoft.OneConnect_5.1902.361.0_neutral_~_8wekyb3d8bbwe"
        "Microsoft.People_2019.123.2346.0_neutral_~_8wekyb3d8bbwe"
        "Microsoft.Print3D_3.3.311.0_neutral_~_8wekyb3d8bbwe"
        "Microsoft.ScreenSketch_2018.1214.231.0_neutral_~_8wekyb3d8bbwe"
        "Microsoft.SkypeApp_14.35.152.0_neutral_~_kzf8qxf38zg5c"
        "Microsoft.StorePurchaseApp_11811.1001.1813.0_neutral_~_8wekyb3d8bbwe"
        "Microsoft.VP9VideoExtensions_1.0.13333.0_x64__8wekyb3d8bbwe"
        "Microsoft.Wallet_2.4.18324.0_neutral_~_8wekyb3d8bbwe"
        "Microsoft.WebMediaExtensions_1.0.13321.0_neutral_~_8wekyb3d8bbwe"
        "Microsoft.WebpImageExtension_1.0.12821.0_x64__8wekyb3d8bbwe"
        "Microsoft.Windows.Photos_2019.18114.19418.0_neutral_~_8wekyb3d8bbwe"
        "Microsoft.WindowsAlarms_2019.105.629.0_neutral_~_8wekyb3d8bbwe"
        "Microsoft.WindowsCalculator_2019.105.612.0_neutral_~_8wekyb3d8bbwe"
        "Microsoft.WindowsCamera_2018.826.78.0_neutral_~_8wekyb3d8bbwe"
        "Microsoft.windowscommunicationsapps_16005.11029.20108.0_neutral_~_8wekyb3d8bbwe"
        "Microsoft.WindowsFeedbackHub_2019.226.2324.0_neutral_~_8wekyb3d8bbwe"
        "Microsoft.WindowsMaps_2019.108.627.0_neutral_~_8wekyb3d8bbwe"
        "Microsoft.WindowsSoundRecorder_2019.105.618.0_neutral_~_8wekyb3d8bbwe"
        "Microsoft.WindowsStore_11811.1001.1813.0_neutral_~_8wekyb3d8bbwe"
        "Microsoft.Xbox.TCUI_1.23.28002.0_neutral_~_8wekyb3d8bbwe"
        "Microsoft.XboxApp_48.48.7001.0_neutral_~_8wekyb3d8bbwe"
        "Microsoft.XboxGameOverlay_1.32.17005.0_neutral_~_8wekyb3d8bbwe"
        "Microsoft.XboxGamingOverlay_2.26.14003.0_neutral_~_8wekyb3d8bbwe"
        "Microsoft.XboxIdentityProvider_12.50.6001.0_neutral_~_8wekyb3d8bbwe"
        "Microsoft.XboxSpeechToTextOverlay_1.17.29001.0_neutral_~_8wekyb3d8bbwe"
        "Microsoft.YourPhone_2018.1128.231.0_neutral_~_8wekyb3d8bbwe"
        "Microsoft.ZuneMusic_2019.18111.17311.0_neutral_~_8wekyb3d8bbwe"
        "Microsoft.ZuneVideo_2019.18111.17311.0_neutral_~_8wekyb3d8bbwe")
    $appx1809 = @(
        "Microsoft.BingWeather_4.25.12127.0_neutral_~_8wekyb3d8bbwe"                   
        "Microsoft.DesktopAppInstaller_2018.720.2137.0_neutral_~_8wekyb3d8bbwe"        
        "Microsoft.GetHelp_10.1706.10441.0_neutral_~_8wekyb3d8bbwe"                    
        "Microsoft.Getstarted_6.13.11581.0_neutral_~_8wekyb3d8bbwe"                    
        "Microsoft.HEIFImageExtension_1.0.11792.0_x64__8wekyb3d8bbwe"                  
        "Microsoft.Messaging_2018.727.1430.0_neutral_~_8wekyb3d8bbwe"                  
        "Microsoft.Microsoft3DViewer_4.1808.15012.0_neutral_~_8wekyb3d8bbwe"           
        "Microsoft.MicrosoftOfficeHub_2017.1219.520.0_neutral_~_8wekyb3d8bbwe"         
        "Microsoft.MicrosoftSolitaireCollection_4.1.5252.0_neutral_~_8wekyb3d8bbwe"    
        "Microsoft.MicrosoftStickyNotes_2.0.13.0_neutral_~_8wekyb3d8bbwe"              
        "Microsoft.MixedReality.Portal_2000.18081.1242.0_neutral_~_8wekyb3d8bbwe"      
        "Microsoft.MSPaint_4.1807.12027.0_neutral_~_8wekyb3d8bbwe"                     
        "Microsoft.Office.OneNote_16001.10228.20003.0_neutral_~_8wekyb3d8bbwe"         
        "Microsoft.OneConnect_5.1807.1991.0_neutral_~_8wekyb3d8bbwe"                   
        "Microsoft.People_2018.516.2011.0_neutral_~_8wekyb3d8bbwe"                     
        "Microsoft.Print3D_3.0.1521.0_neutral_~_8wekyb3d8bbwe"                         
        "Microsoft.ScreenSketch_2018.731.48.0_neutral_~_8wekyb3d8bbwe"                 
        "Microsoft.SkypeApp_14.26.95.0_neutral_~_kzf8qxf38zg5c"                        
        "Microsoft.StorePurchaseApp_11805.1001.813.0_neutral_~_8wekyb3d8bbwe"          
        "Microsoft.VP9VideoExtensions_1.0.12342.0_x64__8wekyb3d8bbwe"                  
        "Microsoft.Wallet_2.2.18179.0_neutral_~_8wekyb3d8bbwe"                         
        "Microsoft.WebMediaExtensions_1.0.12341.0_neutral_~_8wekyb3d8bbwe"             
        "Microsoft.WebpImageExtension_1.0.11551.0_x64__8wekyb3d8bbwe"                  
        "Microsoft.Windows.Photos_2018.18051.21218.0_neutral_~_8wekyb3d8bbwe"          
        "Microsoft.WindowsAlarms_2018.516.2059.0_neutral_~_8wekyb3d8bbwe"              
        "Microsoft.WindowsCalculator_2018.501.612.0_neutral_~_8wekyb3d8bbwe"           
        "Microsoft.WindowsCamera_2018.425.120.0_neutral_~_8wekyb3d8bbwe"               
        "Microsoft.windowscommunicationsapps_2015.9330.21365.0_neutral_~_8wekyb3d8bbwe"
        "Microsoft.WindowsFeedbackHub_2018.822.2.0_neutral_~_8wekyb3d8bbwe"            
        "Microsoft.WindowsMaps_2018.523.2143.0_neutral_~_8wekyb3d8bbwe"                
        "Microsoft.WindowsSoundRecorder_2018.713.2154.0_neutral_~_8wekyb3d8bbwe"       
        "Microsoft.WindowsStore_11805.1001.4913.0_neutral_~_8wekyb3d8bbwe"             
        "Microsoft.Xbox.TCUI_1.11.28003.0_neutral_~_8wekyb3d8bbwe"                     
        "Microsoft.XboxApp_41.41.18001.0_neutral_~_8wekyb3d8bbwe"                      
        "Microsoft.XboxGameOverlay_1.32.17005.0_neutral_~_8wekyb3d8bbwe"               
        "Microsoft.XboxGamingOverlay_2.20.22001.0_neutral_~_8wekyb3d8bbwe"             
        "Microsoft.XboxIdentityProvider_12.44.20001.0_neutral_~_8wekyb3d8bbwe"         
        "Microsoft.XboxSpeechToTextOverlay_1.17.29001.0_neutral_~_8wekyb3d8bbwe"       
        "Microsoft.YourPhone_2018.727.2137.0_neutral_~_8wekyb3d8bbwe"                  
        "Microsoft.ZuneMusic_2019.18052.20211.0_neutral_~_8wekyb3d8bbwe"               
        "Microsoft.ZuneVideo_2019.18052.20211.0_neutral_~_8wekyb3d8bbwe" 
    )
    $appx1803 = @( 
        "Microsoft.BingWeather_4.22.3254.0_neutral_~_8wekyb3d8bbwe"                    
        "Microsoft.DesktopAppInstaller_1.8.15011.0_neutral_~_8wekyb3d8bbwe"            
        "Microsoft.GetHelp_10.1706.10441.0_neutral_~_8wekyb3d8bbwe"                    
        "Microsoft.Getstarted_6.9.10602.0_neutral_~_8wekyb3d8bbwe"                     
        "Microsoft.Messaging_2018.222.2231.0_neutral_~_8wekyb3d8bbwe"                  
        "Microsoft.Microsoft3DViewer_2.1803.8022.0_neutral_~_8wekyb3d8bbwe"            
        "Microsoft.MicrosoftOfficeHub_2017.1219.520.0_neutral_~_8wekyb3d8bbwe"         
        "Microsoft.MicrosoftSolitaireCollection_4.0.1301.0_neutral_~_8wekyb3d8bbwe"    
        "Microsoft.MicrosoftStickyNotes_2.0.13.0_neutral_~_8wekyb3d8bbwe"              
        "Microsoft.MSPaint_3.1803.5027.0_neutral_~_8wekyb3d8bbwe"                      
        "Microsoft.Office.OneNote_2015.8827.20991.0_neutral_~_8wekyb3d8bbwe"           
        "Microsoft.OneConnect_4.1801.521.0_neutral_~_8wekyb3d8bbwe"                    
        "Microsoft.People_2018.215.110.0_neutral_~_8wekyb3d8bbwe"                      
        "Microsoft.Print3D_2.0.3621.0_neutral_~_8wekyb3d8bbwe"                         
        "Microsoft.SkypeApp_12.13.274.0_neutral_~_kzf8qxf38zg5c"                       
        "Microsoft.StorePurchaseApp_11712.1801.10024.0_neutral_~_8wekyb3d8bbwe"        
        "Microsoft.Wallet_2.1.18009.0_neutral_~_8wekyb3d8bbwe"                         
        "Microsoft.WebMediaExtensions_1.0.3102.0_neutral_~_8wekyb3d8bbwe"              
        "Microsoft.Windows.Photos_2018.18011.15918.0_neutral_~_8wekyb3d8bbwe"          
        "Microsoft.WindowsAlarms_2018.302.1846.0_neutral_~_8wekyb3d8bbwe"              
        "Microsoft.WindowsCalculator_2018.302.144.0_neutral_~_8wekyb3d8bbwe"           
        "Microsoft.WindowsCamera_2017.1117.80.0_neutral_~_8wekyb3d8bbwe"               
        "Microsoft.windowscommunicationsapps_2015.8827.22055.0_neutral_~_8wekyb3d8bbwe"
        "Microsoft.WindowsFeedbackHub_2018.302.2011.0_neutral_~_8wekyb3d8bbwe"         
        "Microsoft.WindowsMaps_2018.209.2206.0_neutral_~_8wekyb3d8bbwe"                
        "Microsoft.WindowsSoundRecorder_2018.302.1842.0_neutral_~_8wekyb3d8bbwe"       
        "Microsoft.WindowsStore_11712.1001.2313.0_neutral_~_8wekyb3d8bbwe"             
        "Microsoft.Xbox.TCUI_1.11.28003.0_neutral_~_8wekyb3d8bbwe"                     
        "Microsoft.XboxApp_38.38.14002.0_neutral_~_8wekyb3d8bbwe"                      
        "Microsoft.XboxGameOverlay_1.26.6001.0_neutral_~_8wekyb3d8bbwe"                
        "Microsoft.XboxGamingOverlay_1.15.1001.0_neutral_~_8wekyb3d8bbwe"              
        "Microsoft.XboxIdentityProvider_12.36.15002.0_neutral_~_8wekyb3d8bbwe"         
        "Microsoft.XboxSpeechToTextOverlay_1.17.29001.0_neutral_~_8wekyb3d8bbwe"       
        "Microsoft.ZuneMusic_2019.17112.19011.0_neutral_~_8wekyb3d8bbwe"               
        "Microsoft.ZuneVideo_2019.17112.19011.0_neutral_~_8wekyb3d8bbwe" )
    $appx1709 = @( 
        "Microsoft.BingWeather_4.21.2492.0_neutral_~_8wekyb3d8bbwe",                    
        "Microsoft.DesktopAppInstaller_1.8.4001.0_neutral_~_8wekyb3d8bbwe",             
        "Microsoft.GetHelp_10.1706.1811.0_neutral_~_8wekyb3d8bbwe",                     
        "Microsoft.Getstarted_5.11.1641.0_neutral_~_8wekyb3d8bbwe",                     
        "Microsoft.Messaging_2017.815.2052.0_neutral_~_8wekyb3d8bbwe",                  
        "Microsoft.Microsoft3DViewer_1.1707.26019.0_neutral_~_8wekyb3d8bbwe",           
        "Microsoft.MicrosoftOfficeHub_2017.715.118.0_neutral_~_8wekyb3d8bbwe",          
        "Microsoft.MicrosoftSolitaireCollection_3.17.8162.0_neutral_~_8wekyb3d8bbwe",   
        "Microsoft.MicrosoftStickyNotes_1.8.2.0_neutral_~_8wekyb3d8bbwe",               
        "Microsoft.MSPaint_2.1709.4027.0_neutral_~_8wekyb3d8bbwe",                      
        "Microsoft.Office.OneNote_2015.8366.57611.0_neutral_~_8wekyb3d8bbwe",           
        "Microsoft.OneConnect_3.1708.2224.0_neutral_~_8wekyb3d8bbwe",                   
        "Microsoft.People_2017.823.2207.0_neutral_~_8wekyb3d8bbwe",                     
        "Microsoft.Print3D_1.0.2422.0_neutral_~_8wekyb3d8bbwe",                         
        "Microsoft.SkypeApp_11.18.596.0_neutral_~_kzf8qxf38zg5c",                       
        "Microsoft.StorePurchaseApp_11706.1707.7104.0_neutral_~_8wekyb3d8bbwe",         
        "Microsoft.Wallet_1.0.16328.0_neutral_~_8wekyb3d8bbwe",                         
        "Microsoft.Windows.Photos_2017.37071.16410.0_neutral_~_8wekyb3d8bbwe",          
        "Microsoft.WindowsAlarms_2017.828.2050.0_neutral_~_8wekyb3d8bbwe",              
        "Microsoft.WindowsCalculator_2017.828.2012.0_neutral_~_8wekyb3d8bbwe",          
        "Microsoft.WindowsCamera_2017.727.20.0_neutral_~_8wekyb3d8bbwe",                
        "Microsoft.windowscommunicationsapps_2015.8241.41275.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.WindowsFeedbackHub_1.1705.2121.0_neutral_~_8wekyb3d8bbwe",           
        "Microsoft.WindowsMaps_2017.814.2249.0_neutral_~_8wekyb3d8bbwe",                
        "Microsoft.WindowsSoundRecorder_2017.605.2103.0_neutral_~_8wekyb3d8bbwe",       
        "Microsoft.WindowsStore_11706.1002.94.0_neutral_~_8wekyb3d8bbwe",               
        "Microsoft.Xbox.TCUI_1.8.24001.0_neutral_~_8wekyb3d8bbwe",                      
        "Microsoft.XboxApp_31.32.16002.0_neutral_~_8wekyb3d8bbwe",                      
        "Microsoft.XboxGameOverlay_1.20.25002.0_neutral_~_8wekyb3d8bbwe",               
        "Microsoft.XboxIdentityProvider_2017.605.1240.0_neutral_~_8wekyb3d8bbwe",       
        "Microsoft.XboxSpeechToTextOverlay_1.17.29001.0_neutral_~_8wekyb3d8bbwe",       
        "Microsoft.ZuneMusic_2019.17063.24021.0_neutral_~_8wekyb3d8bbwe",               
        "Microsoft.ZuneVideo_2019.17063.24021.0_neutral_~_8wekyb3d8bbwe" )
    $appx2004 = @(
        "Microsoft.549981C3F5F10_1.1911.21713.0_neutral_~_8wekyb3d8bbwe",                 
        "Microsoft.BingWeather_4.25.20211.0_neutral_~_8wekyb3d8bbwe",                     
        "Microsoft.DesktopAppInstaller_2019.125.2243.0_neutral_~_8wekyb3d8bbwe",          
        "Microsoft.GetHelp_10.1706.13331.0_neutral_~_8wekyb3d8bbwe",                      
        "Microsoft.Getstarted_8.2.22942.0_neutral_~_8wekyb3d8bbwe",                       
        "Microsoft.HEIFImageExtension_1.0.22742.0_x64__8wekyb3d8bbwe",                    
        "Microsoft.Microsoft3DViewer_6.1908.2042.0_neutral_~_8wekyb3d8bbwe",              
        "Microsoft.MicrosoftOfficeHub_18.1903.1152.0_neutral_~_8wekyb3d8bbwe",            
        "Microsoft.MicrosoftSolitaireCollection_4.4.8204.0_neutral_~_8wekyb3d8bbwe",      
        "Microsoft.MicrosoftStickyNotes_3.6.73.0_neutral_~_8wekyb3d8bbwe",                
        "Microsoft.MixedReality.Portal_2000.19081.1301.0_neutral_~_8wekyb3d8bbwe",        
        "Microsoft.MSPaint_2019.729.2301.0_neutral_~_8wekyb3d8bbwe",                      
        "Microsoft.Office.OneNote_16001.12026.20112.0_neutral_~_8wekyb3d8bbwe",           
        "Microsoft.People_2019.305.632.0_neutral_~_8wekyb3d8bbwe",                        
        "Microsoft.ScreenSketch_2019.904.1644.0_neutral_~_8wekyb3d8bbwe",                 
        "Microsoft.SkypeApp_14.53.77.0_neutral_~_kzf8qxf38zg5c",                          
        "Microsoft.StorePurchaseApp_11811.1001.1813.0_neutral_~_8wekyb3d8bbwe",           
        "Microsoft.VCLibs.140.00_14.0.27323.0_x64__8wekyb3d8bbwe",                        
        "Microsoft.VP9VideoExtensions_1.0.22681.0_x64__8wekyb3d8bbwe",                    
        "Microsoft.Wallet_2.4.18324.0_neutral_~_8wekyb3d8bbwe",                           
        "Microsoft.WebMediaExtensions_1.0.20875.0_neutral_~_8wekyb3d8bbwe",               
        "Microsoft.WebpImageExtension_1.0.22753.0_x64__8wekyb3d8bbwe",                    
        "Microsoft.Windows.Photos_2019.19071.12548.0_neutral_~_8wekyb3d8bbwe",            
        "Microsoft.WindowsAlarms_2019.807.41.0_neutral_~_8wekyb3d8bbwe",                  
        "Microsoft.WindowsCalculator_2020.1906.55.0_neutral_~_8wekyb3d8bbwe",             
        "Microsoft.WindowsCamera_2018.826.98.0_neutral_~_8wekyb3d8bbwe",                  
        "microsoft.windowscommunicationsapps_16005.11629.20316.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.WindowsFeedbackHub_2019.1111.2029.0_neutral_~_8wekyb3d8bbwe",          
        "Microsoft.WindowsMaps_2019.716.2316.0_neutral_~_8wekyb3d8bbwe",                  
        "Microsoft.WindowsSoundRecorder_2019.716.2313.0_neutral_~_8wekyb3d8bbwe",         
        "Microsoft.WindowsStore_11910.1002.513.0_neutral_~_8wekyb3d8bbwe",                
        "Microsoft.Xbox.TCUI_1.23.28002.0_neutral_~_8wekyb3d8bbwe",                       
        "Microsoft.XboxApp_48.49.31001.0_neutral_~_8wekyb3d8bbwe",                        
        "Microsoft.XboxGameOverlay_1.46.11001.0_neutral_~_8wekyb3d8bbwe",                 
        "Microsoft.XboxGamingOverlay_2.34.28001.0_neutral_~_8wekyb3d8bbwe",               
        "Microsoft.XboxIdentityProvider_12.50.6001.0_neutral_~_8wekyb3d8bbwe",            
        "Microsoft.XboxSpeechToTextOverlay_1.17.29001.0_neutral_~_8wekyb3d8bbwe",         
        "Microsoft.YourPhone_2019.430.2026.0_neutral_~_8wekyb3d8bbwe",                    
        "Microsoft.ZuneMusic_2019.19071.19011.0_neutral_~_8wekyb3d8bbwe",                 
        "Microsoft.ZuneVideo_2019.19071.19011.0_neutral_~_8wekyb3d8bbwe" )
    $appx2009 = @(
        "Microsoft.549981C3F5F10_1.1911.21713.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.BingWeather_4.25.20211.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.DesktopAppInstaller_2019.125.2243.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.GetHelp_10.1706.13331.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.Getstarted_8.2.22942.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.HEIFImageExtension_1.0.22742.0_x64__8wekyb3d8bbwe",
        "Microsoft.Microsoft3DViewer_6.1908.2042.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.MicrosoftEdge.Stable_84.0.522.52_neutral__8wekyb3d8bbwe",
        "Microsoft.MicrosoftOfficeHub_18.1903.1152.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.MicrosoftSolitaireCollection_4.4.8204.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.MicrosoftStickyNotes_3.6.73.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.MixedReality.Portal_2000.19081.1301.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.MSPaint_2019.729.2301.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.Office.OneNote_16001.12026.20112.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.People_2019.305.632.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.ScreenSketch_2019.904.1644.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.SkypeApp_14.53.77.0_neutral_~_kzf8qxf38zg5c",
        "Microsoft.StorePurchaseApp_11811.1001.1813.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.VCLibs.140.00_14.0.27323.0_x64__8wekyb3d8bbwe",
        "Microsoft.VP9VideoExtensions_1.0.22681.0_x64__8wekyb3d8bbwe",
        "Microsoft.Wallet_2.4.18324.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.WebMediaExtensions_1.0.20875.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.WebpImageExtension_1.0.22753.0_x64__8wekyb3d8bbwe",
        "Microsoft.Windows.Photos_2019.19071.12548.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.WindowsAlarms_2019.807.41.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.WindowsCalculator_2020.1906.55.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.WindowsCamera_2018.826.98.0_neutral_~_8wekyb3d8bbwe",
        "microsoft.windowscommunicationsapps_16005.11629.20316.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.WindowsFeedbackHub_2019.1111.2029.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.WindowsMaps_2019.716.2316.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.WindowsSoundRecorder_2019.716.2313.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.WindowsStore_11910.1002.513.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.Xbox.TCUI_1.23.28002.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.XboxApp_48.49.31001.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.XboxGameOverlay_1.46.11001.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.XboxGamingOverlay_2.34.28001.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.XboxIdentityProvider_12.50.6001.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.XboxSpeechToTextOverlay_1.17.29001.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.YourPhone_2019.430.2026.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.ZuneMusic_2019.19071.19011.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.ZuneVideo_2019.19071.19011.0_neutral_~_8wekyb3d8bbwe")
    $appx21H1 = @(
        "Microsoft.549981C3F5F10_2.2106.2807.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.BingNews_4.7.28001.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.BingWeather_4.9.2002.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.DesktopAppInstaller_2020.812.2125.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.GamingApp_2021.427.138.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.GetHelp_10.2008.32311.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.Getstarted_10.2.41172.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.HEIFImageExtension_1.0.40978.0_x64__8wekyb3d8bbwe",
        "Microsoft.MicrosoftOfficeHub_18.2104.12721.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.MicrosoftSolitaireCollection_4.6.3102.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.MicrosoftStickyNotes_4.1.2.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.Paint_10.2104.17.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.People_2020.901.1724.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.PowerAutomateDesktop_10.0.561.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.ScreenSketch_2021.2104.2.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.SecHealthUI_1000.22000.1.0_neutral__8wekyb3d8bbwe",
        "Microsoft.StorePurchaseApp_12008.1001.113.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.Todos_2.33.33351.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.UI.Xaml.2.4_2.42007.9001.0_x64__8wekyb3d8bbwe",
        "Microsoft.VCLibs.140.00_14.0.29231.0_x64__8wekyb3d8bbwe",
        "Microsoft.VP9VideoExtensions_1.0.41182.0_x64__8wekyb3d8bbwe",
        "Microsoft.WebMediaExtensions_1.0.40831.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.WebpImageExtension_1.0.32731.0_x64__8wekyb3d8bbwe",
        "Microsoft.Windows.Photos_21.21030.25003.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.WindowsAlarms_2021.2101.27.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.WindowsCalculator_2020.2012.21.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.WindowsCamera_2020.503.58.0_neutral_~_8wekyb3d8bbwe",
        "microsoft.windowscommunicationsapps_16005.12827.20400.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.WindowsFeedbackHub_2021.427.1821.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.WindowsMaps_2021.2012.10.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.WindowsNotepad_10.2102.13.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.WindowsSoundRecorder_2021.2012.41.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.WindowsStore_12104.1001.113.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.WindowsTerminal_2021.226.1915.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.Xbox.TCUI_1.23.28002.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.XboxGameOverlay_1.46.11001.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.XboxGamingOverlay_2.50.24002.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.XboxIdentityProvider_12.50.6001.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.XboxSpeechToTextOverlay_1.17.29001.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.YourPhone_2019.430.2026.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.ZuneMusic_2019.21012.10511.0_neutral_~_8wekyb3d8bbwe",
        "Microsoft.ZuneVideo_2019.21012.10511.0_neutral_~_8wekyb3d8bbwe",
        "MicrosoftWindows.Client.WebExperience_321.14700.0.9_neutral_~_cw5n1h2txyewy")
 

    If ($WPFSourceWimVerTextBox.text -like "10.0.18362.*") { $exappxs = write-output $appx1903 | out-gridview -title "Select apps to remove" -passthru }
    If ($WPFSourceWimVerTextBox.text -like "10.0.17763.*") { $exappxs = write-output $appx1809 | out-gridview -title "Select apps to remove" -passthru }
    If ($WPFSourceWimVerTextBox.text -like "10.0.17134.*") { $exappxs = write-output $appx1803 | out-gridview -title "Select apps to remove" -passthru }
    If ($WPFSourceWimVerTextBox.text -like "10.0.16299.*") { $exappxs = write-output $appx1709 | out-gridview -title "Select apps to remove" -passthru }
    If ($WPFSourceWimVerTextBox.text -like "10.0.19041.*") { $exappxs = write-output $appx2004 | out-gridview -title "Select apps to remove" -passthru } 
    If ($WPFSourceWimVerTextBox.text -like "10.0.22000.*") { $exappxs = write-output $appx21H1 | out-gridview -title "Select apps to remove" -passthru } 


    if ($exappxs -eq $null) {
        Update-Log -Data "No apps were selected" -Class Warning
    }
    if ($exappxs -ne $null) {
        Update-Log -data "The following apps were selected for removal:" -Class Information
        Foreach ($exappx in $exappxs) {
            Update-Log -Data $exappx -Class Information
        }

        $WPFAppxTextBox.Text = $exappxs
        return $exappxs
    }
}

#Function to remove appx packages
function remove-appx($array) {
    $exappxs = $array
    update-log -data "Starting AppX removal" -class Information
    foreach ($exappx in $exappxs) {
        Remove-AppxProvisionedPackage -Path $WPFMISMountTextBox.Text -PackageName $exappx | Out-Null
        update-log -data "Removing $exappx" -Class Information
    }
    return
}

#Function to remove unwanted image indexes
Function remove-indexes {
    Update-Log -Data "Attempting to remove unwanted image indexes" -Class Information
    $wimname = Get-Item -Path $PSScriptRoot\Staging\*.wim
   
    Update-Log -Data "Found Image $wimname" -Class Information
    $IndexesAll = Get-WindowsImage -ImagePath $wimname | foreach { $_.ImageName }
    $IndexSelected = $WPFSourceWIMImgDesTextBox.Text
    foreach ($Index in $IndexesAll) {
        Update-Log -data "$Index is being evaluated"
        If ($Index -eq $IndexSelected) {
            Update-Log -Data "$Index is the index we want to keep. Skipping." -Class Information | Out-Null
        }
        else {
            update-log -data "Deleting $Index from WIM" -Class Information
            Remove-WindowsImage -ImagePath $wimname -Name $Index -InformationAction SilentlyContinue | Out-Null

        }
    }
}

#Function to select which folder to save Autopilot JSON file to
Function SelectNewJSONDir {

    Add-Type -AssemblyName System.Windows.Forms
    $browser = New-Object System.Windows.Forms.FolderBrowserDialog
    $browser.Description = "Select the folder to save JSON"
    $null = $browser.ShowDialog()
    $SaveDir = $browser.SelectedPath
    $WPFJSONTextBoxSavePath.text = $SaveDir 
    $text = "Autopilot profile save path selected: $SaveDir" 
    update-log -Data $text -Class Information
}

#Function to retrieve autopilot profile from intune
function get-WWAutopilotProfile ($login, $path) {
    
    function update-autopilot{
        Update-Log -Data "Uninstalling old WindowsAutopilotIntune module..." -Class Warning
        Uninstall-Module -Name WindowsAutopilotIntune -AllVersions
        Update-Log -Data "Installing new WindowsAutopilotIntune module..." -Class Warning
        Install-Module -Name WindowsAutopilotIntune -force
        $AutopilotUpdate = ([System.Windows.MessageBox]::Show("WIM Witch needs to close and PowerShell needs to be restarted. Click OK to close WIM Witch.",'Updating complete.','OK','warning'))
        if ($AutopilotUpdate -eq "OK"){
            $form.Close()
            exit
            }
     }

    Update-Log -data "Checking dependencies for Autopilot profile retrieval..." -Class Information

    try {
        Import-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -ErrorAction Stop
        Update-Log -Data "NuGet is installed" -Class Information
    }
    catch {
        Update-Log -data "NuGet is not installed. Installing now..." -Class Warning
        Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force
        Update-Log -data "NuGet is now installed" -Class Information
    }

    try {

        Import-Module -name AzureAD -ErrorAction Stop | Out-Null
        Update-Log -data "AzureAD Module is installed" -Class Information
    }
    catch {
        Update-Log -data "AzureAD Module is not installed. Installing now..." -Class Warning
        Install-Module AzureAD -Force
        Update-Log -data "AzureAD is now installed" -class Information
    }

    try {

        Import-Module -Name WindowsAutopilotIntune -ErrorAction Stop
        Update-Log -data "WindowsAutopilotIntune module is installed" -Class Information
    }
    catch {

        Update-Log -data "WindowsAutopilotIntune module is not installed. Installing now..." -Class Warning
        Install-Module WindowsAutopilotIntune -Force
        update-log -data "WindowsAutopilotIntune module is now installed." -class Information
    }

        $AutopilotInstalledVer = (get-module -name windowsautopilotintune).Version
        Update-Log -Data "The currently installed version of the WindowsAutopilotIntune module is $AutopilotInstalledVer" -Class Information
        $AutopilotLatestVersion = (find-module -Name windowsautopilotintune).version
        update-log -data "The latest available version of the WindowsAutopilotIntune module is $AutopilotLatestVersion" -Class Information

        if ($AutopilotInstalledVer -eq $AutopilotLatestVersion){
            update-log -data "WindowsAutopilotIntune module is current. Continuing..." -Class Information}
            else{
            Update-Log -data "WindowsAutopilotIntune module is out of date. Prompting the user to upgrade..."
            $UpgradeAutopilot = ([System.Windows.MessageBox]::Show("Would you like to update the WindowsAutopilotIntune module to version $AutopilotLatestVersion now?",'Update Autopilot Module?','YesNo','warning'))
            }

        if ($UpgradeAutopilot -eq "Yes"){
            update-log -Data "User has chosen to update WindowsAutopilotIntune module" -Class Warning
            update-autopilot}
            elseif($AutopilotInstalledVer -ne $AutopilotLatestVersion){
            Update-Log -data "User declined to update WindowsAutopilotIntune module. Continuing..." -Class Warning}


    Update-Log -data "Connecting to Intune..." -Class Information
    if ($AutopilotInstalledVer -lt 3.9){Connect-AutopilotIntune | out-null}
            else{
        Connect-MSGraph | Out-Null}

    Update-Log -data "Connected to Intune" -Class Information

    Update-Log -data "Retrieving profile..." -Class Information
    Get-AutoPilotProfile | Out-GridView -title "Select Autopilot profile" -PassThru | ConvertTo-AutoPilotConfigurationJSON | Out-File $path\AutopilotConfigurationFile.json -Encoding ASCII
    $text = $path + "\AutopilotConfigurationFile.json"
    Update-Log -data "Profile successfully created at $text" -Class Information
}

#Function to save current configuration
function save-config{
    Param(
    [parameter(mandatory = $false, HelpMessage = "config file")] 
    [string]$filename,

    [parameter(mandatory = $false, HelpMessage = "enable CM files")] 
    [switch]$CM
    )

    $CurrentConfig = @{
        SourcePath       = $WPFSourceWIMSelectWIMTextBox.text
        SourceIndex      = $WPFSourceWimIndexTextBox.text
        SourceEdition    = $WPFSourceWIMImgDesTextBox.text
        UpdatesEnabled   = $WPFUpdatesEnableCheckBox.IsChecked
        AutopilotEnabled = $WPFJSONEnableCheckBox.IsChecked
        AutopilotPath    = $WPFJSONTextBox.text
        DriversEnabled   = $WPFDriverCheckBox.IsChecked
        DriverPath1      = $WPFDriverDir1TextBox.text
        DriverPath2      = $WPFDriverDir2TextBox.text
        DriverPath3      = $WPFDriverDir3TextBox.text
        DriverPath4      = $WPFDriverDir4TextBox.text
        DriverPath5      = $WPFDriverDir5TextBox.text
        AppxIsEnabled    = $WPFAppxCheckBox.IsChecked
        AppxSelected     = $WPFAppxTextBox.Text
        WIMName          = $WPFMISWimNameTextBox.text
        WIMPath          = $WPFMISWimFolderTextBox.text
        MountPath        = $WPFMISMountTextBox.text
        DotNetEnabled    = $WPFMISDotNetCheckBox.IsChecked
        OneDriveEnabled  = $WPFMISOneDriveCheckBox.IsChecked
        LPsEnabled       = $WPFCustomCBLangPacks.IsChecked
        LXPsEnabled      = $WPFCustomCBLEP.IsChecked
        FODsEnabled      = $WPFCustomCBFOD.IsChecked
        LPListBox        = $WPFCustomLBLangPacks.items
        LXPListBox       = $WPFCustomLBLEP.Items
        FODListBox       = $WPFCustomLBFOD.Items
        PauseAfterMount  = $WPFMISCBPauseMount.IsChecked
        PauseBeforeDM    = $WPFMISCBPauseDismount.IsChecked
        RunScript        = $WPFCustomCBRunScript.IsChecked
        ScriptTiming     = $WPFCustomCBScriptTiming.SelectedItem
        ScriptFile       = $WPFCustomTBFile.Text
        ScriptParams     = $WPFCustomTBParameters.Text
        CMImageType      = $WPFCMCBImageType.SelectedItem
        CMPackageID      = $WPFCMTBPackageID.Text
        CMImageName      = $WPFCMTBImageName.Text
        CMVersion        = $WPFCMTBImageVer.Text
        CMDescription    = $WPFCMTBDescription.Text
        CMBinDifRep      = $WPFCMCBBinDirRep.IsChecked
        CMSiteCode       = $WPFCMTBSitecode.Text
        CMSiteServer     = $WPFCMTBSiteServer.Text
        CMDPGroup        = $WPFCMCBDPDPG.SelectedItem
        CMDPList         = $WPFCMLBDPs.Items
        UpdateSource     = $WPFUSCBSelectCatalogSource.SelectedItem
        UpdateMIS        = $WPFMISCBCheckForUpdates.IsChecked
        AutoFillVersion  = $WPFCMCBImageVerAuto.IsChecked
        AutoFillDesc     = $WPFCMCBDescriptionAuto.IsChecked
        DefaultAppCB     = $WPFCustomCBEnableApp.IsChecked
        DefaultAppPath   = $WPFCustomTBDefaultApp.Text
        StartMenuCB      = $WPFCustomCBEnableStart.IsChecked
        StartMenuPath    = $WPFCustomTBStartMenu.Text
        RegFilesCB       = $WPFCustomCBEnableRegistry.IsChecked
        RegFilesLB       = $WPFCustomLBRegistry.Items
        SUOptional       = $WPFUpdatesCBEnableOptional.IsChecked
        SUDynamic        = $WPFUpdatesCBEnableDynamic.IsChecked

        ApplyDynamicCB   = $WPFMISCBDynamicUpdates.IsChecked
        UpdateBootCB     = $WPFMISCBBootWIM.IsChecked
        DoNotCreateWIMCB = $WPFMISCBNoWIM.IsChecked
        CreateISO        = $WPFMISCBISO.IsChecked
        ISOFileName      = $WPFMISTBISOFileName.Text
        ISOFilePath      = $WPFMISTBFilePath.Text
        UpgradePackageCB = $WPFMISCBUpgradePackage.IsChecked
        UpgradePackPath  = $WPFMISTBUpgradePackage.Text
        IncludeOptionCB  = $WPFUpdatesOptionalEnableCheckBox.IsChecked
    }

    if ($CM -eq $False){

    Update-Log -data "Saving configuration file $filename" -Class Information

    try 
        {
        $CurrentConfig | Export-Clixml -Path $PSScriptRoot\Configs\$filename -ErrorAction Stop
        update-log -data "file saved" -Class Information
        }
        catch {
        Update-Log -data "Couldn't save file" -Class Error 
    }
    }
    else
        {
        Update-Log -data "Saving ConfigMgr Image info for Package $filename" -Class Information

        $CurrentConfig.CMPackageID = $filename
        $CurrentConfig.CMImageType = "Update Existing Image"

        $CurrentConfig.CMImageType

        if ((test-path -Path $PSScriptRoot\ConfigMgr\PackageInfo) -eq $False){
            Update-Log -Data "Creating ConfigMgr Package Info folder..." -Class Information
        
            try
            {
            New-Item -ItemType Directory -path $PSScriptRoot\ConfigMgr\PackageInfo -ErrorAction Stop
            }
            catch
            {
            update-log -Data "Couldn't create the folder. Likely a permission issue" -Class Error
            }
        }
    try {
        $CurrentConfig | Export-Clixml -Path $PSScriptRoot\ConfigMgr\PackageInfo\$filename -Force -ErrorAction Stop
        update-log -data "file saved" -Class Information
        }
    catch {
        Update-Log -data "Couldn't save file" -Class Error 
        }
    }
}

#Function to import configurations from file
function load-config($filename) {
    update-log -data "Importing config from $filename" -Class Information
    try {
        $settings = Import-Clixml -Path $filename -ErrorAction Stop
        update-log -data "Config file read..." -Class Information
        $WPFSourceWIMSelectWIMTextBox.text = $settings.SourcePath
        $WPFSourceWimIndexTextBox.text = $settings.SourceIndex
        $WPFSourceWIMImgDesTextBox.text = $settings.SourceEdition
        $WPFUpdatesEnableCheckBox.IsChecked = $settings.UpdatesEnabled
        $WPFJSONEnableCheckBox.IsChecked = $settings.AutopilotEnabled
        $WPFJSONTextBox.text = $settings.AutopilotPath 
        $WPFDriverCheckBox.IsChecked = $settings.DriversEnabled
        $WPFDriverDir1TextBox.text = $settings.DriverPath1
        $WPFDriverDir2TextBox.text = $settings.DriverPath2
        $WPFDriverDir3TextBox.text = $settings.DriverPath3
        $WPFDriverDir4TextBox.text = $settings.DriverPath4
        $WPFDriverDir5TextBox.text = $settings.DriverPath5
        $WPFAppxCheckBox.IsChecked = $settings.AppxIsEnabled
        $WPFAppxTextBox.text = $settings.AppxSelected -split " "
        $WPFMISWimNameTextBox.text = $settings.WIMName
        $WPFMISWimFolderTextBox.text = $settings.WIMPath
        $WPFMISMountTextBox.text = $settings.MountPath
        $global:SelectedAppx = $settings.AppxSelected -split " "
        $WPFMISDotNetCheckBox.IsChecked = $settings.DotNetEnabled
        $WPFMISOneDriveCheckBox.IsChecked = $settings.OneDriveEnabled
        $WPFCustomCBLangPacks.IsChecked = $settings.LPsEnabled
        $WPFCustomCBLEP.IsChecked = $settings.LXPsEnabled  
        $WPFCustomCBFOD.IsChecked = $settings.FODsEnabled

        $WPFMISCBPauseMount.IsChecked = $settings.PauseAfterMount 
        $WPFMISCBPauseDismount.IsChecked = $settings.PauseBeforeDM  
        $WPFCustomCBRunScript.IsChecked = $settings.RunScript    
        $WPFCustomCBScriptTiming.SelectedItem = $settings.ScriptTiming   
        $WPFCustomTBFile.Text = $settings.ScriptFile  
        $WPFCustomTBParameters.Text = $settings.ScriptParams  
        $WPFCMCBImageType.SelectedItem = $settings.CMImageType  
        $WPFCMTBPackageID.Text = $settings.CMPackageID   
        $WPFCMTBImageName.Text = $settings.CMImageName  
        $WPFCMTBImageVer.Text = $settings.CMVersion     
        $WPFCMTBDescription.Text = $settings.CMDescription 
        $WPFCMCBBinDirRep.IsChecked = $settings.CMBinDifRep  
        $WPFCMTBSitecode.Text = $settings.CMSiteCode     
        $WPFCMTBSiteServer.Text = $settings.CMSiteServer 
        $WPFCMCBDPDPG.SelectedItem = $settings.CMDPGroup    
        $WPFUSCBSelectCatalogSource.SelectedItem = $settings.UpdateSource 
        $WPFMISCBCheckForUpdates.IsChecked = $settings.UpdateMIS
        
        $WPFCMCBImageVerAuto.IsChecked = $settings.AutoFillVersion
        $WPFCMCBDescriptionAuto.IsChecked = $settings.AutoFillDesc

        $WPFCustomCBEnableApp.IsChecked = $settings.DefaultAppCB
        $WPFCustomTBDefaultApp.Text = $settings.DefaultAppPath 
        $WPFCustomCBEnableStart.IsChecked = $settings.StartMenuCB 
        $WPFCustomTBStartMenu.Text = $settings.StartMenuPath 
        $WPFCustomCBEnableRegistry.IsChecked = $settings.RegFilesCB 
        $WPFUpdatesCBEnableOptional.IsChecked = $settings.SUOptional 
        $WPFUpdatesCBEnableDynamic.IsChecked = $settings.SUDynamic
        
        $WPFMISCBDynamicUpdates.IsChecked = $settings.ApplyDynamicCB
        $WPFMISCBBootWIM.IsChecked = $settings.UpdateBootCB     
        $WPFMISCBNoWIM.IsChecked = $settings.DoNotCreateWIMCB 
        $WPFMISCBISO.IsChecked = $settings.CreateISO        
        $WPFMISTBISOFileName.Text = $settings.ISOFileName      
        $WPFMISTBFilePath.Text = $settings.ISOFilePath      
        $WPFMISCBUpgradePackage.IsChecked = $settings.UpgradePackageCB 
        $WPFMISTBUpgradePackage.Text = $settings.UpgradePackPath  
        $WPFUpdatesOptionalEnableCheckBox.IsChecked = $settings.IncludeOptionCB          
        
        $LEPs =  $settings.LPListBox
        $LXPs =  $settings.LXPListBox
        $FODs =  $settings.FODListBox
        $DPs = $settings.CMDPList     
        $REGs = $settings.RegFilesLB
            


        update-log -data "Configration set" -class Information

        update-log -data "Clearing list boxes..." -Class Information
        $WPFCustomLBLangPacks.Items.Clear()
        $WPFCustomLBLEP.Items.Clear()
        $WPFCustomLBFOD.Items.Clear()
        $WPFCMLBDPs.Items.Clear()
        $WPFCustomLBRegistry.Items.Clear()


        update-log -data "Populating list boxes..." -class Information
        foreach ($LEP in $LEPs){$WPFCustomLBLangPacks.Items.Add($LEP) | out-null}
        foreach ($LXP in $LXPs){$WPFCustomLBLEP.Items.Add($LXP) | out-null}
        foreach ($FOD in $FODs){$WPFCustomLBFOD.Items.Add($FOD) | out-null}
        foreach ($DP in $DPs){$WPFCMLBDPs.Items.Add($DP) | Out-null}
        foreach ($REG in $REGs){$WPFCustomLBRegistry.Items.Add($REG) | Out-null}


        import-wiminfo -IndexNumber $WPFSourceWimIndexTextBox.text

        if ($WPFJSONEnableCheckBox.IsChecked -eq $true) {
            
            Parse-JSON -file $WPFJSONTextBox.text 
        }

        if ($WPFCMCBImageType.SelectedItem -eq "Update Existing Image") {get-imageinfo -PackID $settings.CMPackageID}

        reset-MISCheckBox
        
    }

    catch
    { update-log -data "Could not import from $filename" -Class Error }

    invoke-checkboxcleanup
    Update-Log -data "Config file loaded successfully" -Class Information
}

#Function to select configuration file
Function select-config {
    $SourceXML = New-Object System.Windows.Forms.OpenFileDialog -Property @{ 
        InitialDirectory = "$PSScriptRoot\Configs"
        Filter           = 'XML (*.XML)|'
    }
    $null = $SourceXML.ShowDialog()
    $WPFSLLoadTextBox.text = $SourceXML.FileName
    load-config -filename $WPFSLLoadTextBox.text
}

#Function to reset reminder values from check boxes on the MIS tab when loading a config
function reset-MISCheckBox {
    update-log -data "Refreshing MIS Values..." -class Information

    If ($WPFJSONEnableCheckBox.IsChecked -eq $true) {
        $WPFJSONButton.IsEnabled = $True
        $WPFMISJSONTextBox.Text = "True"
    }
    If ($WPFDriverCheckBox.IsChecked -eq $true) {
        $WPFDriverDir1Button.IsEnabled = $True
        $WPFDriverDir2Button.IsEnabled = $True
        $WPFDriverDir3Button.IsEnabled = $True
        $WPFDriverDir4Button.IsEnabled = $True
        $WPFDriverDir5Button.IsEnabled = $True
        $WPFMISDriverTextBox.Text = "True"
    }
    If ($WPFUpdatesEnableCheckBox.IsChecked -eq $true) {
        $WPFMISUpdatesTextBox.Text = "True"
    }
    If ($WPFAppxCheckBox.IsChecked -eq $true) {
        $WPFAppxButton.IsEnabled = $True
        $WPFMISAppxTextBox.Text = "True"
    }
    If ($WPFCustomCBEnableApp.IsChecked -eq $true){$WPFCustomBDefaultApp.IsEnabled = $True}
    If ($WPFCustomCBEnableStart.IsChecked -eq $true){$WPFCustomBStartMenu.IsEnabled = $True}
    If ($WPFCustomCBEnableRegistry.IsChecked -eq $true){
        $WPFCustomBRegistryAdd.IsEnabled = $True
        $WPFCustomBRegistryRemove.IsEnabled = $True
        }

}

#Function to run WIM Witch from a config file
function run-configfile($filename) {
    Update-Log -Data "Loading the config file: $filename" -Class Information
    load-config -filename $filename 
    Update-Log -Data "Starting auto mode with the config file $filename" -Class Information
    MakeItSo -appx $global:SelectedAppx 
}

#Function to display text on closing of the script or wpf window
function display-closingtext {
    #Before you start bitching about write-host, write-output doesn't work with the exiting function. Suggestions are welcome.
    Write-Host " " 
    Write-Host "##########################################################"
    Write-Host " "
    Write-Host "Thank you for using WIM Witch. If you have any questions,"
    Write-Host "comments, or suggestions, please reach out to me!"
    Write-Host " "
    Write-Host "-Donna Ryan" 
    Write-Host " "
    Write-Host "twitter: @TheNotoriousDRR"
    Write-Host "www.MSEndpointmgr.com"
    Write-Host "www.TheNotoriousDRR.com"
    Write-Host " "
    Write-Host "##########################################################"
    if ($HiHungryImDad -eq $true){
        Write-Host " "
        Write-Host (invoke-dadjoke)
        Write-Host " "
        Write-Host "##########################################################"
        }
}

#Function to display opening text
function display-openingtext {
    cls
    Write-Output "##########################################################"
    Write-Output " "
    Write-Output " ***** Starting WIM Witch *****"
    Write-Output " version $WWScriptVer"
    Write-Output " "
    Write-Output "##########################################################"
    Write-Output " "
}

#Function to check suitability of the proposed mount point folder
function check-mountpath {
    param(
        [parameter(mandatory = $true, HelpMessage = "mount path")] 
        $path,

        [parameter(mandatory = $false, HelpMessage = "clear out the crapola")] 
        [ValidateSet($true)]
        $clean
    )


    $IsMountPoint = $null
    $HasFiles = $null
    $currentmounts = get-windowsimage -Mounted

    foreach ($currentmount in $currentmounts) {
        if ($currentmount.path -eq $path) { $IsMountPoint = $true } 
    }
  
    if ($IsMountPoint -eq $null) {
        if ( (Get-ChildItem $path | Measure-Object).Count -gt 0) {
            $HasFiles = $true
        }
    }

    if ($HasFiles -eq $true) {
        Update-Log -Data "Folder is not empty" -Class Warning
        if ($clean -eq $true) {
            try {
                Update-Log -Data "Cleaning folder..." -Class Warning
                Remove-Item -Path $path\* -Recurse -Force -ErrorAction Stop
                Update-Log -Data "$path cleared" -Class Warning
            }
        
            catch {
                Update-Log -Data "Couldn't delete contents of $path" -Class Error
                Update-Log -Data "Select a different folder to continue." -Class Error
                return
            }
        }
    }

    if ($IsMountPoint -eq $true) {
        Update-Log -Data "$path is currently a mount point" -Class Warning
        if (($IsMountPoint -eq $true) -and ($clean -eq $true)) {
          
            try {
                Update-Log -Data "Attempting to dismount image from mount point" -Class Warning
                Dismount-WindowsImage -Path $path -Discard | Out-Null -ErrorAction Stop
                $IsMountPoint = $null
                Update-Log -Data "Dismounting was successful" -Class Warning
            }   
            
            catch {
                Update-Log -Data "Couldn't completely dismount the folder. Ensure" -Class Error
                update-log -data "all connections to the path are closed, then try again" -Class Error
                return
            }
        }
    }
    if (($IsMountPoint -eq $null) -and ($HasFiles -eq $null)) { 
        Update-Log -Data "$path is suitable for mounting" -Class Information }
}

#Function to check the name of the target file and remediate if necessary
function check-name {
    Param( 
        [parameter(mandatory = $false, HelpMessage = "what to do")] 
        [ValidateSet("stop", "append", "backup", "overwrite")] 
        $conflict = "stop"
    )

    If ($WPFMISWimNameTextBox.Text -like "*.wim") {
        #$WPFLogging.Focus()
        #update-log -Data "New WIM name is valid" -Class Information
    }

    If ($WPFMISWimNameTextBox.Text -notlike "*.wim") {

        $WPFMISWimNameTextBox.Text = $WPFMISWimNameTextBox.Text + ".wim"
        update-log -Data "Appending new file name with an extension" -Class Information
    }

    $WIMpath = $WPFMISWimFolderTextBox.text + "\" + $WPFMISWimNameTextBox.Text
    $FileCheck = Test-Path -Path $WIMpath


    #append,overwrite,stop

    if ($FileCheck -eq $false) { update-log -data "Target WIM file name not in use. Continuing..." -class Information }
    else {
        if ($conflict -eq "append") {
            $renamestatus = (replace-name -file $WIMpath -extension ".wim")
            if ($renamestatus -eq "stop") { return "stop" }
        }
        if ($conflict -eq "overwrite") {
            Write-Host "overwrite action"
            return
        }
        if ($conflict -eq "stop") {
            $string = $WPFMISWimNameTextBox.Text + " already exists. Rename the target WIM and try again"
            update-log -Data $string -Class Warning
            return "stop"
        }
    }
    update-log -Data "New WIM name is valid" -Class Information
}

#Function to rename existing target wim file if the target WIM name already exists
function replace-name($file, $extension) {
    $text = "Renaming existing " + $extension + " file..."
    Update-Log -Data $text -Class Warning
    $filename = (Split-Path -leaf $file)
    $dateinfo = (get-item -Path $file).LastWriteTime -replace (" ", "_") -replace ("/", "_") -replace (":", "_")
    $filename = $filename -replace ($extension, "")
    $filename = $filename + $dateinfo + $extension
    try {
        rename-Item -Path $file -NewName $filename -ErrorAction Stop
        $text = $file + " has been renamed to " + $filename
        Update-Log -Data $text -Class Warning    
    }
    catch {
        Update-Log -data "Couldn't rename file. Stopping..." -force -Class Error
        return "stop"
    }
} 

#Function to see if the folder WIM Witch was started in is an installation folder. If not, prompt for installation
function check-install {

    function select-installfolder {
        $installselect = New-Object System.Windows.Forms.FolderBrowserDialog
        $installselect.Description = "Select the installation folder"
        $null = $installselect.ShowDialog()

        if ($installselect.SelectedPath -eq "") {
            write-output "User Cancelled or invalid entry"
            exit 0
        }

        return $installselect.SelectedPath
    }

    function install-wimwitch {
        Write-Output "Would you like to install WIM Witch here?"
        $yesno = Read-Host -Prompt "(Y/N)"
        Write-Output $yesno
        if (($yesno -ne "Y") -and ($yesno -ne "N")) {
            Write-Output "Invalid entry, try again."
            install-wimwitch
        }

        if (($yesno -eq "y") -and ($PSScriptRoot -notlike "*WindowsPowerShell\Scripts*")){
            foreach ($subfolder in $subfolders) {
                New-Item -Path $subfolder -ItemType Directory | Out-Null
                Write-Output "Created folder: $subfolder"
            }
        }
        if (($yesno -eq "y") -and ($PSScriptRoot -like "*WindowsPowerShell\Scripts*")){
            Write-Output " "
            write-output "You cannot install WIM Witch in the script repository folder."
            Write-Output "Also, you probably shouldn't install this in My Downloads, or My Desktop"
            write-output "Please select another folder"
            $yesno = "n"

        }
        if ($yesno -eq "n") {
            Write-Output "Select an installation folder"
            $installpath = select-installfolder
            
            if ($installpath -like "*WindowsPowerShell\Scripts*"){
                Write-Output "You cannot install WIM Witch in the script repository folder"
                Write-Output "Exiting installer. Please try again"
                exit 0
                }

            Write-Output "Installing WIM Witch in: $installpath"
            Copy-Item -Path $MyInvocation.ScriptName -Destination $installpath -Force
            Write-Output "WIM Witch script copied to installation path"
            Set-Location -Path $installpath
            foreach ($subfolder in $subfolders) {

                if ((Test-Path -Path "$subfolder") -eq $true) { Write-Host "$subfolder exists" }
                if ((Test-Path -Path "$subfolder") -eq $false) {
                    New-Item -Path $subfolder -ItemType Directory | out-null
                    Write-Output "Created folder: $subfolder"
                } 
            }
                
            Write-Output "============================================="
            Write-Output "WIM Witch has been installed to $installpath"
            Write-Output "Start WIM witch from that folder to continue."
            Write-Output " "
            Write-Output "Exiting..."
            break
        }
     }

    $subfolders = @(
        "CompletedWIMs"
        "Configs"      
        "drivers"      
        "jobs"         
        "logging"      
        "Mount"        
        "Staging"      
        "updates"
        "imports"
        "imports\WIM"
        "imports\DotNet"
        "Autopilot"
        "backup" 
    )

# if ((Get-WmiObject win32_operatingsystem).version -like '10.0.*') { Write-Output "WIM Witch is running on a supported OS" }
# else {
# Write-Output "Current OS not supported"
# Write-Output "Please run WIM Witch on Windows 10 / Server 2016+"
# exit 0
   

    $count = $null
    set-location -path $PSScriptRoot
    Write-Output "WIM Witch starting in $PSScriptRoot"
    Write-Output "Checking for installation status"
    foreach ($subfolder in $subfolders) {
        if ((Test-Path -Path .\$subfolder) -eq $true) { $count = $count + 1 }
    }

    if ($count -eq $null) {
        Write-Output "WIM Witch does not appear to be installed in this location."
        install-wimwitch
    }
    if ($count -ne $null) {
        Write-Output "WIM Witch is installed"
        Write-Output "Remediating for missing folders if they exist"
        foreach ($subfolder in $subfolders) {

            if ((Test-Path -Path "$subfolder") -eq $false) {
                New-Item -Path $subfolder -ItemType Directory | Out-Null
                Write-Output "Created folder: $subfolder"
            }
        }      
        write-output "Preflight complete. Starting WIM Witch"
    }
}

#Function to import WIM and .Net binaries from an iso file
#function import-iso($file, $type, $newname) {
function import-iso{

    function set-version($wimversion) {
        if ($wimversion -like '10.0.16299.*') { $version = "1709" }
        if ($wimversion -like '10.0.17134.*') { $version = "1803" }
        if ($wimversion -like '10.0.17763.*') { $version = "1809" }
        if ($wimversion -like '10.0.18362.*') { $version = "1903" }
        if ($wimversion -like '10.0.14393.*') { $version = "1607" }
        if ($wimversion -like '10.0.19041.*') { $version = "2004" }
        if ($wimversion -like '10.0.22000.*') { $version = "21H2" }
        if ($wimversion -like '10.0.20348.*') { $version = "21H2" }

        return $version
    }
 
    $newname = $WPFImportNewNameTextBox.Text
    $file = $WPFImportISOTextBox.Text
 
    #Check to see if destination WIM already exists

    if ($WPFImportWIMCheckBox.IsChecked -eq $true){
        update-log -data "Checking to see if the destination WIM file exists..." -Class Information    
        #check to see if the new name for the imported WIM is valid
        if (($WPFImportNewNameTextBox.Text -eq "") -or ($WPFImportNewNameTextBox.Text -eq "Name for the imported WIM")) {
            update-log -Data "Enter a valid file name for the imported WIM and then try again" -Class Error
            return 
        }

        If ($newname -notlike "*.wim") {
            $newname = $newname + ".wim"
            update-log -Data "Appending new file name with an extension" -Class Information
        }
    
        if ((Test-Path -Path $PSScriptRoot\Imports\WIM\$newname) -eq $true) {
            Update-Log -Data "Destination WIM name already exists. Provide a new name and try again." -Class Error
            return
        }
        else {
            update-log -Data "Name appears to be good. Continuing..." -Class Information
        }
    }

    #Mount ISO
    Update-Log -Data "Mounting ISO..." -Class Information
    try {
        $isomount = Mount-DiskImage -ImagePath $file -PassThru -NoDriveLetter -ErrorAction Stop
        $iso = $isomount.devicepath
        
    } catch {
        Update-Log -Data "Could not mount the ISO! Stopping actions..." -Class Error
        return
    }
    if(-not(Test-Path -Path (Join-Path $iso "\sources\"))){
        Update-Log -Data "Could not access the mounted ISO! Stopping actions..." -Class Error
        try {
            invoke-removeISOmount -inputObject $isomount
        } catch {
            Update-Log -Data "Attempted to dismount iso - might have failed..." -Class Warning
        }
        return
    }
    Update-Log -Data "$isomount" -Class Information
    #Testing for ESD or WIM format
    if(Test-Path -Path (Join-Path $iso "\sources\install.wim")){
        $installWimFound = $true
    } elseif(Test-Path -Path (Join-Path $iso "\sources\install.esd")){
        $installEsdFound = $true
        update-log -data "Found ESD type installer - attempting to convert to WIM." -Class Information
    } else {
        update-log -data "Error accessing install.wim or install.esd! Breaking" -Class Warning
        try {
            invoke-removeISOmount -inputObject $isomount
        } catch {
            Update-Log -Data "Attempted to dismount iso - might have failed..." -Class Warning
        }
        return
    }

    try {
        if($installWimFound) {
            $windowsver = Get-WindowsImage -ImagePath (Join-Path $iso "\sources\install.wim") -Index 1 -ErrorAction Stop
        } elseif ($installEsdFound) {
            $windowsver = Get-WindowsImage -ImagePath (Join-Path $iso "\sources\install.esd") -Index 1 -ErrorAction Stop
        }    
        $version = set-version -wimversion $windowsver.version
    if ($version -eq 1903){
        $Vardate = (Get-Date -Year 2019 -Month 10 -Day 01)
        if ($windowsver.CreatedTime -gt $vardate){$version = 1909}
        }

    if ($version -eq 2004){
        $Vardate = (Get-Date -Year 2020 -Month 09 -Day 01)
        if ($windowsver.CreatedTime -gt $vardate){$version = 2009}
        }
    } catch {
        update-log -data "install.wim could not be found or accessed! Skipping..." -Class Warning
        $installWimFound = $false
    }
    

    #Copy out WIM file
    #if (($type -eq "all") -or ($type -eq "wim")) {
        if (($WPFImportWIMCheckBox.IsChecked -eq $true) -and (($installWimFound) -or ($installEsdFound))){

        #Copy out the WIM file from the selected ISO
        try {
            update-log -data "Purging staging folder..." -Class Information
            Remove-Item -Path $PSScriptRoot\staging\*.* -Force
            update-log -data "Purge complete." -Class Information
            if($installWimFound){
            Update-Log -Data "Copying WIM file to the staging folder..." -Class Information    
            Copy-Item -Path $iso\sources\install.wim -Destination $PSScriptRoot\staging -Force -ErrorAction Stop -PassThru
            } 
        }
        catch {
            Update-Log -data "Couldn't copy from the source" -Class Error
            invoke-removeISOmount -inputObject $isomount
            return
        }
    
                #convert the ESD file to WIM
                if ($installEsdFound){
                    $sourceEsdFile = (Join-Path $iso "\sources\install.esd")
                    Update-Log -Data "Assessing install.esd file..." -Class Information
                    $indexesFound = Get-WindowsImage -ImagePath $sourceEsdFile
                    Update-Log -Data "$($indexesFound.Count) indexes found for conversion..." -Class Information
                    foreach ($index in $indexesFound) {
                        try{
                            Update-Log -Data "Converting index $($index.ImageIndex) - $($index.ImageName)" -Class Information
                            Export-WindowsImage -SourceImagePath $sourceEsdFile -SourceIndex $($index.ImageIndex) -DestinationImagePath (join-path $PSScriptRoot "\staging\install.wim") -CompressionType fast -ErrorAction Stop
                        } catch {
                            Update-Log -Data "Converting index $($index.ImageIndex) failed - skipping..." -Class Error
                            continue
                        }
                    }
                }

        #Change file attribute to normal
        Update-Log -Data "Setting file attribute of install.wim to Normal" -Class Information
        $attrib = Get-Item $PSScriptRoot\staging\install.wim
        $attrib.Attributes = 'Normal'
     
        #Rename install.wim to the new name
        try {
            $text = "Renaming install.wim to " + $newname
            Update-Log -Data $text -Class Information
            Rename-Item -Path $PSScriptRoot\Staging\install.wim -NewName $newname -ErrorAction Stop
        }
        catch {
            Update-Log -data "Couldn't rename the copied file. Most likely a weird permissions issues." -Class Error
            invoke-removeISOmount -inputObject $isomount
            return
        }
    
        #Move the imported WIM to the imports folder
    
        try {
            Update-Log -data "Moving $newname to imports folder..." -Class Information
            Move-Item -Path $PSScriptRoot\Staging\$newname -Destination $PSScriptRoot\Imports\WIM -ErrorAction Stop
        }
        catch {
            Update-Log -Data "Couldn't move the new WIM to the staging folder." -Class Error
            invoke-removeISOmount -inputObject $isomount
            return
        }
        update-log -data "WIM importation complete" -Class Information
    }
 
    #Copy DotNet binaries

    if ($WPFImportDotNetCheckBox.IsChecked -eq $true){
 

 If (($windowsver.imagename -like '*Windows 10*') -or (($windowsver.imagename -like '*server') -and ($windowsver.version -lt 10.0.20248.0))) {$Path = "$PSScriptRoot\Imports\DotNet\$version"}
 If (($windowsver.Imagename -like '*server*') -and ($windowsver.version -gt 10.0.20348.0)){$Path = "$PSScriptRoot\Imports\Dotnet\Windows Server\$version"}
 If ($windowsver.imagename -like '*Windows 11*')  {$Path = "$PSScriptRoot\Imports\Dotnet\Windows 11\$version"}
 
 
        if ((Test-Path -Path $Path) -eq $false) {

            try {
                Update-Log -Data "Creating folders..." -Class Warning
    
                New-Item -Path (split-path -path $path -Parent) -Name $version -ItemType Directory -ErrorAction stop | Out-Null 

            }
            catch {
                Update-Log -Data "Couldn't creating new folder in DotNet imports folder" -Class Error
                return
            }
        }
       

        try {
            Update-Log -Data "Copying .Net binaries..." -Class Information
            Copy-Item -Path $iso\sources\sxs\*netfx3* -Destination $path -Force -ErrorAction Stop

        }
        catch {
            Update-Log -Data "Couldn't copy the .Net binaries" -Class Error
            return
        }
    }

    #Copy out ISO files
    if ($WPFImportISOCheckBox.IsChecked -eq $true){
        #Determine if is Windows 10 or Windows Server
        update-log -Data "Importing ISO/Upgrade Package files..." -Class Information
        if ($windowsver.ImageName -like 'Windows 10*'){
            $OS = "Windows 10"
                #gets a file count of the ISO to determine if 200Xvs21XX
                
             if (( Get-ChildItem ($iso + '\') -Recurse -File | Measure-Object | %{$_.Count}) -eq 905){ $version = "21H1"}
                ###Ping
               
            }
 
        if ($windowsver.ImageName -like 'Windows 11*'){$OS = "Windows 11"}
 
        if ($windowsver.ImageName -like '*Server*'){$OS = "Windows Server"}
        update-log -Data "$OS detected" -Class Information
        if ((Test-Path -Path $PSScriptRoot\imports\iso\$OS\$Version) -eq $false){
            update-log -Data "Path does not exist. Creating..." -Class Information
            new-item -Path $PSScriptRoot\imports\iso\$OS\ -Name $version -ItemType Directory}
        
        update-log -Data "Copying boot folder..." -Class Information
        Copy-Item -Path $iso\boot\ -Destination $PSScriptRoot\imports\iso\$OS\$Version\boot -Recurse -force #-Exclude install.wim
        
        update-log -Data "Copying efi folder..." -Class Information
        Copy-Item -Path $iso\efi\ -Destination $PSScriptRoot\imports\iso\$OS\$Version\efi -Recurse -force #-Exclude install.wim
        
        update-log -Data "Copying sources folder..." -Class Information
        Copy-Item -Path $iso\sources\ -Destination $PSScriptRoot\imports\iso\$OS\$Version\sources -Recurse -force -Exclude install.wim
        
        update-log -Data "Copying support folder..." -Class Information
        Copy-Item -Path $iso\support\ -Destination $PSScriptRoot\imports\iso\$OS\$Version\support -Recurse -force #-Exclude install.wim
        
        update-log -Data "Copying files in root folder..." -Class Information
        copy-item $iso\autorun.inf -Destination $PSScriptRoot\imports\iso\$OS\$Version\ -force
        copy-item $iso\bootmgr -Destination $PSScriptRoot\imports\iso\$OS\$Version\ -force
        copy-item $iso\bootmgr.efi -Destination $PSScriptRoot\imports\iso\$OS\$Version\ -force
        copy-item $iso\setup.exe -Destination $PSScriptRoot\imports\iso\$OS\$Version\ -force
         
    }
    
    #Dismount and finish
    try {
        Update-Log -Data "Dismount!" -Class Information
        invoke-removeISOmount -inputObject $isomount
        }
    catch {
        Update-Log -Data "Couldn't dismount the ISO. WIM Witch uses a file mount option that does not" -Class Error
        Update-Log -Data "provision a drive letter. Use the Dismount-DiskImage command to manaully dismount." -Class Error
    }
    update-log -data "Importing complete" -class Information
}

#function to select ISO for import
function select-iso {

    $SourceISO = New-Object System.Windows.Forms.OpenFileDialog -Property @{ 
        InitialDirectory = [Environment]::GetFolderPath('Desktop') 
        Filter           = 'ISO (*.iso)|'
    }
    $null = $SourceISO.ShowDialog()
    $WPFImportISOTextBox.text = $SourceISO.FileName


    if ($SourceISO.FileName -notlike "*.iso") {
        update-log -Data "An ISO file not selected. Please select a valid file to continue." -Class Warning
        return
    }
    $text = $WPFImportISOTextBox.text + " selected as the ISO to import from"
    Update-Log -Data $text -class Information
}

#function to inject the .Net 3.5 binaries from the import folder
function inject-dotnet {


    $buildnum = get-winvernum
    $OSType = get-windowstype

    #fix the build number 21h

     if ($OSType -eq "Windows 10"){$DotNetFiles = "$PSScriptRoot\imports\DotNet\$buildnum"}
     if (($OSType -eq "Windows 11") -or ($OSType -eq "Windows Server")){$DotNetFiles = "$PSScriptRoot\imports\DotNet\$OSType\$buildnum"}


    try {
        $text = "Injecting .Net 3.5 binaries from " + $DotNetFiles
        Update-Log -Data $text -Class Information
        Add-WindowsPackage -PackagePath $DotNetFiles -Path $WPFMISMountTextBox.Text -ErrorAction Continue | Out-Null
    }
    catch {
        Update-Log -Data "Couldn't inject .Net Binaries" -Class Warning
        return
    } 
    Update-Log -Data ".Net 3.5 injection complete" -Class Information
}

#function to see if the .Net binaries for the select Win10 version exist
function check-dotnetexists {

    $buildnum = get-winvernum
    $OSType = get-windowstype

    if ($OSType -eq "Windows 10"){$DotNetFiles = "$PSScriptRoot\imports\DotNet\$buildnum"}
    if (($OSType -eq "Windows 11") -or ($OSType -eq "Windows Server")) {$DotNetFiles = "$PSScriptRoot\imports\DotNet\$OSType\$buildnum"}

    Test-Path -Path $DotNetFiles\* 
    if ((Test-Path -Path $DotNetFiles\*) -eq $false) {
        $text = ".Net 3.5 Binaries are not present for " + $buildnum
        update-log -Data $text -Class Warning
        update-log -data "Import .Net from an ISO or disable injection to continue" -Class Warning
        return $false
    }
}

#For those who like to dig through code and find notes from the dev team:
#Each function is listed in the order it was created. This point marks
#where v1.0 was released. Everything
#below is from updates -DRR 10/22/2020

#Function to check installed version of WIM Witch and update if available
Function Check-WIMWitchVer{

    function upgrade-wimwitch {
        Write-Output "Would you like to upgrade WIM Witch?"
        $yesno = Read-Host -Prompt "(Y/N)"
        Write-Output $yesno
        if (($yesno -ne "Y") -and ($yesno -ne "N")) {
            Write-Output "Invalid entry, try again."
            upgrade-wimwitch
        }

        if ($yesno -eq "y") {
           Backup-WIMWitch
 
            try{
                Save-Script -Name "WIMWitch" -Path $PSScriptRoot -Force -ErrorAction Stop
                Write-Output "New version has been applied. WIM Witch will now exit."
                Write-Output "Please restart WIM Witch"
                exit}
            catch{
                Write-Output "Couldn't upgrade. Try again when teh tubes are clear"
                return}
           
            }
        
               
        if ($yesno -eq "n") {
            Write-Output "You'll want to upgrade at some point."
            Update-Log -Data "Upgrade to new version was declined" -Class Warning
            Update-Log -Data "Continuing to start WIM Witch..." -Class Warning
            }
  
    }
    
Update-Log -Data "The currently installed version of WIM Witch is $WWScriptVer" -Class Information
Update-Log -data "Checking for updates from PowerShell Gallery..." -Class Information


try{
    $WWCurrentVer = (Find-Script -Name "WIMWitch" -ErrorAction Stop).version 
    Update-Log -Data "The latest version from the Gallery is $WWCurrentVer" -Class Information
    }
catch{
    Update-Log -Data "Couldn't retreive script info from the PowerShell Gallery" -Class Warning
    Update-Log -data "Try rebooting the internet and trying again" -Class Warning
    Update-Log -data "Continuing on with loading WIM Witch..." -Class Warning
    return
    }


If (($WWCurrentVer -gt $WWScriptVer) -and ($auto -eq $false)){upgrade-wimwitch}
if (($WWCurrentVer -gt $WWScriptVer) -and ($auto -eq $true)){update-log -data "Skipping WIM Witch upgrade because she is in auto-mode. Please launch WIM Witch in GUI mode to update." -class warning} 
If ($WWCurrentVer -eq $WWScriptVer){Update-Log -data "WIM Witch is up to date. Starting WIM Witch" -Class Information}
If ($WWCurrentVer -lt $WWScriptVer){
    Update-Log -Data "The local copy of WIM Witch is more current that the most current" -class Warning
    Update-Log -Data "version available. Did you violate the Temporal Prime Directive?" -class Warning
    Update-Log -data "Starting WIM Witch anyway..." -class warning

    }

}

#Function to backup WIM Witch script file during upgrade
function Backup-WIMWitch{
Update-log -data "Backing up existing WIM Witch script..." -Class Information

$scriptname = split-path $MyInvocation.PSCommandPath -Leaf #Find local script name
Update-Log -data "The script to be backed up is: " -Class Information
Update-Log -data $MyInvocation.PSCommandPath -Class Information

try{
    Update-Log -data "Copy script to backup folder..." -Class Information
    Copy-Item -Path $scriptname -Destination $PSScriptRoot\backup -ErrorAction Stop
    Update-Log -Data "Successfully copied..." -Class Information
    }
catch{
    Update-Log -data "Couldn't copy the WIM Witch script. My guess is a permissions issue" -Class Error
    Update-Log -Data "Exiting out of an over abundance of caution" -Class Error
    exit
}

try {
    Update-Log -data "Renaming archived script..." -Class Information
    replace-name -file $PSScriptRoot\backup\$scriptname -extension ".ps1"
    Update-Log -data "Backup successfully renamed for archiving" -class Information
    }
catch {

    Update-Log -Data "Backed-up script couldn't be renamed. This isn't a critical error" -Class Warning
    Update-Log -Data "You may want to change it's name so it doesn't get overwritten." -Class Warning
    Update-Log -Data "Continuing with WIM Witch upgrade..." -Class Warning
    }
}

#Function to download current OneDrive client
#Most of this was stolen from David Segura @SeguraOSD
function download-onedrive{
    update-log -Data "Donwloading latest OneDrive agent installer..." -class Information
    $DownloadUrl = 'https://go.microsoft.com/fwlink/p/?LinkId=248256'
    $DownloadPath = "$PSScriptRoot\updates\OneDrive"
    $DownloadFile = 'OneDriveSetup.exe'

    if (!(Test-Path "$DownloadPath")) {New-Item -Path $DownloadPath -ItemType Directory -Force | Out-Null}
    Invoke-WebRequest -Uri $DownloadUrl -OutFile "$DownloadPath\$DownloadFile"
    if (Test-Path "$DownloadPath\$DownloadFile") {
        Update-Log -Data 'OneDrive Download Complete' -Class Information
        } else {
        Update-log -Data 'OneDrive could not be downloaded' -Class Error
    }
}

#function to copy new OneDrive client installer to mount path
function copy-onedrive{
  
    try{
    update-log -Data "Setting ACL on the original OneDriveSetup.exe file" -Class Information
    $mountpath = $WPFMISMountTextBox.text

    $AclBAK = Get-Acl "$mountpath\Windows\SysWOW64\OneDriveSetup.exe"
    $user = $env:USERDOMAIN + '\' + $env:USERNAME   
    $Account = New-Object -TypeName System.Security.Principal.NTAccount -ArgumentList $user
    $item = Get-Item "$mountpath\Windows\SysWOW64\OneDriveSetup.exe"
    
    $Acl = $null # Reset the $Acl variable to $null
    $Acl = Get-Acl -Path $Item.FullName # Get the ACL from the item
    $Acl.SetOwner($Account) # Update the in-memory ACL
    Set-Acl -Path $Item.FullName -AclObject $Acl -ErrorAction Stop  # Set the updated ACL on the target item
    update-log -Data "Ownership of OneDriveSetup.exe siezed" -Class Information

    $Ar = New-Object System.Security.AccessControl.FileSystemAccessRule($user, "FullControl", "Allow")
    $Acl.SetAccessRule($Ar)
    Set-Acl "$mountpath\Windows\SysWOW64\OneDriveSetup.exe" $Acl -ErrorAction Stop |out-null
    
    update-log -Data "ACL successfully updated. Continuing..."
    }
    catch{
    Update-Log -data "Couldn't set the ACL on the original file" -Class Error
    return
    } 
    
    try{
    
   
    Update-Log -data "Copying updated OneDrive agent installer..." -Class Information
    copy-item "$PSScriptRoot\updates\OneDrive\OneDriveSetup.exe" -Destination "$mountpath\Windows\SysWOW64" -Force -ErrorAction Stop
    Update-Log -Data "OneDrive installer successfully copied." -Class Information
    }
    catch{
    Update-Log -data "Couldn't copy the OneDrive installer file." -class Error
    Update-Log -data $_.Exception.Message -Class Error
    return
    }

    try{
    update-log -data "Restoring original ACL to OneDrive installer." -Class Information
    Set-Acl "$mountpath\Windows\SysWOW64\OneDriveSetup.exe" $AclBAK -ErrorAction Stop |out-null
    update-log -data "Restoration complete" -Class Information
    }
    catch{
    Update-Log "Couldn't restore original ACLs. Continuing." -Class Error
    }
}

#Function to call the next three functions. This determines WinOS and WinVer and calls the function
function select-LPFODCriteria($Type){

    if ($WPFSourceWIMImgDesTextBox.text -like '*10*'){$WinOS = "Windows 10"}
        Else
            {$WinOS = "Windows Server"}

    If ($WPFSourceWimVerTextBox.text -like "10.0.17763.*") { $WinVer = "1809" }
    If ($WPFSourceWimVerTextBox.text -like "10.0.19041.*") { $WinVer = "2004" }

    If ($WPFSourceWimVerTextBox.text -like "10.0.18362.*") {
        if ((get-windowsimage -ImagePath $WPFSourceWIMSelectWIMTextBox.text -Index 1).CreatedTime -gt (Get-Date -Year 2019 -Month 09 -Day 02)){$WinVer = "1909"}
            else{
           $WinVer = "1909"}
      }

    $WinOS = get-windowstype
    $WinVer = get-winvernum

    if ($WinOS -eq "Windows 10"){
        if (($Winver -eq "2009") -or ($winver -eq "20H2") -or ($winver -eq "21H1")) {$winver = "2004"} 
    }

    if ($type -eq "LP"){
        if ((test-path -Path $PSScriptRoot\imports\Lang\$WinOS\$Winver\LanguagePacks) -eq $false){
            update-log -Data "Source not found. Please import some language packs and try again" -Class Error
            return}
        select-LanguagePacks -winver $Winver -WinOS $WinOS
        }

    If ($type -eq "LXP"){
         if ((test-path -Path $PSScriptRoot\imports\Lang\$WinOS\$Winver\localexperiencepack) -eq $false){
            update-log -Data "Source not found. Please import some Local Experience Packs and try again" -Class Error
            return}
        select-localexperiencepack -winver $Winver -WinOS $WinOS}

    if ($type -eq "FOD"){
        if ((test-path -Path $PSScriptRoot\imports\FODs\$WinOS\$Winver\) -eq $false){
            
            update-log -Data "Source not found. Please import some Demanding Features and try again" -Class Error
            return}

    select-FODs -winver $Winver -WinOS $WinOS}
}

#Function to select langauge packs for injection
function select-LanguagePacks($winver,$WinOS){
    
    $LPSourceFolder = $PSScriptRoot + '\imports\lang\' + $WinOS + '\' + $winver + '\'+ 'LanguagePacks' + '\' 
    
    $items = (Get-ChildItem -path $LPSourceFolder | Select-Object -Property Name | Out-GridView -title "Select Language Packs" -PassThru)
    foreach ($item in $items){$WPFCustomLBLangPacks.Items.Add($item.name)}
}

#Function to select LXP packs for injection
function select-localexperiencepack($winver,$WinOS){
    
    $LPSourceFolder = $PSScriptRoot + '\imports\lang\' + $WinOS + '\' + $winver + '\'+ 'localexperiencepack' + '\' 
    

    $items = (Get-ChildItem -path $LPSourceFolder | Select-Object -Property Name | Out-GridView -title "Select Local Experience Packs" -PassThru)
    foreach ($item in $items){$WPFCustomLBLEP.Items.Add($item.name)}
}
#Hey Donna
#Function to select FODs for injection
function select-FODs($winver,$WinOS){
    $Win10_1909_FODs = @("Accessibility.Braille~~~~0.0.1.0",
"Analog.Holographic.Desktop~~~~0.0.1.0",
"App.Support.QuickAssist~~~~0.0.1.0",
"Browser.InternetExplorer~~~~0.0.11.0",
"Hello.Face.18330~~~~0.0.1.0",
"Hello.Face.Migration.18330~~~~0.0.1.0",
"Language.Basic~~~af-ZA~0.0.1.0",
"Language.Basic~~~ar-SA~0.0.1.0",
"Language.Basic~~~as-IN~0.0.1.0",
"Language.Basic~~~az-LATN-AZ~0.0.1.0",
"Language.Basic~~~ba-RU~0.0.1.0",
"Language.Basic~~~be-BY~0.0.1.0",
"Language.Basic~~~bg-BG~0.0.1.0",
"Language.Basic~~~bn-BD~0.0.1.0",
"Language.Basic~~~bn-IN~0.0.1.0",
"Language.Basic~~~bs-LATN-BA~0.0.1.0",
"Language.Basic~~~ca-ES~0.0.1.0",
"Language.Basic~~~cs-CZ~0.0.1.0",
"Language.Basic~~~cy-GB~0.0.1.0",
"Language.Basic~~~da-DK~0.0.1.0",
"Language.Basic~~~de-CH~0.0.1.0",
"Language.Basic~~~de-DE~0.0.1.0",
"Language.Basic~~~el-GR~0.0.1.0",
"Language.Basic~~~en-AU~0.0.1.0",
"Language.Basic~~~en-CA~0.0.1.0",
"Language.Basic~~~en-GB~0.0.1.0",
"Language.Basic~~~en-IN~0.0.1.0",
"Language.Basic~~~en-US~0.0.1.0",
"Language.Basic~~~es-ES~0.0.1.0",
"Language.Basic~~~es-MX~0.0.1.0",
"Language.Basic~~~es-US~0.0.1.0",
"Language.Basic~~~et-EE~0.0.1.0",
"Language.Basic~~~eu-ES~0.0.1.0",
"Language.Basic~~~fa-IR~0.0.1.0",
"Language.Basic~~~fi-FI~0.0.1.0",
"Language.Basic~~~fil-PH~0.0.1.0",
"Language.Basic~~~fr-BE~0.0.1.0",
"Language.Basic~~~fr-CA~0.0.1.0",
"Language.Basic~~~fr-CH~0.0.1.0",
"Language.Basic~~~fr-FR~0.0.1.0",
"Language.Basic~~~ga-IE~0.0.1.0",
"Language.Basic~~~gd-GB~0.0.1.0",
"Language.Basic~~~gl-ES~0.0.1.0",
"Language.Basic~~~gu-IN~0.0.1.0",
"Language.Basic~~~ha-LATN-NG~0.0.1.0",
"Language.Basic~~~haw-US~0.0.1.0",
"Language.Basic~~~he-IL~0.0.1.0",
"Language.Basic~~~hi-IN~0.0.1.0",
"Language.Basic~~~hr-HR~0.0.1.0",
"Language.Basic~~~hu-HU~0.0.1.0",
"Language.Basic~~~hy-AM~0.0.1.0",
"Language.Basic~~~id-ID~0.0.1.0",
"Language.Basic~~~ig-NG~0.0.1.0",
"Language.Basic~~~is-IS~0.0.1.0",
"Language.Basic~~~it-IT~0.0.1.0",
"Language.Basic~~~ja-JP~0.0.1.0",
"Language.Basic~~~ka-GE~0.0.1.0",
"Language.Basic~~~kk-KZ~0.0.1.0",
"Language.Basic~~~kl-GL~0.0.1.0",
"Language.Basic~~~kn-IN~0.0.1.0",
"Language.Basic~~~ko-KR~0.0.1.0",
"Language.Basic~~~kok-DEVA-IN~0.0.1.0",
"Language.Basic~~~ky-KG~0.0.1.0",
"Language.Basic~~~lb-LU~0.0.1.0",
"Language.Basic~~~lt-LT~0.0.1.0",
"Language.Basic~~~lv-LV~0.0.1.0",
"Language.Basic~~~mi-NZ~0.0.1.0",
"Language.Basic~~~mk-MK~0.0.1.0",
"Language.Basic~~~ml-IN~0.0.1.0",
"Language.Basic~~~mn-MN~0.0.1.0",
"Language.Basic~~~mr-IN~0.0.1.0",
"Language.Basic~~~ms-BN~0.0.1.0",
"Language.Basic~~~ms-MY~0.0.1.0",
"Language.Basic~~~mt-MT~0.0.1.0",
"Language.Basic~~~nb-NO~0.0.1.0",
"Language.Basic~~~ne-NP~0.0.1.0",
"Language.Basic~~~nl-NL~0.0.1.0",
"Language.Basic~~~nn-NO~0.0.1.0",
"Language.Basic~~~nso-ZA~0.0.1.0",
"Language.Basic~~~or-IN~0.0.1.0",
"Language.Basic~~~pa-IN~0.0.1.0",
"Language.Basic~~~pl-PL~0.0.1.0",
"Language.Basic~~~ps-AF~0.0.1.0",
"Language.Basic~~~pt-BR~0.0.1.0",
"Language.Basic~~~pt-PT~0.0.1.0",
"Language.Basic~~~rm-CH~0.0.1.0",
"Language.Basic~~~ro-RO~0.0.1.0",
"Language.Basic~~~ru-RU~0.0.1.0",
"Language.Basic~~~rw-RW~0.0.1.0",
"Language.Basic~~~sah-RU~0.0.1.0",
"Language.Basic~~~si-LK~0.0.1.0",
"Language.Basic~~~sk-SK~0.0.1.0",
"Language.Basic~~~sl-SI~0.0.1.0",
"Language.Basic~~~sq-AL~0.0.1.0",
"Language.Basic~~~sr-CYRL-RS~0.0.1.0",
"Language.Basic~~~sr-LATN-RS~0.0.1.0",
"Language.Basic~~~sv-SE~0.0.1.0",
"Language.Basic~~~sw-KE~0.0.1.0",
"Language.Basic~~~ta-IN~0.0.1.0",
"Language.Basic~~~te-IN~0.0.1.0",
"Language.Basic~~~tg-CYRL-TJ~0.0.1.0",
"Language.Basic~~~th-TH~0.0.1.0",
"Language.Basic~~~tk-TM~0.0.1.0",
"Language.Basic~~~tn-ZA~0.0.1.0",
"Language.Basic~~~tr-TR~0.0.1.0",
"Language.Basic~~~tt-RU~0.0.1.0",
"Language.Basic~~~ug-CN~0.0.1.0",
"Language.Basic~~~uk-UA~0.0.1.0",
"Language.Basic~~~ur-PK~0.0.1.0",
"Language.Basic~~~uz-LATN-UZ~0.0.1.0",
"Language.Basic~~~vi-VN~0.0.1.0",
"Language.Basic~~~wo-SN~0.0.1.0",
"Language.Basic~~~xh-ZA~0.0.1.0",
"Language.Basic~~~yo-NG~0.0.1.0",
"Language.Basic~~~zh-CN~0.0.1.0",
"Language.Basic~~~zh-HK~0.0.1.0",
"Language.Basic~~~zh-TW~0.0.1.0",
"Language.Basic~~~zu-ZA~0.0.1.0",
"Language.Fonts.Arab~~~und-ARAB~0.0.1.0",
"Language.Fonts.Beng~~~und-BENG~0.0.1.0",
"Language.Fonts.Cans~~~und-CANS~0.0.1.0",
"Language.Fonts.Cher~~~und-CHER~0.0.1.0",
"Language.Fonts.Deva~~~und-DEVA~0.0.1.0",
"Language.Fonts.Ethi~~~und-ETHI~0.0.1.0",
"Language.Fonts.Gujr~~~und-GUJR~0.0.1.0",
"Language.Fonts.Guru~~~und-GURU~0.0.1.0",
"Language.Fonts.Hans~~~und-HANS~0.0.1.0",
"Language.Fonts.Hant~~~und-HANT~0.0.1.0",
"Language.Fonts.Hebr~~~und-HEBR~0.0.1.0",
"Language.Fonts.Jpan~~~und-JPAN~0.0.1.0",
"Language.Fonts.Khmr~~~und-KHMR~0.0.1.0",
"Language.Fonts.Knda~~~und-KNDA~0.0.1.0",
"Language.Fonts.Kore~~~und-KORE~0.0.1.0",
"Language.Fonts.Laoo~~~und-LAOO~0.0.1.0",
"Language.Fonts.Mlym~~~und-MLYM~0.0.1.0",
"Language.Fonts.Orya~~~und-ORYA~0.0.1.0",
"Language.Fonts.PanEuropeanSupplementalFonts~~~~0.0.1.0",
"Language.Fonts.Sinh~~~und-SINH~0.0.1.0",
"Language.Fonts.Syrc~~~und-SYRC~0.0.1.0",
"Language.Fonts.Taml~~~und-TAML~0.0.1.0",
"Language.Fonts.Telu~~~und-TELU~0.0.1.0",
"Language.Fonts.Thai~~~und-THAI~0.0.1.0",
"Language.Handwriting~~~af-ZA~0.0.1.0",
"Language.Handwriting~~~bs-LATN-BA~0.0.1.0",
"Language.Handwriting~~~ca-ES~0.0.1.0",
"Language.Handwriting~~~cs-CZ~0.0.1.0",
"Language.Handwriting~~~cy-GB~0.0.1.0",
"Language.Handwriting~~~da-DK~0.0.1.0",
"Language.Handwriting~~~de-DE~0.0.1.0",
"Language.Handwriting~~~el-GR~0.0.1.0",
"Language.Handwriting~~~en-GB~0.0.1.0",
"Language.Handwriting~~~en-US~0.0.1.0",
"Language.Handwriting~~~es-ES~0.0.1.0",
"Language.Handwriting~~~es-MX~0.0.1.0",
"Language.Handwriting~~~eu-ES~0.0.1.0",
"Language.Handwriting~~~fi-FI~0.0.1.0",
"Language.Handwriting~~~fr-FR~0.0.1.0",
"Language.Handwriting~~~ga-IE~0.0.1.0",
"Language.Handwriting~~~gd-GB~0.0.1.0",
"Language.Handwriting~~~gl-ES~0.0.1.0",
"Language.Handwriting~~~hi-IN~0.0.1.0",
"Language.Handwriting~~~hr-HR~0.0.1.0",
"Language.Handwriting~~~id-ID~0.0.1.0",
"Language.Handwriting~~~it-IT~0.0.1.0",
"Language.Handwriting~~~ja-JP~0.0.1.0",
"Language.Handwriting~~~ko-KR~0.0.1.0",
"Language.Handwriting~~~lb-LU~0.0.1.0",
"Language.Handwriting~~~mi-NZ~0.0.1.0",
"Language.Handwriting~~~ms-BN~0.0.1.0",
"Language.Handwriting~~~ms-MY~0.0.1.0",
"Language.Handwriting~~~nb-NO~0.0.1.0",
"Language.Handwriting~~~nl-NL~0.0.1.0",
"Language.Handwriting~~~nn-NO~0.0.1.0",
"Language.Handwriting~~~nso-ZA~0.0.1.0",
"Language.Handwriting~~~pl-PL~0.0.1.0",
"Language.Handwriting~~~pt-BR~0.0.1.0",
"Language.Handwriting~~~pt-PT~0.0.1.0",
"Language.Handwriting~~~rm-CH~0.0.1.0",
"Language.Handwriting~~~ro-RO~0.0.1.0",
"Language.Handwriting~~~ru-RU~0.0.1.0",
"Language.Handwriting~~~rw-RW~0.0.1.0",
"Language.Handwriting~~~sk-SK~0.0.1.0",
"Language.Handwriting~~~sl-SI~0.0.1.0",
"Language.Handwriting~~~sq-AL~0.0.1.0",
"Language.Handwriting~~~sr-CYRL-RS~0.0.1.0",
"Language.Handwriting~~~sr-LATN-RS~0.0.1.0",
"Language.Handwriting~~~sv-SE~0.0.1.0",
"Language.Handwriting~~~sw-KE~0.0.1.0",
"Language.Handwriting~~~tn-ZA~0.0.1.0",
"Language.Handwriting~~~tr-TR~0.0.1.0",
"Language.Handwriting~~~wo-SN~0.0.1.0",
"Language.Handwriting~~~xh-ZA~0.0.1.0",
"Language.Handwriting~~~zh-CN~0.0.1.0",
"Language.Handwriting~~~zh-HK~0.0.1.0",
"Language.Handwriting~~~zh-TW~0.0.1.0",
"Language.Handwriting~~~zu-ZA~0.0.1.0",
"Language.OCR~~~ar-SA~0.0.1.0",
"Language.OCR~~~bg-BG~0.0.1.0",
"Language.OCR~~~bs-LATN-BA~0.0.1.0",
"Language.OCR~~~cs-CZ~0.0.1.0",
"Language.OCR~~~da-DK~0.0.1.0",
"Language.OCR~~~de-DE~0.0.1.0",
"Language.OCR~~~el-GR~0.0.1.0",
"Language.OCR~~~en-GB~0.0.1.0",
"Language.OCR~~~en-US~0.0.1.0",
"Language.OCR~~~es-ES~0.0.1.0",
"Language.OCR~~~es-MX~0.0.1.0",
"Language.OCR~~~fi-FI~0.0.1.0",
"Language.OCR~~~fr-CA~0.0.1.0",
"Language.OCR~~~fr-FR~0.0.1.0",
"Language.OCR~~~hr-HR~0.0.1.0",
"Language.OCR~~~hu-HU~0.0.1.0",
"Language.OCR~~~it-IT~0.0.1.0",
"Language.OCR~~~ja-JP~0.0.1.0",
"Language.OCR~~~ko-KR~0.0.1.0",
"Language.OCR~~~nb-NO~0.0.1.0",
"Language.OCR~~~nl-NL~0.0.1.0",
"Language.OCR~~~pl-PL~0.0.1.0",
"Language.OCR~~~pt-BR~0.0.1.0",
"Language.OCR~~~pt-PT~0.0.1.0",
"Language.OCR~~~ro-RO~0.0.1.0",
"Language.OCR~~~ru-RU~0.0.1.0",
"Language.OCR~~~sk-SK~0.0.1.0",
"Language.OCR~~~sl-SI~0.0.1.0",
"Language.OCR~~~sr-CYRL-RS~0.0.1.0",
"Language.OCR~~~sr-LATN-RS~0.0.1.0",
"Language.OCR~~~sv-SE~0.0.1.0",
"Language.OCR~~~tr-TR~0.0.1.0",
"Language.OCR~~~zh-CN~0.0.1.0",
"Language.OCR~~~zh-HK~0.0.1.0",
"Language.OCR~~~zh-TW~0.0.1.0",
"Language.Speech~~~da-DK~0.0.1.0",
"Language.Speech~~~de-DE~0.0.1.0",
"Language.Speech~~~en-AU~0.0.1.0",
"Language.Speech~~~en-CA~0.0.1.0",
"Language.Speech~~~en-GB~0.0.1.0",
"Language.Speech~~~en-IN~0.0.1.0",
"Language.Speech~~~en-US~0.0.1.0",
"Language.Speech~~~es-ES~0.0.1.0",
"Language.Speech~~~es-MX~0.0.1.0",
"Language.Speech~~~fr-CA~0.0.1.0",
"Language.Speech~~~fr-FR~0.0.1.0",
"Language.Speech~~~it-IT~0.0.1.0",
"Language.Speech~~~ja-JP~0.0.1.0",
"Language.Speech~~~pt-BR~0.0.1.0",
"Language.Speech~~~zh-CN~0.0.1.0",
"Language.Speech~~~zh-HK~0.0.1.0",
"Language.Speech~~~zh-TW~0.0.1.0",
"Language.TextToSpeech~~~ar-EG~0.0.1.0",
"Language.TextToSpeech~~~ar-SA~0.0.1.0",
"Language.TextToSpeech~~~bg-BG~0.0.1.0",
"Language.TextToSpeech~~~ca-ES~0.0.1.0",
"Language.TextToSpeech~~~cs-CZ~0.0.1.0",
"Language.TextToSpeech~~~da-DK~0.0.1.0",
"Language.TextToSpeech~~~de-AT~0.0.1.0",
"Language.TextToSpeech~~~de-CH~0.0.1.0",
"Language.TextToSpeech~~~de-DE~0.0.1.0",
"Language.TextToSpeech~~~el-GR~0.0.1.0",
"Language.TextToSpeech~~~en-AU~0.0.1.0",
"Language.TextToSpeech~~~en-CA~0.0.1.0",
"Language.TextToSpeech~~~en-GB~0.0.1.0",
"Language.TextToSpeech~~~en-IE~0.0.1.0",
"Language.TextToSpeech~~~en-IN~0.0.1.0",
"Language.TextToSpeech~~~en-US~0.0.1.0",
"Language.TextToSpeech~~~es-ES~0.0.1.0",
"Language.TextToSpeech~~~es-MX~0.0.1.0",
"Language.TextToSpeech~~~fi-FI~0.0.1.0",
"Language.TextToSpeech~~~fr-CA~0.0.1.0",
"Language.TextToSpeech~~~fr-CH~0.0.1.0",
"Language.TextToSpeech~~~fr-FR~0.0.1.0",
"Language.TextToSpeech~~~he-IL~0.0.1.0",
"Language.TextToSpeech~~~hi-IN~0.0.1.0",
"Language.TextToSpeech~~~hr-HR~0.0.1.0",
"Language.TextToSpeech~~~hu-HU~0.0.1.0",
"Language.TextToSpeech~~~id-ID~0.0.1.0",
"Language.TextToSpeech~~~it-IT~0.0.1.0",
"Language.TextToSpeech~~~ja-JP~0.0.1.0",
"Language.TextToSpeech~~~ko-KR~0.0.1.0",
"Language.TextToSpeech~~~ms-MY~0.0.1.0",
"Language.TextToSpeech~~~nb-NO~0.0.1.0",
"Language.TextToSpeech~~~nl-BE~0.0.1.0",
"Language.TextToSpeech~~~nl-NL~0.0.1.0",
"Language.TextToSpeech~~~pl-PL~0.0.1.0",
"Language.TextToSpeech~~~pt-BR~0.0.1.0",
"Language.TextToSpeech~~~pt-PT~0.0.1.0",
"Language.TextToSpeech~~~ro-RO~0.0.1.0",
"Language.TextToSpeech~~~ru-RU~0.0.1.0",
"Language.TextToSpeech~~~sk-SK~0.0.1.0",
"Language.TextToSpeech~~~sl-SI~0.0.1.0",
"Language.TextToSpeech~~~sv-SE~0.0.1.0",
"Language.TextToSpeech~~~ta-IN~0.0.1.0",
"Language.TextToSpeech~~~th-TH~0.0.1.0",
"Language.TextToSpeech~~~tr-TR~0.0.1.0",
"Language.TextToSpeech~~~vi-VN~0.0.1.0",
"Language.TextToSpeech~~~zh-CN~0.0.1.0",
"Language.TextToSpeech~~~zh-HK~0.0.1.0",
"Language.TextToSpeech~~~zh-TW~0.0.1.0",
"MathRecognizer~~~~0.0.1.0",
"Media.WindowsMediaPlayer~~~~0.0.12.0",
"Microsoft.Onecore.StorageManagement~~~~0.0.1.0",
"Microsoft.WebDriver~~~~0.0.1.0",
"Microsoft.Windows.StorageManagement~~~~0.0.1.0",
"Msix.PackagingTool.Driver~~~~0.0.1.0",
"NetFX3~~~~",
"Network.Irda~~~~0.0.1.0",
"OneCoreUAP.OneSync~~~~0.0.1.0",
"OpenSSH.Client~~~~0.0.1.0",
"OpenSSH.Server~~~~0.0.1.0",
"RasCMAK.Client~~~~0.0.1.0",
"RIP.Listener~~~~0.0.1.0",
"Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0",
"Rsat.BitLocker.Recovery.Tools~~~~0.0.1.0",
"Rsat.CertificateServices.Tools~~~~0.0.1.0",
"Rsat.DHCP.Tools~~~~0.0.1.0",
"Rsat.Dns.Tools~~~~0.0.1.0",
"Rsat.FailoverCluster.Management.Tools~~~~0.0.1.0",
"Rsat.FileServices.Tools~~~~0.0.1.0",
"Rsat.GroupPolicy.Management.Tools~~~~0.0.1.0",
"Rsat.IPAM.Client.Tools~~~~0.0.1.0",
"Rsat.LLDP.Tools~~~~0.0.1.0",
"Rsat.NetworkController.Tools~~~~0.0.1.0",
"Rsat.NetworkLoadBalancing.Tools~~~~0.0.1.0",
"Rsat.RemoteAccess.Management.Tools~~~~0.0.1.0",
"Rsat.RemoteDesktop.Services.Tools~~~~0.0.1.0",
"Rsat.ServerManager.Tools~~~~0.0.1.0",
"Rsat.Shielded.VM.Tools~~~~0.0.1.0",
"Rsat.StorageMigrationService.Management.Tools~~~~0.0.1.0",
"Rsat.StorageReplica.Tools~~~~0.0.1.0",
"Rsat.SystemInsights.Management.Tools~~~~0.0.1.0",
"Rsat.VolumeActivation.Tools~~~~0.0.1.0",
"Rsat.WSUS.Tools~~~~0.0.1.0",
"SNMP.Client~~~~0.0.1.0",
"Tools.DeveloperMode.Core~~~~0.0.1.0",
"Tools.DTrace.Platform~~~~0.0.1.0",
"Tools.Graphics.DirectX~~~~0.0.1.0",
"WMI-SNMP-Provider.Client~~~~0.0.1.0",
"XPS.Viewer~~~~0.0.1.0")
    $Win10_1903_FODs = @("Accessibility.Braille~~~~0.0.1.0",
"Analog.Holographic.Desktop~~~~0.0.1.0",
"App.Support.QuickAssist~~~~0.0.1.0",
"Browser.InternetExplorer~~~~0.0.11.0",
"Hello.Face.17658~~~~0.0.1.0",
"Hello.Face.Migration.17658~~~~0.0.1.0",
"Language.Basic~~~af-ZA~0.0.1.0",
"Language.Basic~~~ar-SA~0.0.1.0",
"Language.Basic~~~as-IN~0.0.1.0",
"Language.Basic~~~az-LATN-AZ~0.0.1.0",
"Language.Basic~~~ba-RU~0.0.1.0",
"Language.Basic~~~be-BY~0.0.1.0",
"Language.Basic~~~bg-BG~0.0.1.0",
"Language.Basic~~~bn-BD~0.0.1.0",
"Language.Basic~~~bn-IN~0.0.1.0",
"Language.Basic~~~bs-LATN-BA~0.0.1.0",
"Language.Basic~~~ca-ES~0.0.1.0",
"Language.Basic~~~cs-CZ~0.0.1.0",
"Language.Basic~~~cy-GB~0.0.1.0",
"Language.Basic~~~da-DK~0.0.1.0",
"Language.Basic~~~de-DE~0.0.1.0",
"Language.Basic~~~el-GR~0.0.1.0",
"Language.Basic~~~en-GB~0.0.1.0",
"Language.Basic~~~en-US~0.0.1.0",
"Language.Basic~~~es-ES~0.0.1.0",
"Language.Basic~~~es-MX~0.0.1.0",
"Language.Basic~~~et-EE~0.0.1.0",
"Language.Basic~~~eu-ES~0.0.1.0",
"Language.Basic~~~fa-IR~0.0.1.0",
"Language.Basic~~~fi-FI~0.0.1.0",
"Language.Basic~~~fil-PH~0.0.1.0",
"Language.Basic~~~fr-CA~0.0.1.0",
"Language.Basic~~~fr-FR~0.0.1.0",
"Language.Basic~~~ga-IE~0.0.1.0",
"Language.Basic~~~gd-GB~0.0.1.0",
"Language.Basic~~~gl-ES~0.0.1.0",
"Language.Basic~~~gu-IN~0.0.1.0",
"Language.Basic~~~ha-LATN-NG~0.0.1.0",
"Language.Basic~~~haw-US~0.0.1.0",
"Language.Basic~~~he-IL~0.0.1.0",
"Language.Basic~~~hi-IN~0.0.1.0",
"Language.Basic~~~hr-HR~0.0.1.0",
"Language.Basic~~~hu-HU~0.0.1.0",
"Language.Basic~~~hy-AM~0.0.1.0",
"Language.Basic~~~id-ID~0.0.1.0",
"Language.Basic~~~ig-NG~0.0.1.0",
"Language.Basic~~~is-IS~0.0.1.0",
"Language.Basic~~~it-IT~0.0.1.0",
"Language.Basic~~~ja-JP~0.0.1.0",
"Language.Basic~~~ka-GE~0.0.1.0",
"Language.Basic~~~kk-KZ~0.0.1.0",
"Language.Basic~~~kl-GL~0.0.1.0",
"Language.Basic~~~kn-IN~0.0.1.0",
"Language.Basic~~~ko-KR~0.0.1.0",
"Language.Basic~~~kok-DEVA-IN~0.0.1.0",
"Language.Basic~~~ky-KG~0.0.1.0",
"Language.Basic~~~lb-LU~0.0.1.0",
"Language.Basic~~~lt-LT~0.0.1.0",
"Language.Basic~~~lv-LV~0.0.1.0",
"Language.Basic~~~mi-NZ~0.0.1.0",
"Language.Basic~~~ml-IN~0.0.1.0",
"Language.Basic~~~mk-MK~0.0.1.0",
"Language.Basic~~~mn-MN~0.0.1.0",
"Language.Basic~~~mr-IN~0.0.1.0",
"Language.Basic~~~ms-BN~0.0.1.0",
"Language.Basic~~~ms-MY~0.0.1.0",
"Language.Basic~~~mt-MT~0.0.1.0",
"Language.Basic~~~nb-NO~0.0.1.0",
"Language.Basic~~~ne-NP~0.0.1.0",
"Language.Basic~~~nl-NL~0.0.1.0",
"Language.Basic~~~nn-NO~0.0.1.0",
"Language.Basic~~~nso-ZA~0.0.1.0",
"Language.Basic~~~or-IN~0.0.1.0",
"Language.Basic~~~pa-IN~0.0.1.0",
"Language.Basic~~~pl-PL~0.0.1.0",
"Language.Basic~~~ps-AF~0.0.1.0",
"Language.Basic~~~pt-BR~0.0.1.0",
"Language.Basic~~~pt-PT~0.0.1.0",
"Language.Basic~~~rm-CH~0.0.1.0",
"Language.Basic~~~ro-RO~0.0.1.0",
"Language.Basic~~~ru-RU~0.0.1.0",
"Language.Basic~~~rw-RW~0.0.1.0",
"Language.Basic~~~sah-RU~0.0.1.0",
"Language.Basic~~~si-LK~0.0.1.0",
"Language.Basic~~~sk-SK~0.0.1.0",
"Language.Basic~~~sl-SI~0.0.1.0",
"Language.Basic~~~sq-AL~0.0.1.0",
"Language.Basic~~~sr-CYRL-RS~0.0.1.0",
"Language.Basic~~~sr-LATN-RS~0.0.1.0",
"Language.Basic~~~sv-SE~0.0.1.0",
"Language.Basic~~~sw-KE~0.0.1.0",
"Language.Basic~~~ta-IN~0.0.1.0",
"Language.Basic~~~te-IN~0.0.1.0",
"Language.Basic~~~tg-CYRL-TJ~0.0.1.0",
"Language.Basic~~~th-TH~0.0.1.0",
"Language.Basic~~~tk-TM~0.0.1.0",
"Language.Basic~~~tn-ZA~0.0.1.0",
"Language.Basic~~~tr-TR~0.0.1.0",
"Language.Basic~~~tt-RU~0.0.1.0",
"Language.Basic~~~ug-CN~0.0.1.0",
"Language.Basic~~~uk-UA~0.0.1.0",
"Language.Basic~~~ur-PK~0.0.1.0",
"Language.Basic~~~uz-LATN-UZ~0.0.1.0",
"Language.Basic~~~vi-VN~0.0.1.0",
"Language.Basic~~~wo-SN~0.0.1.0",
"Language.Basic~~~xh-ZA~0.0.1.0",
"Language.Basic~~~yo-NG~0.0.1.0",
"Language.Basic~~~zh-CN~0.0.1.0",
"Language.Basic~~~zh-HK~0.0.1.0",
"Language.Basic~~~zh-TW~0.0.1.0",
"Language.Basic~~~zu-ZA~0.0.1.0",
"Language.Fonts.Arab~~~und-ARAB~0.0.1.0",
"Language.Fonts.Beng~~~und-BENG~0.0.1.0",
"Language.Fonts.Cans~~~und-CANS~0.0.1.0",
"Language.Fonts.Cher~~~und-CHER~0.0.1.0",
"Language.Fonts.Deva~~~und-DEVA~0.0.1.0",
"Language.Fonts.Ethi~~~und-ETHI~0.0.1.0",
"Language.Fonts.Gujr~~~und-GUJR~0.0.1.0",
"Language.Fonts.Guru~~~und-GURU~0.0.1.0",
"Language.Fonts.Hans~~~und-HANS~0.0.1.0",
"Language.Fonts.Hant~~~und-HANT~0.0.1.0",
"Language.Fonts.Hebr~~~und-HEBR~0.0.1.0",
"Language.Fonts.Jpan~~~und-JPAN~0.0.1.0",
"Language.Fonts.Khmr~~~und-KHMR~0.0.1.0",
"Language.Fonts.Knda~~~und-KNDA~0.0.1.0",
"Language.Fonts.Kore~~~und-KORE~0.0.1.0",
"Language.Fonts.Laoo~~~und-LAOO~0.0.1.0",
"Language.Fonts.Mlym~~~und-MLYM~0.0.1.0",
"Language.Fonts.Orya~~~und-ORYA~0.0.1.0",
"Language.Fonts.PanEuropeanSupplementalFonts~~~~0.0.1.0",
"Language.Fonts.Sinh~~~und-SINH~0.0.1.0",
"Language.Fonts.Syrc~~~und-SYRC~0.0.1.0",
"Language.Fonts.Taml~~~und-TAML~0.0.1.0",
"Language.Fonts.Telu~~~und-TELU~0.0.1.0",
"Language.Fonts.Thai~~~und-THAI~0.0.1.0",
"Language.Handwriting~~~af-ZA~0.0.1.0",
"Language.Handwriting~~~bs-LATN-BA~0.0.1.0",
"Language.Handwriting~~~ca-ES~0.0.1.0",
"Language.Handwriting~~~cs-CZ~0.0.1.0",
"Language.Handwriting~~~cy-GB~0.0.1.0",
"Language.Handwriting~~~da-DK~0.0.1.0",
"Language.Handwriting~~~de-DE~0.0.1.0",
"Language.Handwriting~~~el-GR~0.0.1.0",
"Language.Handwriting~~~en-GB~0.0.1.0",
"Language.Handwriting~~~en-US~0.0.1.0",
"Language.Handwriting~~~es-ES~0.0.1.0",
"Language.Handwriting~~~es-MX~0.0.1.0",
"Language.Handwriting~~~eu-ES~0.0.1.0",
"Language.Handwriting~~~fi-FI~0.0.1.0",
"Language.Handwriting~~~fr-FR~0.0.1.0",
"Language.Handwriting~~~ga-IE~0.0.1.0",
"Language.Handwriting~~~gd-GB~0.0.1.0",
"Language.Handwriting~~~gl-ES~0.0.1.0",
"Language.Handwriting~~~hi-IN~0.0.1.0",
"Language.Handwriting~~~hr-HR~0.0.1.0",
"Language.Handwriting~~~id-ID~0.0.1.0",
"Language.Handwriting~~~it-IT~0.0.1.0",
"Language.Handwriting~~~ja-JP~0.0.1.0",
"Language.Handwriting~~~ko-KR~0.0.1.0",
"Language.Handwriting~~~lb-LU~0.0.1.0",
"Language.Handwriting~~~mi-NZ~0.0.1.0",
"Language.Handwriting~~~ms-BN~0.0.1.0",
"Language.Handwriting~~~ms-MY~0.0.1.0",
"Language.Handwriting~~~nb-NO~0.0.1.0",
"Language.Handwriting~~~nl-NL~0.0.1.0",
"Language.Handwriting~~~nn-NO~0.0.1.0",
"Language.Handwriting~~~nso-ZA~0.0.1.0",
"Language.Handwriting~~~pl-PL~0.0.1.0",
"Language.Handwriting~~~pt-BR~0.0.1.0",
"Language.Handwriting~~~pt-PT~0.0.1.0",
"Language.Handwriting~~~rm-CH~0.0.1.0",
"Language.Handwriting~~~ro-RO~0.0.1.0",
"Language.Handwriting~~~ru-RU~0.0.1.0",
"Language.Handwriting~~~rw-RW~0.0.1.0",
"Language.Handwriting~~~sk-SK~0.0.1.0",
"Language.Handwriting~~~sl-SI~0.0.1.0",
"Language.Handwriting~~~sq-AL~0.0.1.0",
"Language.Handwriting~~~sr-CYRL-RS~0.0.1.0",
"Language.Handwriting~~~sr-LATN-RS~0.0.1.0",
"Language.Handwriting~~~sv-SE~0.0.1.0",
"Language.Handwriting~~~sw-KE~0.0.1.0",
"Language.Handwriting~~~tn-ZA~0.0.1.0",
"Language.Handwriting~~~tr-TR~0.0.1.0",
"Language.Handwriting~~~wo-SN~0.0.1.0",
"Language.Handwriting~~~xh-ZA~0.0.1.0",
"Language.Handwriting~~~zh-CN~0.0.1.0",
"Language.Handwriting~~~zh-HK~0.0.1.0",
"Language.Handwriting~~~zh-TW~0.0.1.0",
"Language.Handwriting~~~zu-ZA~0.0.1.0",
"Language.OCR~~~ar-SA~0.0.1.0",
"Language.OCR~~~bg-BG~0.0.1.0",
"Language.OCR~~~bs-LATN-BA~0.0.1.0",
"Language.OCR~~~cs-CZ~0.0.1.0",
"Language.OCR~~~da-DK~0.0.1.0",
"Language.OCR~~~de-DE~0.0.1.0",
"Language.OCR~~~el-GR~0.0.1.0",
"Language.OCR~~~en-GB~0.0.1.0",
"Language.OCR~~~en-US~0.0.1.0",
"Language.OCR~~~es-ES~0.0.1.0",
"Language.OCR~~~es-MX~0.0.1.0",
"Language.OCR~~~fi-FI~0.0.1.0",
"Language.OCR~~~fr-CA~0.0.1.0",
"Language.OCR~~~fr-FR~0.0.1.0",
"Language.OCR~~~hr-HR~0.0.1.0",
"Language.OCR~~~hu-HU~0.0.1.0",
"Language.OCR~~~it-IT~0.0.1.0",
"Language.OCR~~~ja-JP~0.0.1.0",
"Language.OCR~~~ko-KR~0.0.1.0",
"Language.OCR~~~nb-NO~0.0.1.0",
"Language.OCR~~~nl-NL~0.0.1.0",
"Language.OCR~~~pl-PL~0.0.1.0",
"Language.OCR~~~pt-BR~0.0.1.0",
"Language.OCR~~~pt-PT~0.0.1.0",
"Language.OCR~~~ro-RO~0.0.1.0",
"Language.OCR~~~ru-RU~0.0.1.0",
"Language.OCR~~~sk-SK~0.0.1.0",
"Language.OCR~~~sl-SI~0.0.1.0",
"Language.OCR~~~sr-CYRL-RS~0.0.1.0",
"Language.OCR~~~sr-LATN-RS~0.0.1.0",
"Language.OCR~~~sv-SE~0.0.1.0",
"Language.OCR~~~tr-TR~0.0.1.0",
"Language.OCR~~~zh-CN~0.0.1.0",
"Language.OCR~~~zh-HK~0.0.1.0",
"Language.OCR~~~zh-TW~0.0.1.0",
"Language.Speech~~~de-DE~0.0.1.0",
"Language.Speech~~~en-AU~0.0.1.0",
"Language.Speech~~~en-CA~0.0.1.0",
"Language.Speech~~~en-GB~0.0.1.0",
"Language.Speech~~~en-IN~0.0.1.0",
"Language.Speech~~~en-US~0.0.1.0",
"Language.Speech~~~es-ES~0.0.1.0",
"Language.Speech~~~es-MX~0.0.1.0",
"Language.Speech~~~fr-CA~0.0.1.0",
"Language.Speech~~~fr-FR~0.0.1.0",
"Language.Speech~~~it-IT~0.0.1.0",
"Language.Speech~~~ja-JP~0.0.1.0",
"Language.Speech~~~pt-BR~0.0.1.0",
"Language.Speech~~~zh-CN~0.0.1.0",
"Language.Speech~~~zh-HK~0.0.1.0",
"Language.Speech~~~zh-TW~0.0.1.0",
"Language.TextToSpeech~~~ar-EG~0.0.1.0",
"Language.TextToSpeech~~~ar-SA~0.0.1.0",
"Language.TextToSpeech~~~bg-BG~0.0.1.0",
"Language.TextToSpeech~~~ca-ES~0.0.1.0",
"Language.TextToSpeech~~~cs-CZ~0.0.1.0",
"Language.TextToSpeech~~~da-DK~0.0.1.0",
"Language.TextToSpeech~~~de-AT~0.0.1.0",
"Language.TextToSpeech~~~de-CH~0.0.1.0",
"Language.TextToSpeech~~~de-DE~0.0.1.0",
"Language.TextToSpeech~~~el-GR~0.0.1.0",
"Language.TextToSpeech~~~en-AU~0.0.1.0",
"Language.TextToSpeech~~~en-CA~0.0.1.0",
"Language.TextToSpeech~~~en-GB~0.0.1.0",
"Language.TextToSpeech~~~en-IE~0.0.1.0",
"Language.TextToSpeech~~~en-IN~0.0.1.0",
"Language.TextToSpeech~~~en-US~0.0.1.0",
"Language.TextToSpeech~~~es-ES~0.0.1.0",
"Language.TextToSpeech~~~es-MX~0.0.1.0",
"Language.TextToSpeech~~~fi-FI~0.0.1.0",
"Language.TextToSpeech~~~fr-CA~0.0.1.0",
"Language.TextToSpeech~~~fr-CH~0.0.1.0",
"Language.TextToSpeech~~~fr-FR~0.0.1.0",
"Language.TextToSpeech~~~he-IL~0.0.1.0",
"Language.TextToSpeech~~~hi-IN~0.0.1.0",
"Language.TextToSpeech~~~hr-HR~0.0.1.0",
"Language.TextToSpeech~~~hu-HU~0.0.1.0",
"Language.TextToSpeech~~~id-ID~0.0.1.0",
"Language.TextToSpeech~~~it-IT~0.0.1.0",
"Language.TextToSpeech~~~ja-JP~0.0.1.0",
"Language.TextToSpeech~~~ko-KR~0.0.1.0",
"Language.TextToSpeech~~~ms-MY~0.0.1.0",
"Language.TextToSpeech~~~nb-NO~0.0.1.0",
"Language.TextToSpeech~~~nl-BE~0.0.1.0",
"Language.TextToSpeech~~~nl-NL~0.0.1.0",
"Language.TextToSpeech~~~pl-PL~0.0.1.0",
"Language.TextToSpeech~~~pt-BR~0.0.1.0",
"Language.TextToSpeech~~~pt-PT~0.0.1.0",
"Language.TextToSpeech~~~ro-RO~0.0.1.0",
"Language.TextToSpeech~~~ru-RU~0.0.1.0",
"Language.TextToSpeech~~~sk-SK~0.0.1.0",
"Language.TextToSpeech~~~sl-SI~0.0.1.0",
"Language.TextToSpeech~~~sv-SE~0.0.1.0",
"Language.TextToSpeech~~~ta-IN~0.0.1.0",
"Language.TextToSpeech~~~th-TH~0.0.1.0",
"Language.TextToSpeech~~~tr-TR~0.0.1.0",
"Language.TextToSpeech~~~vi-VN~0.0.1.0",
"Language.TextToSpeech~~~zh-CN~0.0.1.0",
"Language.TextToSpeech~~~zh-HK~0.0.1.0",
"Language.TextToSpeech~~~zh-TW~0.0.1.0",
"MathRecognizer~~~~0.0.1.0",
"Media.WindowsMediaPlayer~~~~0.0.12.0",
"Microsoft.Onecore.StorageManagement~~~~0.0.1.0",
"Microsoft.WebDriver~~~~0.0.1.0",
"Microsoft.Windows.StorageManagement~~~~0.0.1.0",
"Msix.PackagingTool.Driver~~~~0.0.1.0",
"NetFX3~~~~",
"OneCoreUAP.OneSync~~~~0.0.1.0",
"OpenSSH.Client~~~~0.0.1.0",
"OpenSSH.Server~~~~0.0.1.0",
"RasCMAK.Client~~~~0.0.1.0",
"RIP.Listener~~~~0.0.1.0",
"Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0",
"Rsat.BitLocker.Recovery.Tools~~~~0.0.1.0",
"Rsat.CertificateServices.Tools~~~~0.0.1.0",
"Rsat.DHCP.Tools~~~~0.0.1.0",
"Rsat.Dns.Tools~~~~0.0.1.0",
"Rsat.FailoverCluster.Management.Tools~~~~0.0.1.0",
"Rsat.FileServices.Tools~~~~0.0.1.0",
"Rsat.GroupPolicy.Management.Tools~~~~0.0.1.0",
"Rsat.IPAM.Client.Tools~~~~0.0.1.0",
"Rsat.LLDP.Tools~~~~0.0.1.0",
"Rsat.NetworkController.Tools~~~~0.0.1.0",
"Rsat.NetworkLoadBalancing.Tools~~~~0.0.1.0",
"Rsat.RemoteAccess.Management.Tools~~~~0.0.1.0",
"Rsat.RemoteDesktop.Services.Tools~~~~0.0.1.0",
"Rsat.ServerManager.Tools~~~~0.0.1.0",
"Rsat.Shielded.VM.Tools~~~~0.0.1.0",
"Rsat.StorageMigrationService.Management.Tools~~~~0.0.1.0",
"Rsat.StorageReplica.Tools~~~~0.0.1.0",
"Rsat.SystemInsights.Management.Tools~~~~0.0.1.0",
"Rsat.VolumeActivation.Tools~~~~0.0.1.0",
"Rsat.WSUS.Tools~~~~0.0.1.0",
"SNMP.Client~~~~0.0.1.0",
"Tools.DeveloperMode.Core~~~~0.0.1.0",
"Tools.DTrace.Platform~~~~0.0.1.0",
"Tools.Graphics.DirectX~~~~0.0.1.0",
"WMI-SNMP-Provider.Client~~~~0.0.1.0",
"XPS.Viewer~~~~0.0.1.0")
    $Win10_1809_FODs = @("Accessibility.Braille~~~~0.0.1.0",
"Analog.Holographic.Desktop~~~~0.0.1.0",
"App.Support.QuickAssist~~~~0.0.1.0",
"Browser.InternetExplorer~~~~0.0.11.0",
"Hello.Face.17658~~~~0.0.1.0",
"Hello.Face.Migration.17658~~~~0.0.1.0",
"Language.Basic~~~af-ZA~0.0.1.0",
"Language.Basic~~~ar-SA~0.0.1.0",
"Language.Basic~~~as-IN~0.0.1.0",
"Language.Basic~~~az-LATN-AZ~0.0.1.0",
"Language.Basic~~~ba-RU~0.0.1.0",
"Language.Basic~~~be-BY~0.0.1.0",
"Language.Basic~~~bg-BG~0.0.1.0",
"Language.Basic~~~bn-BD~0.0.1.0",
"Language.Basic~~~bn-IN~0.0.1.0",
"Language.Basic~~~bs-LATN-BA~0.0.1.0",
"Language.Basic~~~ca-ES~0.0.1.0",
"Language.Basic~~~cs-CZ~0.0.1.0",
"Language.Basic~~~cy-GB~0.0.1.0",
"Language.Basic~~~da-DK~0.0.1.0",
"Language.Basic~~~de-DE~0.0.1.0",
"Language.Basic~~~el-GR~0.0.1.0",
"Language.Basic~~~en-GB~0.0.1.0",
"Language.Basic~~~en-US~0.0.1.0",
"Language.Basic~~~es-ES~0.0.1.0",
"Language.Basic~~~es-MX~0.0.1.0",
"Language.Basic~~~et-EE~0.0.1.0",
"Language.Basic~~~eu-ES~0.0.1.0",
"Language.Basic~~~fa-IR~0.0.1.0",
"Language.Basic~~~fi-FI~0.0.1.0",
"Language.Basic~~~fil-PH~0.0.1.0",
"Language.Basic~~~fr-CA~0.0.1.0",
"Language.Basic~~~fr-FR~0.0.1.0",
"Language.Basic~~~ga-IE~0.0.1.0",
"Language.Basic~~~gd-GB~0.0.1.0",
"Language.Basic~~~gl-ES~0.0.1.0",
"Language.Basic~~~gu-IN~0.0.1.0",
"Language.Basic~~~ha-LATN-NG~0.0.1.0",
"Language.Basic~~~haw-US~0.0.1.0",
"Language.Basic~~~he-IL~0.0.1.0",
"Language.Basic~~~hi-IN~0.0.1.0",
"Language.Basic~~~hr-HR~0.0.1.0",
"Language.Basic~~~hu-HU~0.0.1.0",
"Language.Basic~~~hy-AM~0.0.1.0",
"Language.Basic~~~id-ID~0.0.1.0",
"Language.Basic~~~ig-NG~0.0.1.0",
"Language.Basic~~~is-IS~0.0.1.0",
"Language.Basic~~~it-IT~0.0.1.0",
"Language.Basic~~~ja-JP~0.0.1.0",
"Language.Basic~~~ka-GE~0.0.1.0",
"Language.Basic~~~kk-KZ~0.0.1.0",
"Language.Basic~~~kl-GL~0.0.1.0",
"Language.Basic~~~kn-IN~0.0.1.0",
"Language.Basic~~~ko-KR~0.0.1.0",
"Language.Basic~~~kok-DEVA-IN~0.0.1.0",
"Language.Basic~~~ky-KG~0.0.1.0",
"Language.Basic~~~lb-LU~0.0.1.0",
"Language.Basic~~~lt-LT~0.0.1.0",
"Language.Basic~~~lv-LV~0.0.1.0",
"Language.Basic~~~mi-NZ~0.0.1.0",
"Language.Basic~~~ml-IN~0.0.1.0",
"Language.Basic~~~mk-MK~0.0.1.0",
"Language.Basic~~~mn-MN~0.0.1.0",
"Language.Basic~~~mr-IN~0.0.1.0",
"Language.Basic~~~ms-BN~0.0.1.0",
"Language.Basic~~~ms-MY~0.0.1.0",
"Language.Basic~~~mt-MT~0.0.1.0",
"Language.Basic~~~nb-NO~0.0.1.0",
"Language.Basic~~~ne-NP~0.0.1.0",
"Language.Basic~~~nl-NL~0.0.1.0",
"Language.Basic~~~nn-NO~0.0.1.0",
"Language.Basic~~~nso-ZA~0.0.1.0",
"Language.Basic~~~or-IN~0.0.1.0",
"Language.Basic~~~pa-IN~0.0.1.0",
"Language.Basic~~~pl-PL~0.0.1.0",
"Language.Basic~~~ps-AF~0.0.1.0",
"Language.Basic~~~pt-BR~0.0.1.0",
"Language.Basic~~~pt-PT~0.0.1.0",
"Language.Basic~~~rm-CH~0.0.1.0",
"Language.Basic~~~ro-RO~0.0.1.0",
"Language.Basic~~~ru-RU~0.0.1.0",
"Language.Basic~~~rw-RW~0.0.1.0",
"Language.Basic~~~sah-RU~0.0.1.0",
"Language.Basic~~~si-LK~0.0.1.0",
"Language.Basic~~~sk-SK~0.0.1.0",
"Language.Basic~~~sl-SI~0.0.1.0",
"Language.Basic~~~sq-AL~0.0.1.0",
"Language.Basic~~~sr-CYRL-RS~0.0.1.0",
"Language.Basic~~~sr-LATN-RS~0.0.1.0",
"Language.Basic~~~sv-SE~0.0.1.0",
"Language.Basic~~~sw-KE~0.0.1.0",
"Language.Basic~~~ta-IN~0.0.1.0",
"Language.Basic~~~te-IN~0.0.1.0",
"Language.Basic~~~tg-CYRL-TJ~0.0.1.0",
"Language.Basic~~~th-TH~0.0.1.0",
"Language.Basic~~~tk-TM~0.0.1.0",
"Language.Basic~~~tn-ZA~0.0.1.0",
"Language.Basic~~~tr-TR~0.0.1.0",
"Language.Basic~~~tt-RU~0.0.1.0",
"Language.Basic~~~ug-CN~0.0.1.0",
"Language.Basic~~~uk-UA~0.0.1.0",
"Language.Basic~~~ur-PK~0.0.1.0",
"Language.Basic~~~uz-LATN-UZ~0.0.1.0",
"Language.Basic~~~vi-VN~0.0.1.0",
"Language.Basic~~~wo-SN~0.0.1.0",
"Language.Basic~~~xh-ZA~0.0.1.0",
"Language.Basic~~~yo-NG~0.0.1.0",
"Language.Basic~~~zh-CN~0.0.1.0",
"Language.Basic~~~zh-HK~0.0.1.0",
"Language.Basic~~~zh-TW~0.0.1.0",
"Language.Basic~~~zu-ZA~0.0.1.0",
"Language.Fonts.Arab~~~und-ARAB~0.0.1.0",
"Language.Fonts.Beng~~~und-BENG~0.0.1.0",
"Language.Fonts.Cans~~~und-CANS~0.0.1.0",
"Language.Fonts.Cher~~~und-CHER~0.0.1.0",
"Language.Fonts.Deva~~~und-DEVA~0.0.1.0",
"Language.Fonts.Ethi~~~und-ETHI~0.0.1.0",
"Language.Fonts.Gujr~~~und-GUJR~0.0.1.0",
"Language.Fonts.Guru~~~und-GURU~0.0.1.0",
"Language.Fonts.Hans~~~und-HANS~0.0.1.0",
"Language.Fonts.Hant~~~und-HANT~0.0.1.0",
"Language.Fonts.Hebr~~~und-HEBR~0.0.1.0",
"Language.Fonts.Jpan~~~und-JPAN~0.0.1.0",
"Language.Fonts.Khmr~~~und-KHMR~0.0.1.0",
"Language.Fonts.Knda~~~und-KNDA~0.0.1.0",
"Language.Fonts.Kore~~~und-KORE~0.0.1.0",
"Language.Fonts.Laoo~~~und-LAOO~0.0.1.0",
"Language.Fonts.Mlym~~~und-MLYM~0.0.1.0",
"Language.Fonts.Orya~~~und-ORYA~0.0.1.0",
"Language.Fonts.PanEuropeanSupplementalFonts~~~~0.0.1.0",
"Language.Fonts.Sinh~~~und-SINH~0.0.1.0",
"Language.Fonts.Syrc~~~und-SYRC~0.0.1.0",
"Language.Fonts.Taml~~~und-TAML~0.0.1.0",
"Language.Fonts.Telu~~~und-TELU~0.0.1.0",
"Language.Fonts.Thai~~~und-THAI~0.0.1.0",
"Language.Handwriting~~~af-ZA~0.0.1.0",
"Language.Handwriting~~~bs-LATN-BA~0.0.1.0",
"Language.Handwriting~~~ca-ES~0.0.1.0",
"Language.Handwriting~~~cs-CZ~0.0.1.0",
"Language.Handwriting~~~cy-GB~0.0.1.0",
"Language.Handwriting~~~da-DK~0.0.1.0",
"Language.Handwriting~~~de-DE~0.0.1.0",
"Language.Handwriting~~~el-GR~0.0.1.0",
"Language.Handwriting~~~en-GB~0.0.1.0",
"Language.Handwriting~~~en-US~0.0.1.0",
"Language.Handwriting~~~es-ES~0.0.1.0",
"Language.Handwriting~~~es-MX~0.0.1.0",
"Language.Handwriting~~~eu-ES~0.0.1.0",
"Language.Handwriting~~~fi-FI~0.0.1.0",
"Language.Handwriting~~~fr-FR~0.0.1.0",
"Language.Handwriting~~~ga-IE~0.0.1.0",
"Language.Handwriting~~~gd-GB~0.0.1.0",
"Language.Handwriting~~~gl-ES~0.0.1.0",
"Language.Handwriting~~~hi-IN~0.0.1.0",
"Language.Handwriting~~~hr-HR~0.0.1.0",
"Language.Handwriting~~~id-ID~0.0.1.0",
"Language.Handwriting~~~it-IT~0.0.1.0",
"Language.Handwriting~~~ja-JP~0.0.1.0",
"Language.Handwriting~~~ko-KR~0.0.1.0",
"Language.Handwriting~~~lb-LU~0.0.1.0",
"Language.Handwriting~~~mi-NZ~0.0.1.0",
"Language.Handwriting~~~ms-BN~0.0.1.0",
"Language.Handwriting~~~ms-MY~0.0.1.0",
"Language.Handwriting~~~nb-NO~0.0.1.0",
"Language.Handwriting~~~nl-NL~0.0.1.0",
"Language.Handwriting~~~nn-NO~0.0.1.0",
"Language.Handwriting~~~nso-ZA~0.0.1.0",
"Language.Handwriting~~~pl-PL~0.0.1.0",
"Language.Handwriting~~~pt-BR~0.0.1.0",
"Language.Handwriting~~~pt-PT~0.0.1.0",
"Language.Handwriting~~~rm-CH~0.0.1.0",
"Language.Handwriting~~~ro-RO~0.0.1.0",
"Language.Handwriting~~~ru-RU~0.0.1.0",
"Language.Handwriting~~~rw-RW~0.0.1.0",
"Language.Handwriting~~~sk-SK~0.0.1.0",
"Language.Handwriting~~~sl-SI~0.0.1.0",
"Language.Handwriting~~~sq-AL~0.0.1.0",
"Language.Handwriting~~~sr-CYRL-RS~0.0.1.0",
"Language.Handwriting~~~sr-LATN-RS~0.0.1.0",
"Language.Handwriting~~~sv-SE~0.0.1.0",
"Language.Handwriting~~~sw-KE~0.0.1.0",
"Language.Handwriting~~~tn-ZA~0.0.1.0",
"Language.Handwriting~~~tr-TR~0.0.1.0",
"Language.Handwriting~~~wo-SN~0.0.1.0",
"Language.Handwriting~~~xh-ZA~0.0.1.0",
"Language.Handwriting~~~zh-CN~0.0.1.0",
"Language.Handwriting~~~zh-HK~0.0.1.0",
"Language.Handwriting~~~zh-TW~0.0.1.0",
"Language.Handwriting~~~zu-ZA~0.0.1.0",
"Language.OCR~~~ar-SA~0.0.1.0",
"Language.OCR~~~bg-BG~0.0.1.0",
"Language.OCR~~~bs-LATN-BA~0.0.1.0",
"Language.OCR~~~cs-CZ~0.0.1.0",
"Language.OCR~~~da-DK~0.0.1.0",
"Language.OCR~~~de-DE~0.0.1.0",
"Language.OCR~~~el-GR~0.0.1.0",
"Language.OCR~~~en-GB~0.0.1.0",
"Language.OCR~~~en-US~0.0.1.0",
"Language.OCR~~~es-ES~0.0.1.0",
"Language.OCR~~~es-MX~0.0.1.0",
"Language.OCR~~~fi-FI~0.0.1.0",
"Language.OCR~~~fr-CA~0.0.1.0",
"Language.OCR~~~fr-FR~0.0.1.0",
"Language.OCR~~~hr-HR~0.0.1.0",
"Language.OCR~~~hu-HU~0.0.1.0",
"Language.OCR~~~it-IT~0.0.1.0",
"Language.OCR~~~ja-JP~0.0.1.0",
"Language.OCR~~~ko-KR~0.0.1.0",
"Language.OCR~~~nb-NO~0.0.1.0",
"Language.OCR~~~nl-NL~0.0.1.0",
"Language.OCR~~~pl-PL~0.0.1.0",
"Language.OCR~~~pt-BR~0.0.1.0",
"Language.OCR~~~pt-PT~0.0.1.0",
"Language.OCR~~~ro-RO~0.0.1.0",
"Language.OCR~~~ru-RU~0.0.1.0",
"Language.OCR~~~sk-SK~0.0.1.0",
"Language.OCR~~~sl-SI~0.0.1.0",
"Language.OCR~~~sr-CYRL-RS~0.0.1.0",
"Language.OCR~~~sr-LATN-RS~0.0.1.0",
"Language.OCR~~~sv-SE~0.0.1.0",
"Language.OCR~~~tr-TR~0.0.1.0",
"Language.OCR~~~zh-CN~0.0.1.0",
"Language.OCR~~~zh-HK~0.0.1.0",
"Language.OCR~~~zh-TW~0.0.1.0",
"Language.Speech~~~de-DE~0.0.1.0",
"Language.Speech~~~en-AU~0.0.1.0",
"Language.Speech~~~en-CA~0.0.1.0",
"Language.Speech~~~en-GB~0.0.1.0",
"Language.Speech~~~en-IN~0.0.1.0",
"Language.Speech~~~en-US~0.0.1.0",
"Language.Speech~~~es-ES~0.0.1.0",
"Language.Speech~~~es-MX~0.0.1.0",
"Language.Speech~~~fr-CA~0.0.1.0",
"Language.Speech~~~fr-FR~0.0.1.0",
"Language.Speech~~~it-IT~0.0.1.0",
"Language.Speech~~~ja-JP~0.0.1.0",
"Language.Speech~~~pt-BR~0.0.1.0",
"Language.Speech~~~zh-CN~0.0.1.0",
"Language.Speech~~~zh-HK~0.0.1.0",
"Language.Speech~~~zh-TW~0.0.1.0",
"Language.TextToSpeech~~~ar-EG~0.0.1.0",
"Language.TextToSpeech~~~ar-SA~0.0.1.0",
"Language.TextToSpeech~~~bg-BG~0.0.1.0",
"Language.TextToSpeech~~~ca-ES~0.0.1.0",
"Language.TextToSpeech~~~cs-CZ~0.0.1.0",
"Language.TextToSpeech~~~da-DK~0.0.1.0",
"Language.TextToSpeech~~~de-AT~0.0.1.0",
"Language.TextToSpeech~~~de-CH~0.0.1.0",
"Language.TextToSpeech~~~de-DE~0.0.1.0",
"Language.TextToSpeech~~~el-GR~0.0.1.0",
"Language.TextToSpeech~~~en-AU~0.0.1.0",
"Language.TextToSpeech~~~en-CA~0.0.1.0",
"Language.TextToSpeech~~~en-GB~0.0.1.0",
"Language.TextToSpeech~~~en-IE~0.0.1.0",
"Language.TextToSpeech~~~en-IN~0.0.1.0",
"Language.TextToSpeech~~~en-US~0.0.1.0",
"Language.TextToSpeech~~~es-ES~0.0.1.0",
"Language.TextToSpeech~~~es-MX~0.0.1.0",
"Language.TextToSpeech~~~fi-FI~0.0.1.0",
"Language.TextToSpeech~~~fr-CA~0.0.1.0",
"Language.TextToSpeech~~~fr-CH~0.0.1.0",
"Language.TextToSpeech~~~fr-FR~0.0.1.0",
"Language.TextToSpeech~~~he-IL~0.0.1.0",
"Language.TextToSpeech~~~hi-IN~0.0.1.0",
"Language.TextToSpeech~~~hr-HR~0.0.1.0",
"Language.TextToSpeech~~~hu-HU~0.0.1.0",
"Language.TextToSpeech~~~id-ID~0.0.1.0",
"Language.TextToSpeech~~~it-IT~0.0.1.0",
"Language.TextToSpeech~~~ja-JP~0.0.1.0",
"Language.TextToSpeech~~~ko-KR~0.0.1.0",
"Language.TextToSpeech~~~ms-MY~0.0.1.0",
"Language.TextToSpeech~~~nb-NO~0.0.1.0",
"Language.TextToSpeech~~~nl-BE~0.0.1.0",
"Language.TextToSpeech~~~nl-NL~0.0.1.0",
"Language.TextToSpeech~~~pl-PL~0.0.1.0",
"Language.TextToSpeech~~~pt-BR~0.0.1.0",
"Language.TextToSpeech~~~pt-PT~0.0.1.0",
"Language.TextToSpeech~~~ro-RO~0.0.1.0",
"Language.TextToSpeech~~~ru-RU~0.0.1.0",
"Language.TextToSpeech~~~sk-SK~0.0.1.0",
"Language.TextToSpeech~~~sl-SI~0.0.1.0",
"Language.TextToSpeech~~~sv-SE~0.0.1.0",
"Language.TextToSpeech~~~ta-IN~0.0.1.0",
"Language.TextToSpeech~~~th-TH~0.0.1.0",
"Language.TextToSpeech~~~tr-TR~0.0.1.0",
"Language.TextToSpeech~~~vi-VN~0.0.1.0",
"Language.TextToSpeech~~~zh-CN~0.0.1.0",
"Language.TextToSpeech~~~zh-HK~0.0.1.0",
"Language.TextToSpeech~~~zh-TW~0.0.1.0",
"MathRecognizer~~~~0.0.1.0",
"Media.WindowsMediaPlayer~~~~0.0.12.0",
"Microsoft.Onecore.StorageManagement~~~~0.0.1.0",
"Microsoft.WebDriver~~~~0.0.1.0",
"Microsoft.Windows.StorageManagement~~~~0.0.1.0",
"Msix.PackagingTool.Driver~~~~0.0.1.0",
"NetFX3~~~~"
"OneCoreUAP.OneSync~~~~0.0.1.0",
"OpenSSH.Client~~~~0.0.1.0",
"OpenSSH.Server~~~~0.0.1.0",
"RasCMAK.Client~~~~0.0.1.0",
"RIP.Listener~~~~0.0.1.0",
"Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0",
"Rsat.BitLocker.Recovery.Tools~~~~0.0.1.0",
"Rsat.CertificateServices.Tools~~~~0.0.1.0",
"Rsat.DHCP.Tools~~~~0.0.1.0",
"Rsat.Dns.Tools~~~~0.0.1.0",
"Rsat.FailoverCluster.Management.Tools~~~~0.0.1.0",
"Rsat.FileServices.Tools~~~~0.0.1.0",
"Rsat.GroupPolicy.Management.Tools~~~~0.0.1.0",
"Rsat.IPAM.Client.Tools~~~~0.0.1.0",
"Rsat.LLDP.Tools~~~~0.0.1.0",
"Rsat.NetworkController.Tools~~~~0.0.1.0",
"Rsat.NetworkLoadBalancing.Tools~~~~0.0.1.0",
"Rsat.RemoteAccess.Management.Tools~~~~0.0.1.0",
"Rsat.RemoteDesktop.Services.Tools~~~~0.0.1.0",
"Rsat.ServerManager.Tools~~~~0.0.1.0",
"Rsat.Shielded.VM.Tools~~~~0.0.1.0",
"Rsat.StorageMigrationService.Management.Tools~~~~0.0.1.0",
"Rsat.StorageReplica.Tools~~~~0.0.1.0",
"Rsat.SystemInsights.Management.Tools~~~~0.0.1.0",
"Rsat.VolumeActivation.Tools~~~~0.0.1.0",
"Rsat.WSUS.Tools~~~~0.0.1.0",
"SNMP.Client~~~~0.0.1.0",
"Tools.DeveloperMode.Core~~~~0.0.1.0",
"Tools.DTrace.Platform~~~~0.0.1.0",
"Tools.Graphics.DirectX~~~~0.0.1.0",
"WMI-SNMP-Provider.Client~~~~0.0.1.0",
"XPS.Viewer~~~~0.0.1.0"
)
$Win10_1809_server_FODs = @("Accessibility.Braille~~~~0.0.1.0",
"Analog.Holographic.Desktop~~~~0.0.1.0",
"App.Support.QuickAssist~~~~0.0.1.0",
"Browser.InternetExplorer~~~~0.0.11.0",
"Hello.Face.17658~~~~0.0.1.0",
"Hello.Face.Migration.17658~~~~0.0.1.0",
"Language.Basic~~~af-ZA~0.0.1.0",
"Language.Basic~~~ar-SA~0.0.1.0",
"Language.Basic~~~as-IN~0.0.1.0",
"Language.Basic~~~az-LATN-AZ~0.0.1.0",
"Language.Basic~~~ba-RU~0.0.1.0",
"Language.Basic~~~be-BY~0.0.1.0",
"Language.Basic~~~bg-BG~0.0.1.0",
"Language.Basic~~~bn-BD~0.0.1.0",
"Language.Basic~~~bn-IN~0.0.1.0",
"Language.Basic~~~bs-LATN-BA~0.0.1.0",
"Language.Basic~~~ca-ES~0.0.1.0",
"Language.Basic~~~cs-CZ~0.0.1.0",
"Language.Basic~~~cy-GB~0.0.1.0",
"Language.Basic~~~da-DK~0.0.1.0",
"Language.Basic~~~de-DE~0.0.1.0",
"Language.Basic~~~el-GR~0.0.1.0",
"Language.Basic~~~en-GB~0.0.1.0",
"Language.Basic~~~en-US~0.0.1.0",
"Language.Basic~~~es-ES~0.0.1.0",
"Language.Basic~~~es-MX~0.0.1.0",
"Language.Basic~~~et-EE~0.0.1.0",
"Language.Basic~~~eu-ES~0.0.1.0",
"Language.Basic~~~fa-IR~0.0.1.0",
"Language.Basic~~~fi-FI~0.0.1.0",
"Language.Basic~~~fil-PH~0.0.1.0",
"Language.Basic~~~fr-CA~0.0.1.0",
"Language.Basic~~~fr-FR~0.0.1.0",
"Language.Basic~~~ga-IE~0.0.1.0",
"Language.Basic~~~gd-GB~0.0.1.0",
"Language.Basic~~~gl-ES~0.0.1.0",
"Language.Basic~~~gu-IN~0.0.1.0",
"Language.Basic~~~ha-LATN-NG~0.0.1.0",
"Language.Basic~~~haw-US~0.0.1.0",
"Language.Basic~~~he-IL~0.0.1.0",
"Language.Basic~~~hi-IN~0.0.1.0",
"Language.Basic~~~hr-HR~0.0.1.0",
"Language.Basic~~~hu-HU~0.0.1.0",
"Language.Basic~~~hy-AM~0.0.1.0",
"Language.Basic~~~id-ID~0.0.1.0",
"Language.Basic~~~ig-NG~0.0.1.0",
"Language.Basic~~~is-IS~0.0.1.0",
"Language.Basic~~~it-IT~0.0.1.0",
"Language.Basic~~~ja-JP~0.0.1.0",
"Language.Basic~~~ka-GE~0.0.1.0",
"Language.Basic~~~kk-KZ~0.0.1.0",
"Language.Basic~~~kl-GL~0.0.1.0",
"Language.Basic~~~kn-IN~0.0.1.0",
"Language.Basic~~~ko-KR~0.0.1.0",
"Language.Basic~~~kok-DEVA-IN~0.0.1.0",
"Language.Basic~~~ky-KG~0.0.1.0",
"Language.Basic~~~lb-LU~0.0.1.0",
"Language.Basic~~~lt-LT~0.0.1.0",
"Language.Basic~~~lv-LV~0.0.1.0",
"Language.Basic~~~mi-NZ~0.0.1.0",
"Language.Basic~~~ml-IN~0.0.1.0",
"Language.Basic~~~mk-MK~0.0.1.0",
"Language.Basic~~~mn-MN~0.0.1.0",
"Language.Basic~~~mr-IN~0.0.1.0",
"Language.Basic~~~ms-BN~0.0.1.0",
"Language.Basic~~~ms-MY~0.0.1.0",
"Language.Basic~~~mt-MT~0.0.1.0",
"Language.Basic~~~nb-NO~0.0.1.0",
"Language.Basic~~~ne-NP~0.0.1.0",
"Language.Basic~~~nl-NL~0.0.1.0",
"Language.Basic~~~nn-NO~0.0.1.0",
"Language.Basic~~~nso-ZA~0.0.1.0",
"Language.Basic~~~or-IN~0.0.1.0",
"Language.Basic~~~pa-IN~0.0.1.0",
"Language.Basic~~~pl-PL~0.0.1.0",
"Language.Basic~~~ps-AF~0.0.1.0",
"Language.Basic~~~pt-BR~0.0.1.0",
"Language.Basic~~~pt-PT~0.0.1.0",
"Language.Basic~~~rm-CH~0.0.1.0",
"Language.Basic~~~ro-RO~0.0.1.0",
"Language.Basic~~~ru-RU~0.0.1.0",
"Language.Basic~~~rw-RW~0.0.1.0",
"Language.Basic~~~sah-RU~0.0.1.0",
"Language.Basic~~~si-LK~0.0.1.0",
"Language.Basic~~~sk-SK~0.0.1.0",
"Language.Basic~~~sl-SI~0.0.1.0",
"Language.Basic~~~sq-AL~0.0.1.0",
"Language.Basic~~~sr-CYRL-RS~0.0.1.0",
"Language.Basic~~~sr-LATN-RS~0.0.1.0",
"Language.Basic~~~sv-SE~0.0.1.0",
"Language.Basic~~~sw-KE~0.0.1.0",
"Language.Basic~~~ta-IN~0.0.1.0",
"Language.Basic~~~te-IN~0.0.1.0",
"Language.Basic~~~tg-CYRL-TJ~0.0.1.0",
"Language.Basic~~~th-TH~0.0.1.0",
"Language.Basic~~~tk-TM~0.0.1.0",
"Language.Basic~~~tn-ZA~0.0.1.0",
"Language.Basic~~~tr-TR~0.0.1.0",
"Language.Basic~~~tt-RU~0.0.1.0",
"Language.Basic~~~ug-CN~0.0.1.0",
"Language.Basic~~~uk-UA~0.0.1.0",
"Language.Basic~~~ur-PK~0.0.1.0",
"Language.Basic~~~uz-LATN-UZ~0.0.1.0",
"Language.Basic~~~vi-VN~0.0.1.0",
"Language.Basic~~~wo-SN~0.0.1.0",
"Language.Basic~~~xh-ZA~0.0.1.0",
"Language.Basic~~~yo-NG~0.0.1.0",
"Language.Basic~~~zh-CN~0.0.1.0",
"Language.Basic~~~zh-HK~0.0.1.0",
"Language.Basic~~~zh-TW~0.0.1.0",
"Language.Basic~~~zu-ZA~0.0.1.0",
"Language.Fonts.Arab~~~und-ARAB~0.0.1.0",
"Language.Fonts.Beng~~~und-BENG~0.0.1.0",
"Language.Fonts.Cans~~~und-CANS~0.0.1.0",
"Language.Fonts.Cher~~~und-CHER~0.0.1.0",
"Language.Fonts.Deva~~~und-DEVA~0.0.1.0",
"Language.Fonts.Ethi~~~und-ETHI~0.0.1.0",
"Language.Fonts.Gujr~~~und-GUJR~0.0.1.0",
"Language.Fonts.Guru~~~und-GURU~0.0.1.0",
"Language.Fonts.Hans~~~und-HANS~0.0.1.0",
"Language.Fonts.Hant~~~und-HANT~0.0.1.0",
"Language.Fonts.Hebr~~~und-HEBR~0.0.1.0",
"Language.Fonts.Jpan~~~und-JPAN~0.0.1.0",
"Language.Fonts.Khmr~~~und-KHMR~0.0.1.0",
"Language.Fonts.Knda~~~und-KNDA~0.0.1.0",
"Language.Fonts.Kore~~~und-KORE~0.0.1.0",
"Language.Fonts.Laoo~~~und-LAOO~0.0.1.0",
"Language.Fonts.Mlym~~~und-MLYM~0.0.1.0",
"Language.Fonts.Orya~~~und-ORYA~0.0.1.0",
"Language.Fonts.PanEuropeanSupplementalFonts~~~~0.0.1.0",
"Language.Fonts.Sinh~~~und-SINH~0.0.1.0",
"Language.Fonts.Syrc~~~und-SYRC~0.0.1.0",
"Language.Fonts.Taml~~~und-TAML~0.0.1.0",
"Language.Fonts.Telu~~~und-TELU~0.0.1.0",
"Language.Fonts.Thai~~~und-THAI~0.0.1.0",
"Language.Handwriting~~~af-ZA~0.0.1.0",
"Language.Handwriting~~~bs-LATN-BA~0.0.1.0",
"Language.Handwriting~~~ca-ES~0.0.1.0",
"Language.Handwriting~~~cs-CZ~0.0.1.0",
"Language.Handwriting~~~cy-GB~0.0.1.0",
"Language.Handwriting~~~da-DK~0.0.1.0",
"Language.Handwriting~~~de-DE~0.0.1.0",
"Language.Handwriting~~~el-GR~0.0.1.0",
"Language.Handwriting~~~en-GB~0.0.1.0",
"Language.Handwriting~~~en-US~0.0.1.0",
"Language.Handwriting~~~es-ES~0.0.1.0",
"Language.Handwriting~~~es-MX~0.0.1.0",
"Language.Handwriting~~~eu-ES~0.0.1.0",
"Language.Handwriting~~~fi-FI~0.0.1.0",
"Language.Handwriting~~~fr-FR~0.0.1.0",
"Language.Handwriting~~~ga-IE~0.0.1.0",
"Language.Handwriting~~~gd-GB~0.0.1.0",
"Language.Handwriting~~~gl-ES~0.0.1.0",
"Language.Handwriting~~~hi-IN~0.0.1.0",
"Language.Handwriting~~~hr-HR~0.0.1.0",
"Language.Handwriting~~~id-ID~0.0.1.0",
"Language.Handwriting~~~it-IT~0.0.1.0",
"Language.Handwriting~~~ja-JP~0.0.1.0",
"Language.Handwriting~~~ko-KR~0.0.1.0",
"Language.Handwriting~~~lb-LU~0.0.1.0",
"Language.Handwriting~~~mi-NZ~0.0.1.0",
"Language.Handwriting~~~ms-BN~0.0.1.0",
"Language.Handwriting~~~ms-MY~0.0.1.0",
"Language.Handwriting~~~nb-NO~0.0.1.0",
"Language.Handwriting~~~nl-NL~0.0.1.0",
"Language.Handwriting~~~nn-NO~0.0.1.0",
"Language.Handwriting~~~nso-ZA~0.0.1.0",
"Language.Handwriting~~~pl-PL~0.0.1.0",
"Language.Handwriting~~~pt-BR~0.0.1.0",
"Language.Handwriting~~~pt-PT~0.0.1.0",
"Language.Handwriting~~~rm-CH~0.0.1.0",
"Language.Handwriting~~~ro-RO~0.0.1.0",
"Language.Handwriting~~~ru-RU~0.0.1.0",
"Language.Handwriting~~~rw-RW~0.0.1.0",
"Language.Handwriting~~~sk-SK~0.0.1.0",
"Language.Handwriting~~~sl-SI~0.0.1.0",
"Language.Handwriting~~~sq-AL~0.0.1.0",
"Language.Handwriting~~~sr-CYRL-RS~0.0.1.0",
"Language.Handwriting~~~sr-LATN-RS~0.0.1.0",
"Language.Handwriting~~~sv-SE~0.0.1.0",
"Language.Handwriting~~~sw-KE~0.0.1.0",
"Language.Handwriting~~~tn-ZA~0.0.1.0",
"Language.Handwriting~~~tr-TR~0.0.1.0",
"Language.Handwriting~~~wo-SN~0.0.1.0",
"Language.Handwriting~~~xh-ZA~0.0.1.0",
"Language.Handwriting~~~zh-CN~0.0.1.0",
"Language.Handwriting~~~zh-HK~0.0.1.0",
"Language.Handwriting~~~zh-TW~0.0.1.0",
"Language.Handwriting~~~zu-ZA~0.0.1.0",
"Language.OCR~~~ar-SA~0.0.1.0",
"Language.OCR~~~bg-BG~0.0.1.0",
"Language.OCR~~~bs-LATN-BA~0.0.1.0",
"Language.OCR~~~cs-CZ~0.0.1.0",
"Language.OCR~~~da-DK~0.0.1.0",
"Language.OCR~~~de-DE~0.0.1.0",
"Language.OCR~~~el-GR~0.0.1.0",
"Language.OCR~~~en-GB~0.0.1.0",
"Language.OCR~~~en-US~0.0.1.0",
"Language.OCR~~~es-ES~0.0.1.0",
"Language.OCR~~~es-MX~0.0.1.0",
"Language.OCR~~~fi-FI~0.0.1.0",
"Language.OCR~~~fr-CA~0.0.1.0",
"Language.OCR~~~fr-FR~0.0.1.0",
"Language.OCR~~~hr-HR~0.0.1.0",
"Language.OCR~~~hu-HU~0.0.1.0",
"Language.OCR~~~it-IT~0.0.1.0",
"Language.OCR~~~ja-JP~0.0.1.0",
"Language.OCR~~~ko-KR~0.0.1.0",
"Language.OCR~~~nb-NO~0.0.1.0",
"Language.OCR~~~nl-NL~0.0.1.0",
"Language.OCR~~~pl-PL~0.0.1.0",
"Language.OCR~~~pt-BR~0.0.1.0",
"Language.OCR~~~pt-PT~0.0.1.0",
"Language.OCR~~~ro-RO~0.0.1.0",
"Language.OCR~~~ru-RU~0.0.1.0",
"Language.OCR~~~sk-SK~0.0.1.0",
"Language.OCR~~~sl-SI~0.0.1.0",
"Language.OCR~~~sr-CYRL-RS~0.0.1.0",
"Language.OCR~~~sr-LATN-RS~0.0.1.0",
"Language.OCR~~~sv-SE~0.0.1.0",
"Language.OCR~~~tr-TR~0.0.1.0",
"Language.OCR~~~zh-CN~0.0.1.0",
"Language.OCR~~~zh-HK~0.0.1.0",
"Language.OCR~~~zh-TW~0.0.1.0",
"Language.Speech~~~de-DE~0.0.1.0",
"Language.Speech~~~en-AU~0.0.1.0",
"Language.Speech~~~en-CA~0.0.1.0",
"Language.Speech~~~en-GB~0.0.1.0",
"Language.Speech~~~en-IN~0.0.1.0",
"Language.Speech~~~en-US~0.0.1.0",
"Language.Speech~~~es-ES~0.0.1.0",
"Language.Speech~~~es-MX~0.0.1.0",
"Language.Speech~~~fr-CA~0.0.1.0",
"Language.Speech~~~fr-FR~0.0.1.0",
"Language.Speech~~~it-IT~0.0.1.0",
"Language.Speech~~~ja-JP~0.0.1.0",
"Language.Speech~~~pt-BR~0.0.1.0",
"Language.Speech~~~zh-CN~0.0.1.0",
"Language.Speech~~~zh-HK~0.0.1.0",
"Language.Speech~~~zh-TW~0.0.1.0",
"Language.TextToSpeech~~~ar-EG~0.0.1.0",
"Language.TextToSpeech~~~ar-SA~0.0.1.0",
"Language.TextToSpeech~~~bg-BG~0.0.1.0",
"Language.TextToSpeech~~~ca-ES~0.0.1.0",
"Language.TextToSpeech~~~cs-CZ~0.0.1.0",
"Language.TextToSpeech~~~da-DK~0.0.1.0",
"Language.TextToSpeech~~~de-AT~0.0.1.0",
"Language.TextToSpeech~~~de-CH~0.0.1.0",
"Language.TextToSpeech~~~de-DE~0.0.1.0",
"Language.TextToSpeech~~~el-GR~0.0.1.0",
"Language.TextToSpeech~~~en-AU~0.0.1.0",
"Language.TextToSpeech~~~en-CA~0.0.1.0",
"Language.TextToSpeech~~~en-GB~0.0.1.0",
"Language.TextToSpeech~~~en-IE~0.0.1.0",
"Language.TextToSpeech~~~en-IN~0.0.1.0",
"Language.TextToSpeech~~~en-US~0.0.1.0",
"Language.TextToSpeech~~~es-ES~0.0.1.0",
"Language.TextToSpeech~~~es-MX~0.0.1.0",
"Language.TextToSpeech~~~fi-FI~0.0.1.0",
"Language.TextToSpeech~~~fr-CA~0.0.1.0",
"Language.TextToSpeech~~~fr-CH~0.0.1.0",
"Language.TextToSpeech~~~fr-FR~0.0.1.0",
"Language.TextToSpeech~~~he-IL~0.0.1.0",
"Language.TextToSpeech~~~hi-IN~0.0.1.0",
"Language.TextToSpeech~~~hr-HR~0.0.1.0",
"Language.TextToSpeech~~~hu-HU~0.0.1.0",
"Language.TextToSpeech~~~id-ID~0.0.1.0",
"Language.TextToSpeech~~~it-IT~0.0.1.0",
"Language.TextToSpeech~~~ja-JP~0.0.1.0",
"Language.TextToSpeech~~~ko-KR~0.0.1.0",
"Language.TextToSpeech~~~ms-MY~0.0.1.0",
"Language.TextToSpeech~~~nb-NO~0.0.1.0",
"Language.TextToSpeech~~~nl-BE~0.0.1.0",
"Language.TextToSpeech~~~nl-NL~0.0.1.0",
"Language.TextToSpeech~~~pl-PL~0.0.1.0",
"Language.TextToSpeech~~~pt-BR~0.0.1.0",
"Language.TextToSpeech~~~pt-PT~0.0.1.0",
"Language.TextToSpeech~~~ro-RO~0.0.1.0",
"Language.TextToSpeech~~~ru-RU~0.0.1.0",
"Language.TextToSpeech~~~sk-SK~0.0.1.0",
"Language.TextToSpeech~~~sl-SI~0.0.1.0",
"Language.TextToSpeech~~~sv-SE~0.0.1.0",
"Language.TextToSpeech~~~ta-IN~0.0.1.0",
"Language.TextToSpeech~~~th-TH~0.0.1.0",
"Language.TextToSpeech~~~tr-TR~0.0.1.0",
"Language.TextToSpeech~~~vi-VN~0.0.1.0",
"Language.TextToSpeech~~~zh-CN~0.0.1.0",
"Language.TextToSpeech~~~zh-HK~0.0.1.0",
"Language.TextToSpeech~~~zh-TW~0.0.1.0",
"MathRecognizer~~~~0.0.1.0",
"Media.WindowsMediaPlayer~~~~0.0.12.0",
"Microsoft.Onecore.StorageManagement~~~~0.0.1.0",
"Microsoft.WebDriver~~~~0.0.1.0",
"Microsoft.Windows.StorageManagement~~~~0.0.1.0",
"Msix.PackagingTool.Driver~~~~0.0.1.0",
"NetFX3~~~~"
"OneCoreUAP.OneSync~~~~0.0.1.0",
"OpenSSH.Client~~~~0.0.1.0",
"OpenSSH.Server~~~~0.0.1.0",
"RasCMAK.Client~~~~0.0.1.0",
"RIP.Listener~~~~0.0.1.0",
"Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0",
"Rsat.BitLocker.Recovery.Tools~~~~0.0.1.0",
"Rsat.CertificateServices.Tools~~~~0.0.1.0",
"Rsat.DHCP.Tools~~~~0.0.1.0",
"Rsat.Dns.Tools~~~~0.0.1.0",
"Rsat.FailoverCluster.Management.Tools~~~~0.0.1.0",
"Rsat.FileServices.Tools~~~~0.0.1.0",
"Rsat.GroupPolicy.Management.Tools~~~~0.0.1.0",
"Rsat.IPAM.Client.Tools~~~~0.0.1.0",
"Rsat.LLDP.Tools~~~~0.0.1.0",
"Rsat.NetworkController.Tools~~~~0.0.1.0",
"Rsat.NetworkLoadBalancing.Tools~~~~0.0.1.0",
"Rsat.RemoteAccess.Management.Tools~~~~0.0.1.0",
"Rsat.RemoteDesktop.Services.Tools~~~~0.0.1.0",
"Rsat.ServerManager.Tools~~~~0.0.1.0",
"Rsat.Shielded.VM.Tools~~~~0.0.1.0",
"Rsat.StorageMigrationService.Management.Tools~~~~0.0.1.0",
"Rsat.StorageReplica.Tools~~~~0.0.1.0",
"Rsat.SystemInsights.Management.Tools~~~~0.0.1.0",
"Rsat.VolumeActivation.Tools~~~~0.0.1.0",
"Rsat.WSUS.Tools~~~~0.0.1.0",
"ServerCore.AppCompatibility~~~~0.0.1.0",
"SNMP.Client~~~~0.0.1.0",
"Tools.DeveloperMode.Core~~~~0.0.1.0",
"Tools.DTrace.Platform~~~~0.0.1.0",
"Tools.Graphics.DirectX~~~~0.0.1.0",
"WMI-SNMP-Provider.Client~~~~0.0.1.0",
"XPS.Viewer~~~~0.0.1.0"
)
$Win10_2004_FODs = @("Accessibility.Braille~~~~0.0.1.0",
"Analog.Holographic.Desktop~~~~0.0.1.0",
"App.StepsRecorder~~~~0.0.1.0",
"App.Support.QuickAssist~~~~0.0.1.0",
"App.WirelessDisplay.Connect~~~~0.0.1.0",
"Browser.InternetExplorer~~~~0.0.11.0",
"DirectX.Configuration.Database~~~~0.0.1.0",
"Hello.Face.18967~~~~0.0.1.0",
"Hello.Face.Migration.18967~~~~0.0.1.0",
"Language.Basic~~~af-ZA~0.0.1.0",
"Language.Basic~~~ar-SA~0.0.1.0",
"Language.Basic~~~as-IN~0.0.1.0",
"Language.Basic~~~az-LATN-AZ~0.0.1.0",
"Language.Basic~~~ba-RU~0.0.1.0",
"Language.Basic~~~be-BY~0.0.1.0",
"Language.Basic~~~bg-BG~0.0.1.0",
"Language.Basic~~~bn-BD~0.0.1.0",
"Language.Basic~~~bn-IN~0.0.1.0",
"Language.Basic~~~bs-LATN-BA~0.0.1.0",
"Language.Basic~~~ca-ES~0.0.1.0",
"Language.Basic~~~cs-CZ~0.0.1.0",
"Language.Basic~~~cy-GB~0.0.1.0",
"Language.Basic~~~da-DK~0.0.1.0",
"Language.Basic~~~de-CH~0.0.1.0",
"Language.Basic~~~de-DE~0.0.1.0",
"Language.Basic~~~el-GR~0.0.1.0",
"Language.Basic~~~en-AU~0.0.1.0",
"Language.Basic~~~en-CA~0.0.1.0",
"Language.Basic~~~en-GB~0.0.1.0",
"Language.Basic~~~en-IN~0.0.1.0",
"Language.Basic~~~en-US~0.0.1.0",
"Language.Basic~~~es-ES~0.0.1.0",
"Language.Basic~~~es-MX~0.0.1.0",
"Language.Basic~~~es-US~0.0.1.0",
"Language.Basic~~~et-EE~0.0.1.0",
"Language.Basic~~~eu-ES~0.0.1.0",
"Language.Basic~~~fa-IR~0.0.1.0",
"Language.Basic~~~fi-FI~0.0.1.0",
"Language.Basic~~~fil-PH~0.0.1.0",
"Language.Basic~~~fr-BE~0.0.1.0",
"Language.Basic~~~fr-CA~0.0.1.0",
"Language.Basic~~~fr-CH~0.0.1.0",
"Language.Basic~~~fr-FR~0.0.1.0",
"Language.Basic~~~ga-IE~0.0.1.0",
"Language.Basic~~~gd-GB~0.0.1.0",
"Language.Basic~~~gl-ES~0.0.1.0",
"Language.Basic~~~gu-IN~0.0.1.0",
"Language.Basic~~~ha-LATN-NG~0.0.1.0",
"Language.Basic~~~haw-US~0.0.1.0",
"Language.Basic~~~he-IL~0.0.1.0",
"Language.Basic~~~hi-IN~0.0.1.0",
"Language.Basic~~~hr-HR~0.0.1.0",
"Language.Basic~~~hu-HU~0.0.1.0",
"Language.Basic~~~hy-AM~0.0.1.0",
"Language.Basic~~~id-ID~0.0.1.0",
"Language.Basic~~~ig-NG~0.0.1.0",
"Language.Basic~~~is-IS~0.0.1.0",
"Language.Basic~~~it-IT~0.0.1.0",
"Language.Basic~~~ja-JP~0.0.1.0",
"Language.Basic~~~ka-GE~0.0.1.0",
"Language.Basic~~~kk-KZ~0.0.1.0",
"Language.Basic~~~kl-GL~0.0.1.0",
"Language.Basic~~~kn-IN~0.0.1.0",
"Language.Basic~~~ko-KR~0.0.1.0",
"Language.Basic~~~kok-DEVA-IN~0.0.1.0",
"Language.Basic~~~ky-KG~0.0.1.0",
"Language.Basic~~~lb-LU~0.0.1.0",
"Language.Basic~~~lt-LT~0.0.1.0",
"Language.Basic~~~lv-LV~0.0.1.0",
"Language.Basic~~~mi-NZ~0.0.1.0",
"Language.Basic~~~mk-MK~0.0.1.0",
"Language.Basic~~~ml-IN~0.0.1.0",
"Language.Basic~~~mn-MN~0.0.1.0",
"Language.Basic~~~mr-IN~0.0.1.0",
"Language.Basic~~~ms-BN~0.0.1.0",
"Language.Basic~~~ms-MY~0.0.1.0",
"Language.Basic~~~mt-MT~0.0.1.0",
"Language.Basic~~~nb-NO~0.0.1.0",
"Language.Basic~~~ne-NP~0.0.1.0",
"Language.Basic~~~nl-NL~0.0.1.0",
"Language.Basic~~~nn-NO~0.0.1.0",
"Language.Basic~~~nso-ZA~0.0.1.0",
"Language.Basic~~~or-IN~0.0.1.0",
"Language.Basic~~~pa-IN~0.0.1.0",
"Language.Basic~~~pl-PL~0.0.1.0",
"Language.Basic~~~ps-AF~0.0.1.0",
"Language.Basic~~~pt-BR~0.0.1.0",
"Language.Basic~~~pt-PT~0.0.1.0",
"Language.Basic~~~rm-CH~0.0.1.0",
"Language.Basic~~~ro-RO~0.0.1.0",
"Language.Basic~~~ru-RU~0.0.1.0",
"Language.Basic~~~rw-RW~0.0.1.0",
"Language.Basic~~~sah-RU~0.0.1.0",
"Language.Basic~~~si-LK~0.0.1.0",
"Language.Basic~~~sk-SK~0.0.1.0",
"Language.Basic~~~sl-SI~0.0.1.0",
"Language.Basic~~~sq-AL~0.0.1.0",
"Language.Basic~~~sr-CYRL-RS~0.0.1.0",
"Language.Basic~~~sr-LATN-RS~0.0.1.0",
"Language.Basic~~~sv-SE~0.0.1.0",
"Language.Basic~~~sw-KE~0.0.1.0",
"Language.Basic~~~ta-IN~0.0.1.0",
"Language.Basic~~~te-IN~0.0.1.0",
"Language.Basic~~~tg-CYRL-TJ~0.0.1.0",
"Language.Basic~~~th-TH~0.0.1.0",
"Language.Basic~~~tk-TM~0.0.1.0",
"Language.Basic~~~tn-ZA~0.0.1.0",
"Language.Basic~~~tr-TR~0.0.1.0",
"Language.Basic~~~tt-RU~0.0.1.0",
"Language.Basic~~~ug-CN~0.0.1.0",
"Language.Basic~~~uk-UA~0.0.1.0",
"Language.Basic~~~ur-PK~0.0.1.0",
"Language.Basic~~~uz-LATN-UZ~0.0.1.0",
"Language.Basic~~~vi-VN~0.0.1.0",
"Language.Basic~~~wo-SN~0.0.1.0",
"Language.Basic~~~xh-ZA~0.0.1.0",
"Language.Basic~~~yo-NG~0.0.1.0",
"Language.Basic~~~zh-CN~0.0.1.0",
"Language.Basic~~~zh-HK~0.0.1.0",
"Language.Basic~~~zh-TW~0.0.1.0",
"Language.Basic~~~zu-ZA~0.0.1.0",
"Language.Fonts.Arab~~~und-ARAB~0.0.1.0",
"Language.Fonts.Beng~~~und-BENG~0.0.1.0",
"Language.Fonts.Cans~~~und-CANS~0.0.1.0",
"Language.Fonts.Cher~~~und-CHER~0.0.1.0",
"Language.Fonts.Deva~~~und-DEVA~0.0.1.0",
"Language.Fonts.Ethi~~~und-ETHI~0.0.1.0",
"Language.Fonts.Gujr~~~und-GUJR~0.0.1.0",
"Language.Fonts.Guru~~~und-GURU~0.0.1.0",
"Language.Fonts.Hans~~~und-HANS~0.0.1.0",
"Language.Fonts.Hant~~~und-HANT~0.0.1.0",
"Language.Fonts.Hebr~~~und-HEBR~0.0.1.0",
"Language.Fonts.Jpan~~~und-JPAN~0.0.1.0",
"Language.Fonts.Khmr~~~und-KHMR~0.0.1.0",
"Language.Fonts.Knda~~~und-KNDA~0.0.1.0",
"Language.Fonts.Kore~~~und-KORE~0.0.1.0",
"Language.Fonts.Laoo~~~und-LAOO~0.0.1.0",
"Language.Fonts.Mlym~~~und-MLYM~0.0.1.0",
"Language.Fonts.Orya~~~und-ORYA~0.0.1.0",
"Language.Fonts.PanEuropeanSupplementalFonts~~~~0.0.1.0",
"Language.Fonts.Sinh~~~und-SINH~0.0.1.0",
"Language.Fonts.Syrc~~~und-SYRC~0.0.1.0",
"Language.Fonts.Taml~~~und-TAML~0.0.1.0",
"Language.Fonts.Telu~~~und-TELU~0.0.1.0",
"Language.Fonts.Thai~~~und-THAI~0.0.1.0",
"Language.Handwriting~~~af-ZA~0.0.1.0",
"Language.Handwriting~~~bs-LATN-BA~0.0.1.0",
"Language.Handwriting~~~ca-ES~0.0.1.0",
"Language.Handwriting~~~cs-CZ~0.0.1.0",
"Language.Handwriting~~~cy-GB~0.0.1.0",
"Language.Handwriting~~~da-DK~0.0.1.0",
"Language.Handwriting~~~de-DE~0.0.1.0",
"Language.Handwriting~~~el-GR~0.0.1.0",
"Language.Handwriting~~~en-GB~0.0.1.0",
"Language.Handwriting~~~en-US~0.0.1.0",
"Language.Handwriting~~~es-ES~0.0.1.0",
"Language.Handwriting~~~es-MX~0.0.1.0",
"Language.Handwriting~~~eu-ES~0.0.1.0",
"Language.Handwriting~~~fi-FI~0.0.1.0",
"Language.Handwriting~~~fr-FR~0.0.1.0",
"Language.Handwriting~~~ga-IE~0.0.1.0",
"Language.Handwriting~~~gd-GB~0.0.1.0",
"Language.Handwriting~~~gl-ES~0.0.1.0",
"Language.Handwriting~~~hi-IN~0.0.1.0",
"Language.Handwriting~~~hr-HR~0.0.1.0",
"Language.Handwriting~~~id-ID~0.0.1.0",
"Language.Handwriting~~~it-IT~0.0.1.0",
"Language.Handwriting~~~ja-JP~0.0.1.0",
"Language.Handwriting~~~ko-KR~0.0.1.0",
"Language.Handwriting~~~lb-LU~0.0.1.0",
"Language.Handwriting~~~mi-NZ~0.0.1.0",
"Language.Handwriting~~~ms-BN~0.0.1.0",
"Language.Handwriting~~~ms-MY~0.0.1.0",
"Language.Handwriting~~~nb-NO~0.0.1.0",
"Language.Handwriting~~~nl-NL~0.0.1.0",
"Language.Handwriting~~~nn-NO~0.0.1.0",
"Language.Handwriting~~~nso-ZA~0.0.1.0",
"Language.Handwriting~~~pl-PL~0.0.1.0",
"Language.Handwriting~~~pt-BR~0.0.1.0",
"Language.Handwriting~~~pt-PT~0.0.1.0",
"Language.Handwriting~~~rm-CH~0.0.1.0",
"Language.Handwriting~~~ro-RO~0.0.1.0",
"Language.Handwriting~~~ru-RU~0.0.1.0",
"Language.Handwriting~~~rw-RW~0.0.1.0",
"Language.Handwriting~~~sk-SK~0.0.1.0",
"Language.Handwriting~~~sl-SI~0.0.1.0",
"Language.Handwriting~~~sq-AL~0.0.1.0",
"Language.Handwriting~~~sr-CYRL-RS~0.0.1.0",
"Language.Handwriting~~~sr-LATN-RS~0.0.1.0",
"Language.Handwriting~~~sv-SE~0.0.1.0",
"Language.Handwriting~~~sw-KE~0.0.1.0",
"Language.Handwriting~~~tn-ZA~0.0.1.0",
"Language.Handwriting~~~tr-TR~0.0.1.0",
"Language.Handwriting~~~wo-SN~0.0.1.0",
"Language.Handwriting~~~xh-ZA~0.0.1.0",
"Language.Handwriting~~~zh-CN~0.0.1.0",
"Language.Handwriting~~~zh-HK~0.0.1.0",
"Language.Handwriting~~~zh-TW~0.0.1.0",
"Language.Handwriting~~~zu-ZA~0.0.1.0",
"Language.OCR~~~ar-SA~0.0.1.0",
"Language.OCR~~~bg-BG~0.0.1.0",
"Language.OCR~~~bs-LATN-BA~0.0.1.0",
"Language.OCR~~~cs-CZ~0.0.1.0",
"Language.OCR~~~da-DK~0.0.1.0",
"Language.OCR~~~de-DE~0.0.1.0",
"Language.OCR~~~el-GR~0.0.1.0",
"Language.OCR~~~en-GB~0.0.1.0",
"Language.OCR~~~en-US~0.0.1.0",
"Language.OCR~~~es-ES~0.0.1.0",
"Language.OCR~~~es-MX~0.0.1.0",
"Language.OCR~~~fi-FI~0.0.1.0",
"Language.OCR~~~fr-CA~0.0.1.0",
"Language.OCR~~~fr-FR~0.0.1.0",
"Language.OCR~~~hr-HR~0.0.1.0",
"Language.OCR~~~hu-HU~0.0.1.0",
"Language.OCR~~~it-IT~0.0.1.0",
"Language.OCR~~~ja-JP~0.0.1.0",
"Language.OCR~~~ko-KR~0.0.1.0",
"Language.OCR~~~nb-NO~0.0.1.0",
"Language.OCR~~~nl-NL~0.0.1.0",
"Language.OCR~~~pl-PL~0.0.1.0",
"Language.OCR~~~pt-BR~0.0.1.0",
"Language.OCR~~~pt-PT~0.0.1.0",
"Language.OCR~~~ro-RO~0.0.1.0",
"Language.OCR~~~ru-RU~0.0.1.0",
"Language.OCR~~~sk-SK~0.0.1.0",
"Language.OCR~~~sl-SI~0.0.1.0",
"Language.OCR~~~sr-CYRL-RS~0.0.1.0",
"Language.OCR~~~sr-LATN-RS~0.0.1.0",
"Language.OCR~~~sv-SE~0.0.1.0",
"Language.OCR~~~tr-TR~0.0.1.0",
"Language.OCR~~~zh-CN~0.0.1.0",
"Language.OCR~~~zh-HK~0.0.1.0",
"Language.OCR~~~zh-TW~0.0.1.0",
"Language.Speech~~~da-DK~0.0.1.0",
"Language.Speech~~~de-DE~0.0.1.0",
"Language.Speech~~~en-AU~0.0.1.0",
"Language.Speech~~~en-CA~0.0.1.0",
"Language.Speech~~~en-GB~0.0.1.0",
"Language.Speech~~~en-IN~0.0.1.0",
"Language.Speech~~~en-US~0.0.1.0",
"Language.Speech~~~es-ES~0.0.1.0",
"Language.Speech~~~es-MX~0.0.1.0",
"Language.Speech~~~fr-CA~0.0.1.0",
"Language.Speech~~~fr-FR~0.0.1.0",
"Language.Speech~~~it-IT~0.0.1.0",
"Language.Speech~~~ja-JP~0.0.1.0",
"Language.Speech~~~pt-BR~0.0.1.0",
"Language.Speech~~~zh-CN~0.0.1.0",
"Language.Speech~~~zh-HK~0.0.1.0",
"Language.Speech~~~zh-TW~0.0.1.0",
"Language.TextToSpeech~~~ar-EG~0.0.1.0",
"Language.TextToSpeech~~~ar-SA~0.0.1.0",
"Language.TextToSpeech~~~bg-BG~0.0.1.0",
"Language.TextToSpeech~~~ca-ES~0.0.1.0",
"Language.TextToSpeech~~~cs-CZ~0.0.1.0",
"Language.TextToSpeech~~~da-DK~0.0.1.0",
"Language.TextToSpeech~~~de-AT~0.0.1.0",
"Language.TextToSpeech~~~de-CH~0.0.1.0",
"Language.TextToSpeech~~~de-DE~0.0.1.0",
"Language.TextToSpeech~~~el-GR~0.0.1.0",
"Language.TextToSpeech~~~en-AU~0.0.1.0",
"Language.TextToSpeech~~~en-CA~0.0.1.0",
"Language.TextToSpeech~~~en-GB~0.0.1.0",
"Language.TextToSpeech~~~en-IE~0.0.1.0",
"Language.TextToSpeech~~~en-IN~0.0.1.0",
"Language.TextToSpeech~~~en-US~0.0.1.0",
"Language.TextToSpeech~~~es-ES~0.0.1.0",
"Language.TextToSpeech~~~es-MX~0.0.1.0",
"Language.TextToSpeech~~~fi-FI~0.0.1.0",
"Language.TextToSpeech~~~fr-CA~0.0.1.0",
"Language.TextToSpeech~~~fr-CH~0.0.1.0",
"Language.TextToSpeech~~~fr-FR~0.0.1.0",
"Language.TextToSpeech~~~he-IL~0.0.1.0",
"Language.TextToSpeech~~~hi-IN~0.0.1.0",
"Language.TextToSpeech~~~hr-HR~0.0.1.0",
"Language.TextToSpeech~~~hu-HU~0.0.1.0",
"Language.TextToSpeech~~~id-ID~0.0.1.0",
"Language.TextToSpeech~~~it-IT~0.0.1.0",
"Language.TextToSpeech~~~ja-JP~0.0.1.0",
"Language.TextToSpeech~~~ko-KR~0.0.1.0",
"Language.TextToSpeech~~~ms-MY~0.0.1.0",
"Language.TextToSpeech~~~nb-NO~0.0.1.0",
"Language.TextToSpeech~~~nl-BE~0.0.1.0",
"Language.TextToSpeech~~~nl-NL~0.0.1.0",
"Language.TextToSpeech~~~pl-PL~0.0.1.0",
"Language.TextToSpeech~~~pt-BR~0.0.1.0",
"Language.TextToSpeech~~~pt-PT~0.0.1.0",
"Language.TextToSpeech~~~ro-RO~0.0.1.0",
"Language.TextToSpeech~~~ru-RU~0.0.1.0",
"Language.TextToSpeech~~~sk-SK~0.0.1.0",
"Language.TextToSpeech~~~sl-SI~0.0.1.0",
"Language.TextToSpeech~~~sv-SE~0.0.1.0",
"Language.TextToSpeech~~~ta-IN~0.0.1.0",
"Language.TextToSpeech~~~th-TH~0.0.1.0",
"Language.TextToSpeech~~~tr-TR~0.0.1.0",
"Language.TextToSpeech~~~vi-VN~0.0.1.0",
"Language.TextToSpeech~~~zh-CN~0.0.1.0",
"Language.TextToSpeech~~~zh-HK~0.0.1.0",
"Language.TextToSpeech~~~zh-TW~0.0.1.0",
"MathRecognizer~~~~0.0.1.0",
"Media.WindowsMediaPlayer~~~~0.0.12.0",
"Microsoft.Onecore.StorageManagement~~~~0.0.1.0",
"Microsoft.WebDriver~~~~0.0.1.0",
"Microsoft.Windows.MSPaint~~~~0.0.1.0",
"Microsoft.Windows.Notepad~~~~0.0.1.0",
"Microsoft.Windows.PowerShell.ISE~~~~0.0.1.0",
"Microsoft.Windows.StorageManagement~~~~0.0.1.0",
"Microsoft.Windows.WordPad~~~~0.0.1.0",
"Msix.PackagingTool.Driver~~~~0.0.1.0",
"NetFX3~~~~",
"Network.Irda~~~~0.0.1.0",
"OneCoreUAP.OneSync~~~~0.0.1.0",
"OpenSSH.Client~~~~0.0.1.0",
"OpenSSH.Server~~~~0.0.1.0",
"Print.Fax.Scan~~~~0.0.1.0",
"Print.Management.Console~~~~0.0.1.0",
"RasCMAK.Client~~~~0.0.1.0",
"RIP.Listener~~~~0.0.1.0",
"Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0",
"Rsat.BitLocker.Recovery.Tools~~~~0.0.1.0",
"Rsat.CertificateServices.Tools~~~~0.0.1.0",
"Rsat.DHCP.Tools~~~~0.0.1.0",
"Rsat.Dns.Tools~~~~0.0.1.0",
"Rsat.FailoverCluster.Management.Tools~~~~0.0.1.0",
"Rsat.FileServices.Tools~~~~0.0.1.0",
"Rsat.GroupPolicy.Management.Tools~~~~0.0.1.0",
"Rsat.IPAM.Client.Tools~~~~0.0.1.0",
"Rsat.LLDP.Tools~~~~0.0.1.0",
"Rsat.NetworkController.Tools~~~~0.0.1.0",
"Rsat.NetworkLoadBalancing.Tools~~~~0.0.1.0",
"Rsat.RemoteAccess.Management.Tools~~~~0.0.1.0",
"Rsat.RemoteDesktop.Services.Tools~~~~0.0.1.0",
"Rsat.ServerManager.Tools~~~~0.0.1.0",
"Rsat.Shielded.VM.Tools~~~~0.0.1.0",
"Rsat.StorageMigrationService.Management.Tools~~~~0.0.1.0",
"Rsat.StorageReplica.Tools~~~~0.0.1.0",
"Rsat.SystemInsights.Management.Tools~~~~0.0.1.0",
"Rsat.VolumeActivation.Tools~~~~0.0.1.0",
"Rsat.WSUS.Tools~~~~0.0.1.0",
"SNMP.Client~~~~0.0.1.0",
"Tools.DeveloperMode.Core~~~~0.0.1.0",
"Tools.Graphics.DirectX~~~~0.0.1.0",
"Windows.Client.ShellComponents~~~~0.0.1.0",
"Windows.Desktop.EMS-SAC.Tools~~~~0.0.1.0",
"WMI-SNMP-Provider.Client~~~~0.0.1.0",
"XPS.Viewer~~~~0.0.1.0")


    If ($Winver -eq "2004"){$items = ($Win10_2004_FODs | Out-GridView -title "Select Features On Demand" -PassThru) }
    If ($Winver -eq "1909"){$items = ($Win10_1909_FODs | Out-GridView -title "Select Features On Demand" -PassThru) }
    If ($Winver -eq "1903"){$items = ($Win10_1903_FODs | Out-GridView -title "Select Features On Demand" -PassThru) }
    If ($Winver -eq "1809"){
        if ($WinOS -eq "Windows 10"){$items = ($Win10_1809_FODs | Out-GridView -title "Select Features On Demand" -PassThru) }
        if ($WinOS -eq "Windows Server"){$items = ($Win10_1809_server_FODs | Out-GridView -title "Select Features On Demand" -PassThru) }
  }

#(Get-ChildItem -path $LPSourceFolder | Select-Object -Property Name | Out-GridView -title "Select Local Experience Packs" -PassThru)

    if ($WinOS -eq "Windows 11"){
        $items = (get-childitem -path "$PSScriptRoot\imports\fods\Windows 11\$winver" | Select-Object -Property Name | Out-Gridview -title "Select Featres" -PassThru) 
        foreach ($item in $items){$WPFCustomLBFOD.Items.Add($item.name)}
        } 
        else{

        foreach ($item in $items){$WPFCustomLBFOD.Items.Add($item)}
        }
    }
 
#Function to apply the selected Langauge Packs to the mounted WIM
function apply-LanguagePacks{
    Update-Log -data "Applying Language Packs..." -Class Information
    if ($WPFSourceWIMImgDesTextBox.text -like '*10*'){$WinOS = "Windows 10"}
        Else
            {$WinOS = "Windows Server"}
    
    If ($WPFSourceWimVerTextBox.text -like "10.0.18362.*") { $WinVer = "1909" }
    If ($WPFSourceWimVerTextBox.text -like "10.0.17763.*") { $WinVer = "1809" }
    If ($WPFSourceWimVerTextBox.text -like "10.0.19041.*") { $WinVer = "2004" }

    $WinOS = get-windowstype
    $Winver = get-winvernum

    if (($WinOS -eq "Windows 10") -and (($winver -eq "20H2") -or ($winver -eq "21H1") -or ($winver -eq "2009"))) {$winver = "2004"}

    $mountdir = $WPFMISMountTextBox.text

$LPSourceFolder = $PSScriptRoot + '\imports\Lang\' + $WinOS + '\' + $winver + '\LanguagePacks\'
$items = $WPFCustomLBLangPacks.items

foreach ($item in $items){
    $source = $LPSourceFolder + $item

    $text = 'Applying ' + $item
    Update-Log -Data $text -Class Information
    
    try{
    Add-WindowsPackage -PackagePath $source -Path $mountdir -ErrorAction Stop | out-null
    Update-Log -Data "Injection Successful" -Class Information
    }
    catch
    {
    Update-Log -Data "Failed to inject Language Pack" -Class Error
    Update-Log -data $_.Exception.Message -Class Error
    }

    }
Update-Log -Data "Language Pack injections complete" -Class Information
}

#Function to apply selected LXPs to the mounted WIM
function apply-localexperiencepack{
     Update-Log -data "Applying Local Experience Packs..." -Class Information
    if ($WPFSourceWIMImgDesTextBox.text -like '*10*'){$WinOS = "Windows 10"}
        Else
            {$WinOS = "Windows Server"}
    
    If ($WPFSourceWimVerTextBox.text -like "10.0.18362.*") { $WinVer = "1909" }
    If ($WPFSourceWimVerTextBox.text -like "10.0.17763.*") { $WinVer = "1809" }
    If ($WPFSourceWimVerTextBox.text -like "10.0.19041.*") { $WinVer = "2004" }
    $mountdir = $WPFMISMountTextBox.text

    $WinOS = get-windowstype
    $Winver = get-winvernum

    if (($WinOS -eq "Windows 10") -and (($winver -eq "20H2") -or ($winver -eq "21H1") -or ($winver -eq "2009"))) {$winver = "2004"}

$LPSourceFolder = $PSScriptRoot + '\imports\Lang\' + $WinOS + '\' + $winver + '\localexperiencepack\'
$items = $WPFCustomLBLEP.items

foreach ($item in $items){
    $source = $LPSourceFolder + $item
    $license = get-item -Path $source\*.xml
    $file = get-item -Path $source\*.appx
    $text = 'Applying ' + $item
    Update-Log -Data $text -Class Information
    try
    {
    Add-ProvisionedAppxPackage -PackagePath $file -LicensePath $license -Path $mountdir -ErrorAction Stop| out-null
    Update-Log -Data "Injection Successful" -Class Information
    }
    catch
    {
    Update-Log -data "Failed to apply Local Experience Pack" -Class Error
    Update-Log -data $_.Exception.Message -Class Error
    }
    }
Update-Log -Data "Local Experience Pack injections complete" -Class Information
}

#Function to apply selected FODs to the mounted WIM
function apply-FODs{
    Update-Log -data "Applying Features On Demand..." -Class Information
    if ($WPFSourceWIMImgDesTextBox.text -like '*10*'){$WinOS = "Windows 10"}
        Else
            {$WinOS = "Windows Server"}
    
    If ($WPFSourceWimVerTextBox.text -like "10.0.18362.*") { $WinVer = "1909" }
    If ($WPFSourceWimVerTextBox.text -like "10.0.17763.*") { $WinVer = "1809" }
    If ($WPFSourceWimVerTextBox.text -like "10.0.19041.*") { $WinVer = "2004" }
    $mountdir = $WPFMISMountTextBox.text

    $WinOS = get-windowstype
    $Winver = get-winvernum

    if (($WinOS -eq "Windows 10") -and (($winver -eq "20H2") -or ($winver -eq "21H1") -or ($winver -eq "2009"))) {$winver = "2004"}


$FODsource = $PSScriptRoot + '\imports\FODs\' + $winOS + '\' + $Winver + '\'
$items = $WPFCustomLBFOD.items

foreach ($item in $items){
    $text = "Applying " + $item
    update-log -Data $text -Class Information
    
    try
    {
    Add-WindowsCapability -Path $mountdir -Name $item -Source $FODsource -ErrorAction Stop| out-null
    Update-Log -Data "Injection Successful" -Class Information
    }
    catch
    {
    Update-Log -data "Failed to apply Feature On Demand" -Class Error
    Update-Log -data $_.Exception.Message -Class Error
    }


    }
Update-Log -Data "Feature on Demand injections complete" -Class Information
}

#Function to import the selected LP's in to the Imports folder
Function import-LanguagePacks($Winver,$LPSourceFolder,$WinOS){
update-log -Data "Importing Language Packs..." -Class Information

#Note To Donna - Make a step that checks if $winver -eq 1903, and if so, set $winver to 1909
if ($winver -eq "1903"){
    update-log -Data "Changing version variable because 1903 and 1909 use the same packages" -Class Information
    $winver = "1909"}

if ((test-path -Path $PSScriptRoot\imports\Lang\$WinOS\$winver\LanguagePacks) -eq $False){
    Update-Log -Data "Destination folder does not exist. Creating..." -Class Warning
    $path = $PSScriptRoot + '\imports\Lang\' + $WinOS + '\' + $winver +'\LanguagePacks'
    $text = 'Creating folder ' + $path
    update-log -data $text -Class Information
    New-Item -Path $PSScriptRoot\imports\Lang\$WinOS\$winver -Name LanguagePacks -ItemType Directory
    update-log -Data "Folder created successfully" -Class Information
    }

$items = $WPFImportOtherLBList.items
foreach ($item in $items){
    $source = $LPSourceFolder + $item
    $text = 'Importing ' + $item
    update-log -Data $text -Class Information
    Copy-Item $source -destination $PSScriptRoot\imports\Lang\$WinOS\$Winver\LanguagePacks -Force}
update-log -Data "Importation Complete" -Class Information
}

#Function to import the selected LXP's into the imports forlder
Function import-LocalExperiencePack($Winver,$LPSourceFolder,$WinOS){

if ($winver -eq "1903"){
    update-log -Data "Changing version variable because 1903 and 1909 use the same packages" -Class Information
    $winver = "1909"}

update-log -Data "Importing Local Experience Packs..." -Class Information

if ((test-path -Path $PSScriptRoot\imports\Lang\$WinOS\$winver\localexperiencepack) -eq $False){
    Update-Log -Data "Destination folder does not exist. Creating..." -Class Warning
    $path = $PSScriptRoot + '\imports\Lang\' + $WinOS + '\' + $winver +'\localexperiencepack'
    $text = 'Creating folder ' + $path
    update-log -data $text -Class Information
    New-Item -Path $PSScriptRoot\imports\Lang\$WinOS\$winver -Name localexperiencepack -ItemType Directory
    update-log -Data "Folder created successfully" -Class Information
    }

$items = $WPFImportOtherLBList.items
foreach ($item in $items){
    $name = $item
    $source = $LPSourceFolder + $name
    $text = 'Creating destination folder for ' + $item
    update-log -Data $text -Class Information

    if ((test-path -Path $PSScriptRoot\imports\lang\$WinOS\$winver\localexperiencepack\$name) -eq $False){New-Item -Path $PSScriptRoot\imports\lang\$WinOS\$winver\localexperiencepack -Name $name -ItemType Directory}
        else
        {$text = 'The folder for ' + $item + ' already exists. Skipping creation...'
        Update-Log -Data $text -Class Warning}

    Update-Log -Data "Copying source to destination folders..." -Class Information   
    get-childitem -path $source | Copy-Item -destination $PSScriptRoot\imports\Lang\$WinOS\$Winver\LocalExperiencePack\$name -Force}
Update-log -Data "Importation complete" -Class Information
}

#Function to import the contents of the selected FODs into the imports forlder
Function import-FOD($Winver,$LPSourceFolder,$WinOS){

if ($winver -eq "1903"){
    update-log -Data "Changing version variable because 1903 and 1909 use the same packages" -Class Information
    $winver = "1909"}

$path = $WPFImportOtherTBPath.text
$text = 'Starting importation of Feature On Demand binaries from ' + $path
update-log -Data $text -Class Information

$langpacks = Get-ChildItem -path $LPSourceFolder 

if ((test-path -Path $PSScriptRoot\imports\FODs\$WinOS\$Winver) -eq $False){
    Update-Log -Data "Destination folder does not exist. Creating..." -Class Warning
    $path = $PSScriptRoot + '\imports\FODs\' + $WinOS + '\' + $winver
    $text = 'Creating folder ' + $path
    update-log -data $text -Class Information
    New-Item -Path $PSScriptRoot\imports\fods\$WinOS -Name $winver -ItemType Directory
    update-log -Data "Folder created successfully" -Class Information
    }
#If Windows 11

if ($WPFImportOtherCBWinOS.SelectedItem -eq "Windows 11"){
    $items = $WPFImportOtherLBList.items
        foreach ($item in $items){
        $source = $LPSourceFolder + $item
        $text = 'Importing ' + $item
        update-log -Data $text -Class Information
        Copy-Item $source -destination $PSScriptRoot\imports\FODs\$WinOS\$Winver\ -Force}

}


#If not Windows 11
if ($WPFImportOtherCBWinOS.SelectedItem -ne "Windows 11"){    
    foreach ($langpack in $langpacks){
        $source = $LPSourceFolder + $langpack.name
  
        Copy-Item $source -destination $PSScriptRoot\imports\FODs\$WinOS\$Winver\ -Force
        $name = $langpack.name
        $text = 'Copying ' + $name
        Update-Log -Data $text -Class Information

        }
    }

Update-Log -Data "Importing metadata subfolder..." -Class Information
get-childitem -path ($LPSourceFolder + '\metadata\') | Copy-Item -destination $PSScriptRoot\imports\FODs\$WinOS\$Winver\metadata -force
update-log -data "Feature On Demand imporation complete."
}

#Function to update winver cobmo box
function update-importverCB{
    $WPFImportOtherCBWinVer.Items.Clear()
    if ($WPFImportOtherCBWinOS.SelectedItem -eq "Windows Server"){Foreach ($WinSrvVer in $WinSrvVer){$WPFImportOtherCBWinVer.Items.Add($WinSrvVer)}}
    if ($WPFImportOtherCBWinOS.SelectedItem -eq "Windows 10"){Foreach ($Win10Ver in $Win10ver){$WPFImportOtherCBWinVer.Items.Add($Win10Ver)}}
    if ($WPFImportOtherCBWinOS.SelectedItem -eq "Windows 11"){Foreach ($Win11Ver in $Win11ver){$WPFImportOtherCBWinVer.Items.Add($Win11Ver)}}
}

#function to select other object import source path
function select-importotherpath{
    Add-Type -AssemblyName System.Windows.Forms
    $browser = New-Object System.Windows.Forms.FolderBrowserDialog
    $browser.Description = "Source folder"
    $null = $browser.ShowDialog()
    $ImportPath = $browser.SelectedPath + '\'
    $WPFImportOtherTBPath.text = $ImportPath

    }

#function to allow user to pause MAke it so process
function pause-makeitso{
$MISPause = ([System.Windows.MessageBox]::Show("Click Yes to continue the image build. Click No to cancel and discard the wim file.",'WIM Witch Paused','YesNo','Warning'))
    if ($MISPause -eq "Yes"){return "Yes"}
      
    if ($MISPause -eq "No"){ return "No"}
  }  

#function to run a powershell script with supplied paramenters
function run-script($file,$parameter){
    $string = "$file $parameter"
    try{
    update-log -Data "Running script" -Class Information
    Invoke-Expression -command $string -ErrorAction Stop
    update-log -data "Script complete" -Class Information
    }
    catch
    {
    update-log -Data "Script failed" -Class Error
    }
}

#function to select existing configMgr image package
function get-imageinfo{
    Param(
    [parameter(mandatory = $true)] 
    [string]$PackID

    )


   #set-ConfigMgrConnection
   cd $CMDrive
   $image = (Get-WmiObject -Namespace "root\SMS\Site_$($global:SiteCode)" -Class SMS_ImagePackage -ComputerName $global:SiteServer) | Where-Object { ($_.PackageID -eq $PackID)}

    $WPFCMTBImageName.text = $image.name
    $WPFCMTBWinBuildNum.text = $image.ImageOSversion
    $WPFCMTBPackageID.text = $image.PackageID
    $WPFCMTBImageVer.text = $image.version
    $WPFCMTBDescription.text = $image.Description

    $text = "Image " + $WPFCMTBImageName.text + " selected"
    update-log -data $text -class Information
    
    $text = "Package ID is " + $image.PackageID
    update-log -data $text -class Information

    $text = "Image build number is " + $image.ImageOSversion
    update-log -data $text -class Information

    $packageID = (Get-CMOperatingSystemImage -Id $image.PackageID)
   # $packageID.PkgSourcePath

    $WPFMISWimFolderTextBox.text = (Split-Path -Path $packageID.PkgSourcePath)
    $WPFMISWimNameTextBox.text = (Split-Path -Path $packageID.PkgSourcePath -Leaf)

    $Package = $packageID.PackageID
    $DPs = Get-CMDistributionPoint
    $NALPaths = (get-wmiobject -namespace "root\SMS\Site_$($global:SiteCode)" -ComputerName $global:SiteServer -query "SELECT * FROM SMS_DistributionPoint WHERE PackageID='$Package'")

    Update-Log -Data "Retrieving Distrbution Point Information" -Class Information
    foreach ($NALPath in $NALPaths){
        foreach ($dp in $dps){
            $DPPath = $dp.NetworkOSPath
            if ($NALPath.ServerNALPath -like ("*$DPPath*")){
            update-log -data "Image has been previously distributed to $DPPath" -class Information
            $WPFCMLBDPs.Items.Add($DPPath)
  
            }
        }
    }

    #Detect Binary Diff Replication
    update-log -data "Checking Binary Differential Replication setting" -Class Information
    if ($image.PkgFlags -eq ($image.PkgFlags -bor 0x04000000)){
        $WPFCMCBBinDirRep.IsChecked = $True}
        else{
        $WPFCMCBBinDirRep.IsChecked = $False}

    #Detect Package Share Enabled
    update-log -data "Checking package share settings" -Class Information
    if ($image.PkgFlags -eq ($image.PkgFlags -bor 0x80)){
        $WPFCMCBDeploymentShare.IsChecked = $true}
        else
        {$WPFCMCBDeploymentShare.IsChecked = $false}

    cd $PSScriptRoot
}

#function to select DP's from ConfigMgr
function select-DPs{
    #set-ConfigMgrConnection
    cd $CMDrive
    
    if ($WPFCMCBDPDPG.SelectedItem -eq 'Distribution Points'){

        $SelectedDPs = (Get-CMDistributionPoint -SiteCode $global:sitecode).NetworkOSPath | Out-GridView -title "Select Distribution Points" -PassThru
        foreach ($SelectedDP in $SelectedDPs){$WPFCMLBDPs.Items.Add($SelectedDP)}
        }
    if ($WPFCMCBDPDPG.SelectedItem -eq 'Distribution Point Groups'){     
        $SelectedDPs = (Get-CMDistributionPointGroup).Name | Out-GridView -title "Select Distribution Point Groups" -PassThru
        foreach ($SelectedDP in $SelectedDPs){$WPFCMLBDPs.Items.Add($SelectedDP)}
        }
    cd $PSScriptRoot
}

#function to create the new image in ConfigMgr
function create-CMImagePackage{
    #set-ConfigMgrConnection
    cd $CMDrive
    $Path = $WPFMISWimFolderTextBox.text + '\' + $WPFMISWimNameTextBox.text 
    
    try{
        New-CMOperatingSystemImage -Name $WPFCMTBImageName.text -Path $Path -ErrorAction Stop
        update-log -data "Image was created. Check ConfigMgr console" -Class Information
        }
    catch{
        Update-Log -data "Failed to create the image" -Class Error
        Update-Log -data $_.Exception.Message -Class Error
        }

    $PackageID = (Get-CMOperatingSystemImage -Name $WPFCMTBImageName.text).PackageID
    Update-Log -Data "The Package ID of the new image is $PackageID" -Class Information

    set-imageproperties -PackageID $PackageID

    Update-Log -Data "Retriveing Distribution Point information..." -Class Information    
    $DPs = $WPFCMLBDPs.Items

    foreach ($DP in $DPs){
       # Hello! This line was written on 3/3/2020.
        $DP = $DP -replace "\\",”"

        update-log -Data "Distributiong image package content..." -Class Information
        if ($WPFCMCBDPDPG.SelectedItem -eq 'Distribution Points'){
            Start-CMContentDistribution -OperatingSystemImageId $PackageID -DistributionPointName $DP}
        if ($WPFCMCBDPDPG.SelectedItem -eq 'Distribution Point Groups'){
            Start-CMContentDistribution -OperatingSystemImageId $PackageID -DistributionPointGroupName $DP}
        
        Update-Log -Data "Content has been distributed." -Class Information
    }
   
    save-config -CM $PackageID
    cd $PSScriptRoot
}

#Function to enable/disable options on ConfigMgr tab
function enable-ConfigMgrOptions {

    #"Disabled","New Image","Update Existing Image"
    if ($WPFCMCBImageType.SelectedItem -eq "New Image"){
        $WPFCMBAddDP.IsEnabled = $True                                                                                                                                  
        $WPFCMBRemoveDP.IsEnabled = $True                                                                            
        $WPFCMBSelectImage.IsEnabled = $False                                                                  
        $WPFCMCBBinDirRep.IsEnabled = $True                  
        $WPFCMCBDPDPG.IsEnabled = $True                                                                              
        $WPFCMLBDPs.IsEnabled = $True                                                                            
        $WPFCMTBDescription.IsEnabled = $True                                                                                                                                             
        $WPFCMTBImageName.IsEnabled = $True                                                                 
        $WPFCMTBImageVer.IsEnabled = $True                                                                    
        $WPFCMTBPackageID.IsEnabled = $False                                                                     
        $WPFCMTBSitecode.IsEnabled = $True                                                                         
        $WPFCMTBSiteServer.IsEnabled = $True                                                                  
        $WPFCMTBWinBuildNum.IsEnabled = $False
        $WPFCMCBImageVerAuto.IsEnabled = $True
        $WPFCMCBDescriptionAuto.IsEnabled = $True
        $WPFCMCBDeploymentShare.IsEnabled = $True
        
        
        $MEMCMsiteinfo = Get-ItemProperty -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\SMS\Identification"
        $WPFCMTBSiteServer.text = $MEMCMsiteinfo.'Site Server'
        $WPFCMTBSitecode.text = $MEMCMsiteinfo.'Site Code' 
        update-log -data "ConfigMgr feature enabled. New Image selected" -class Information
        update-log -data $WPFCMTBSitecode.text -class Information 
        update-log -data $WPFCMTBSiteServer.text -class Information    
    }

    if ($WPFCMCBImageType.SelectedItem -eq "Update Existing Image"){
        $WPFCMBAddDP.IsEnabled = $False                                                                                                                                    
        $WPFCMBRemoveDP.IsEnabled = $False                                                                            
        $WPFCMBSelectImage.IsEnabled = $True                                                                  
        $WPFCMCBBinDirRep.IsEnabled = $True                  
        $WPFCMCBDPDPG.IsEnabled = $False                                                                              
        $WPFCMLBDPs.IsEnabled = $False                                                                           
        $WPFCMTBDescription.IsEnabled = $True                                                                                                                                             
        $WPFCMTBImageName.IsEnabled = $False                                                                 
        $WPFCMTBImageVer.IsEnabled = $True                                                                    
        $WPFCMTBPackageID.IsEnabled = $True                                                                     
        $WPFCMTBSitecode.IsEnabled = $True                                                                         
        $WPFCMTBSiteServer.IsEnabled = $True                                                                  
        $WPFCMTBWinBuildNum.IsEnabled = $False
        $WPFCMCBImageVerAuto.IsEnabled = $True
        $WPFCMCBDescriptionAuto.IsEnabled = $True
        $WPFCMCBDeploymentShare.IsEnabled = $True          
    
        $MEMCMsiteinfo = Get-ItemProperty -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\SMS\Identification"
        $WPFCMTBSiteServer.text = $MEMCMsiteinfo.'Site Server'
        $WPFCMTBSitecode.text = $MEMCMsiteinfo.'Site Code'  
        update-log -data "ConfigMgr feature enabled. Update an existing image selected" -class Information
        update-log -data $WPFCMTBSitecode.text -class Information 
        update-log -data $WPFCMTBSiteServer.text -class Information            
    } 

    if ($WPFCMCBImageType.SelectedItem -eq "Disabled"){
        $WPFCMBAddDP.IsEnabled = $False                                                                                                                                    
        $WPFCMBRemoveDP.IsEnabled = $False                                                                            
        $WPFCMBSelectImage.IsEnabled = $False                                                                  
        $WPFCMCBBinDirRep.IsEnabled = $False                  
        $WPFCMCBDPDPG.IsEnabled = $False                                                                              
        $WPFCMLBDPs.IsEnabled = $False                                                                            
        $WPFCMTBDescription.IsEnabled = $False                                                                                                                                            
        $WPFCMTBImageName.IsEnabled = $False                                                                  
        $WPFCMTBImageVer.IsEnabled = $False                                                                    
        $WPFCMTBPackageID.IsEnabled = $False                                                                     
        $WPFCMTBSitecode.IsEnabled = $False                                                                         
        $WPFCMTBSiteServer.IsEnabled = $False                                                                  
        $WPFCMTBWinBuildNum.IsEnabled = $False
        $WPFCMCBImageVerAuto.IsEnabled = $False
        $WPFCMCBDescriptionAuto.IsEnabled = $False
        $WPFCMCBDeploymentShare.IsEnabled = $False
        update-log -data "ConfigMgr feature disabled" -class Information  
    
    } 

}

#Function to update DP's when updating existing image file in ConfigMgr
function update-CMImage {
    #set-ConfigMgrConnection
    cd $CMDrive    
    $wmi = (Get-WmiObject -Namespace "root\SMS\Site_$($global:SiteCode)" -Class SMS_ImagePackage -ComputerName $global:SiteServer) | Where-Object {$_.PackageID -eq $WPFCMTBPackageID.text}
    
    

    update-log -Data "Updating images on the Distribution Points..."
    $WMI.RefreshPkgSource() |out-null
    
    update-log -Data "Refreshing image proprties from the WIM" -Class Information
    $WMI.ReloadImageProperties() |Out-Null

    set-imageproperties -PackageID $WPFCMTBPackageID.Text
    save-config -CM -filename $WPFCMTBPackageID.Text

    cd $PSScriptRoot
}

#Function to enable disable & options on the Software Update Catalog tab
function invoke-UpdateTabOptions {

    if ($WPFUSCBSelectCatalogSource.SelectedItem -eq "None" ){
       
        $WPFUpdateOSDBUpdateButton.IsEnabled = $false
        $WPFUpdatesDownloadNewButton.IsEnabled = $false
        $WPFUpdatesW10Main.IsEnabled = $false
        $WPFUpdatesS2019.IsEnabled = $false
        $WPFUpdatesS2016.IsEnabled = $false
        
        $WPFMISCBCheckForUpdates.IsEnabled = $false
        $WPFMISCBCheckForUpdates.IsChecked = $false

        }

    if ($WPFUSCBSelectCatalogSource.SelectedItem -eq "OSDSUS") {
        $WPFUpdateOSDBUpdateButton.IsEnabled = $true
        $WPFUpdatesDownloadNewButton.IsEnabled = $true
        $WPFUpdatesW10Main.IsEnabled = $true
        $WPFUpdatesS2019.IsEnabled = $true
        $WPFUpdatesS2016.IsEnabled = $true 

        $WPFMISCBCheckForUpdates.IsEnabled = $false
        $WPFMISCBCheckForUpdates.IsChecked = $false
        update-log -data "OSDSUS selected as update catalog" -class Information
        invoke-OSDCheck

        }

    if ($WPFUSCBSelectCatalogSource.SelectedItem -eq "ConfigMgr") {
        $WPFUpdateOSDBUpdateButton.IsEnabled = $false
        $WPFUpdatesDownloadNewButton.IsEnabled = $true
        $WPFUpdatesW10Main.IsEnabled = $true
        $WPFUpdatesS2019.IsEnabled = $true
        $WPFUpdatesS2016.IsEnabled = $true         
        $WPFMISCBCheckForUpdates.IsEnabled = $true
        $MEMCMsiteinfo = Get-ItemProperty -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\SMS\Identification"
        $WPFCMTBSiteServer.text = $MEMCMsiteinfo.'Site Server'
        $WPFCMTBSitecode.text = $MEMCMsiteinfo.'Site Code' 
        update-log -data "ConfigMgr is selected as the update catalog" -Class Information

        }

}

#Function to check for updates against ConfigMgr
function invoke-MEMCMUpdatecatalog($prod,$ver){
    function Invoke-MSUpdateItemDownload {
        [CmdletBinding(SupportsShouldProcess=$true)]
        param(
            [parameter(Mandatory=$true, HelpMessage="Specify the path to where the update item will be downloaded.")]
            [ValidateNotNullOrEmpty()]
            [string]$FilePath,

            $UpdateName
        )
    #write-host $updatename
    #write-host $filepath

    $OptionalUpdateCheck = 0

#Adding in optional updates


    if ($UpdateName -like "*Adobe*"){
       $UpdateClass = "AdobeSU"
       $OptionalUpdateCheck = 1    }
    if ($UpdateName -like "*Microsoft .NET Framework*"){
       $UpdateClass = "DotNet"
       $OptionalUpdateCheck = 1}
    if ($UpdateName -like "*Cumulative Update for .NET Framework*"){
       $OptionalUpdateCheck = 1
       $UpdateClass = "DotNetCU"}
    if ($UpdateName -like "*Cumulative Update for Windows*"){
       $UpdateClass = "LCU"
       $OptionalUpdateCheck = 1}
    if ($UpdateName -like "*Cumulative Update for Microsoft*"){
       $UpdateClass = "LCU"
       $OptionalUpdateCheck = 1}
    if ($UpdateName -like "*Servicing Stack Update*"){
       $OptionalUpdateCheck = 1
       $UpdateClass = "SSU"}
    if ($UpdateName -like "*Dynamic*"){
       $OptionalUpdateCheck = 1
       $UpdateClass = "Dynamic"}

    if ($OptionalUpdateCheck -eq "0"){
 
        #update-log -data "This update appears to be optional. Skipping..." -Class Warning
        #return
        if ($WPFUpdatesCBEnableOptional.IsChecked -eq $True){update-log -data "This update appears to be optional. Downloading..." -Class Information}
            else{
            update-log -data "This update appears to be optional, but are not enabled for download. Skipping..." -Class Information
            return
            }
        #update-log -data "This update appears to be optional. Downloading..." -Class Information
        
        $UpdateClass = "Optional"
        
        }

    if ($UpdateName -like "*Windows 10*"){
    if (($UpdateName -like "* 1903 *") -or ($UpdateName -like "* 1909 *") -or ($UpdateName -like "* 2004 *") -or ($UpdateName -like "* 20H2 *")-or ($UpdateName -like "* 21H1 *")){$WMIQueryFilter = "LocalizedCategoryInstanceNames = 'Windows 10, version 1903 and later'"}
        else{$WMIQueryFilter = "LocalizedCategoryInstanceNames = 'Windows 10'"}
        if ($updateName -like "*Dynamic*"){
            if ($WPFUpdatesCBEnableDynamic.IsChecked -eq $True){$WMIQueryFilter = "LocalizedCategoryInstanceNames = 'Windows 10 Dynamic Update'"}
            }
            #else{
            #update-log -data "Dynamic updates have not been selected for downloading. Skipping..." -Class Information
            #return
            #}
        }

    if ($UpdateName -like "*Windows 11*"){
        {$WMIQueryFilter = "LocalizedCategoryInstanceNames = 'Windows 11'"}
        
        if ($updateName -like "*Dynamic*"){
            if ($WPFUpdatesCBEnableDynamic.IsChecked -eq $True){$WMIQueryFilter = "LocalizedCategoryInstanceNames = 'Windows 11 Dynamic Update'"}
            }
 
     }

        
 
    if (($UpdateName -like "*Windows Server*") -and ($ver -eq "1607")) {$WMIQueryFilter = "LocalizedCategoryInstanceNames = 'Windows Server 2016'"}
    if (($UpdateName -like "*Windows Server*") -and ($ver -eq "1809")) {$WMIQueryFilter = "LocalizedCategoryInstanceNames = 'Windows Server 2019'"}
    if (($UpdateName -like "*Windows Server*") -and ($ver -eq "21H2")){$WMIQueryFilter = "LocalizedCategoryInstanceNames = 'Microsoft Server operating system-21H2'"}


        $UpdateItem = Get-WmiObject -Namespace "root\SMS\Site_$($global:SiteCode)" -Class SMS_SoftwareUpdate -ComputerName $global:SiteServer -Filter $WMIQueryFilter -ErrorAction Stop | Where-Object { ($_.LocalizedDisplayName -eq $UpdateName) }

        if ($UpdateItem -ne $null) {

            # Determine the ContentID instances associated with the update instance
            $UpdateItemContentIDs = Get-WmiObject -Namespace "root\SMS\Site_$($global:SiteCode)" -Class SMS_CIToContent -ComputerName $global:SiteServer -Filter "CI_ID = $($UpdateItem.CI_ID)" -ErrorAction Stop
            if ($UpdateItemContentIDs -ne $null) {

                # Account for multiple content ID items
                foreach ($UpdateItemContentID in $UpdateItemContentIDs) {
                    # Get the content files associated with current Content ID
                    $UpdateItemContent = Get-WmiObject -Namespace "root\SMS\Site_$($global:SiteCode)" -Class SMS_CIContentFiles -ComputerName $global:SiteServer -Filter "ContentID = $($UpdateItemContentID.ContentID)" -ErrorAction Stop
                    if ($UpdateItemContent -ne $null) {
                        # Create new custom object for the update content
                        #write-host $UpdateItemContent.filename
                        $PSObject = [PSCustomObject]@{
                            "DisplayName" = $UpdateItem.LocalizedDisplayName
                            "ArticleID" = $UpdateItem.ArticleID
                            "FileName" = $UpdateItemContent.filename
                            "SourceURL" = $UpdateItemContent.SourceURL
                            "DateRevised" = [System.Management.ManagementDateTimeConverter]::ToDateTime($UpdateItem.DateRevised)
                        }

                       $variable = $FilePath + $UpdateClass + '\' + $UpdateName

                       if ((Test-Path -Path $variable) -eq $false){
                            update-log -Data "Creating folder $variable" -Class Information
                            New-Item -Path $variable -ItemType Directory | Out-Null
                            update-log -data "Created folder" -Class Information}
                            else{
                            $testpath = $variable + '\' + $PSObject.FileName

                            if ((test-path -Path $testpath) -eq $true){
                                update-log -Data "Update already exists. Skipping the download..." -Class Information
                                return}
                                }

                        try {
                            update-log -Data "Downloading update item content from: $($PSObject.SourceURL)" -Class Information

                            $DNLDPath = $variable + '\' + $PSObject.FileName

                            $WebClient = New-Object -TypeName System.Net.WebClient
                            $WebClient.DownloadFile($PSObject.SourceURL, $DNLDPath)
                           
                            update-log -Data "Download completed successfully, renamed file to: $($PSObject.FileName)" -Class Information
                            $ReturnValue = 0
                        }
                        catch [System.Exception] {
                            update-log -data "Unable to download update item content. Error message: $($_.Exception.Message)" -Class Error
                            $ReturnValue = 1
                        }
                    }
                    else {
                        update-log -data "Unable to determine update content instance for CI_ID: $($UpdateItemContentID.ContentID)" -Class Error
                        $ReturnValue = 1
                    }
                }
            }
            else {
                update-log -Data "Unable to determine ContentID instance for CI_ID: $($UpdateItem.CI_ID)" -Class Error
                $ReturnValue = 1
            }
        }
        else {
            update-log -data "Unable to locate update item from SMS Provider for update type: $($UpdateType)" -Class Error
            $ReturnValue = 2
        }

    
        # Handle return value from function
        return $ReturnValue | Out-Null
    }


    #set-ConfigMgrConnection
    cd $CMDrive
    $Arch = 'x64'

    if ($prod -eq 'Windows 10'){     
# if (($ver -ge '1903') -or ($ver -eq "21H1")){$WMIQueryFilter = "LocalizedCategoryInstanceNames = 'Windows 10, version 1903 and later'"}
        if (($ver -ge '1903') -or ($ver -eq "21H1") -or ($ver -eq "20H2")){$WMIQueryFilter = "LocalizedCategoryInstanceNames = 'Windows 10, version 1903 and later'"}
        if ($ver -le '1809'){$WMIQueryFilter = "LocalizedCategoryInstanceNames = 'Windows 10'"}  

        $Updates = (Get-WmiObject -Namespace "root\SMS\Site_$($global:SiteCode)" -Class SMS_SoftwareUpdate -ComputerName $global:SiteServer -Filter $WMIQueryFilter -ErrorAction Stop | Where-Object { ($_.IsSuperseded -eq $false) -and ($_.LocalizedDisplayName -like "*$($ver)*$($Arch)*")} )
        }


    if (($prod -like "*Windows Server*") -and ($ver -eq "1607")){
        $WMIQueryFilter = "LocalizedCategoryInstanceNames = 'Windows Server 2016'"  
        $Updates = (Get-WmiObject -Namespace "root\SMS\Site_$($global:SiteCode)" -Class SMS_SoftwareUpdate -ComputerName $global:SiteServer -Filter $WMIQueryFilter -ErrorAction Stop | Where-Object { ($_.IsSuperseded -eq $false) -and ($_.LocalizedDisplayName -notlike "* Next *") -and ($_.LocalizedDisplayName -notlike "*(1703)*") -and ($_.LocalizedDisplayName -notlike "*(1709)*") -and ($_.LocalizedDisplayName -notlike "*(1803)*") })
        }
   
    if (($prod -like "*Windows Server*") -and ($ver -eq "1809")){
        $WMIQueryFilter = "LocalizedCategoryInstanceNames = 'Windows Server 2019'"
        $Updates = (Get-WmiObject -Namespace "root\SMS\Site_$($global:SiteCode)" -Class SMS_SoftwareUpdate -ComputerName $global:SiteServer -Filter $WMIQueryFilter -ErrorAction Stop | Where-Object { ($_.IsSuperseded -eq $false) -and ($_.LocalizedDisplayName -like "*$($Arch)*")} )
        }
    
    if (($prod -like "*Windows Server*") -and ($ver -eq "21H2")){
            $WMIQueryFilter = "LocalizedCategoryInstanceNames = 'Microsoft Server operating system-21H2'"
            $Updates = (Get-WmiObject -Namespace "root\SMS\Site_$($global:SiteCode)" -Class SMS_SoftwareUpdate -ComputerName $global:SiteServer -Filter $WMIQueryFilter -ErrorAction Stop | Where-Object { ($_.IsSuperseded -eq $false) -and ($_.LocalizedDisplayName -like "*$($Arch)*")} )
        }

     if($prod -eq 'Windows 11'){
        $WMIQueryFilter = "LocalizedCategoryInstanceNames = 'Windows 11'"
        $Updates = (Get-WmiObject -Namespace "root\SMS\Site_$($global:SiteCode)" -Class SMS_SoftwareUpdate -ComputerName $global:SiteServer -Filter $WMIQueryFilter -ErrorAction Stop | Where-Object { ($_.IsSuperseded -eq $false) -and ($_.LocalizedDisplayName -like "*$($Arch)*") } )

        }

    if ($WPFUpdatesCBEnableDynamic.IsChecked -eq $True){

        if ($prod -eq "Windows 10"){$Updates = $Updates + (Get-WmiObject -Namespace "root\SMS\Site_$($global:SiteCode)" -Class SMS_SoftwareUpdate -ComputerName $global:SiteServer -Filter "LocalizedCategoryInstanceNames = 'Windows 10 Dynamic Update'" -ErrorAction Stop | Where-Object { ($_.IsSuperseded -eq $false) -and ($_.LocalizedDisplayName -like "*$($ver)*$($Arch)*")} )}
        if ($prod -eq "Windows 11"){$Updates = $Updates + (Get-WmiObject -Namespace "root\SMS\Site_$($global:SiteCode)" -Class SMS_SoftwareUpdate -ComputerName $global:SiteServer -Filter "LocalizedCategoryInstanceNames = 'Windows 10 Dynamic Update'" -ErrorAction Stop | Where-Object { ($_.IsSuperseded -eq $false) -and ($_.LocalizedDisplayName -like "*$prod*") -and ($_.LocalizedDisplayName -like "*$arch*") } )}
        
        
        }


    if ($updates -eq $null){
        update-log -data "No updates found. Product is likely not synchronized. Continuing with build..." -class Warning
        cd $PSScriptRoot
        return}
 
 
    foreach ($update in $updates){
        if ((($update.localizeddisplayname -notlike "Feature update*") -and ($update.localizeddisplayname -notlike "Upgrade to Windows 11*" )) -and ($update.localizeddisplayname -notlike "*Language Pack*")){
            update-log -Data "Checking the following update:" -Class Information
            update-log -data $update.localizeddisplayname -Class Information
            #write-host "Display Name"
            #write-host $update.LocalizedDisplayName
# if ($ver -eq "20H2"){$ver = "2009"} #Another 20H2 naming work around
            Invoke-MSUpdateItemDownload -FilePath "$PSScriptRoot\updates\$Prod\$ver\" -UpdateName $update.LocalizedDisplayName
        }
    }

    cd $PSScriptRoot
}

#Function to check for supersedence against ConfigMgr
function invoke-MEMCMUpdateSupersedence($prod,$Ver){
    #set-ConfigMgrConnection
    cd $CMDrive    
    $Arch = 'x64'
    
    if (($prod -eq 'Windows 10') -and (($ver -ge '1903') -or ($ver -eq "20H2") -or ($ver -eq "21H1"))){$WMIQueryFilter = "LocalizedCategoryInstanceNames = 'Windows 10, version 1903 and later'"}
    if (($prod -eq 'Windows 10') -and ($ver -le '1809')){$WMIQueryFilter = "LocalizedCategoryInstanceNames = 'Windows 10'"}  
    if (($prod -eq 'Windows Server') -and ($ver = "1607")){$WMIQueryFilter = "LocalizedCategoryInstanceNames = 'Windows Server 2016'"}  
    if (($prod -eq 'Windows Server') -and ($ver -eq "1809")){$WMIQueryFilter = "LocalizedCategoryInstanceNames = 'Windows Server 2019'"} 
    if (($prod -eq 'Windows Server') -and ($ver -eq "21H2")){$WMIQueryFilter = "LocalizedCategoryInstanceNames = 'Microsoft Server operating system-21H2'"} 

    update-log -data "Checking files for supersedense..."  -Class Information
  
    if((test-path -path "$PSScriptRoot\updates\$Prod\$ver\") -eq $False){
        update-log -Data "Folder doesnt exist. Skipping supersedence check..." -Class Warning
        return
        }

  #For every folder under updates\prod\ver
    $FolderFirstLevels = get-childitem -Path "$PSScriptRoot\updates\$Prod\$ver\"
    foreach ($FolderFirstLevel in $FolderFirstLevels){

        #For every folder under updates\prod\ver\class
        $FolderSecondLevels = get-childitem -Path "$PSScriptRoot\updates\$Prod\$ver\$FolderFirstLevel"
        foreach ($FolderSecondLevel in $FolderSecondLevels){
 
        #for every cab under updates\prod\ver\class\update
        $UpdateCabs = (Get-ChildItem -Path "$PSScriptRoot\updates\$Prod\$ver\$FolderFirstLevel\$FolderSecondLevel")
            foreach ($UpdateCab in $UpdateCabs){
                update-log -data "Checking update file name $UpdateCab" -Class Information
                $UpdateItem = Get-WmiObject -Namespace "root\SMS\Site_$($global:SiteCode)" -Class SMS_SoftwareUpdate -ComputerName $global:SiteServer -Filter $WMIQueryFilter -ErrorAction Stop | Where-Object { ($_.LocalizedDisplayName -eq $FolderSecondLevel) }
            
                if ($UpdateItem.IsSuperseded -eq $false){
                    
                    update-log -data "Update $FolderSecondLevel is current" -Class Information
                    }
                    else{
                    update-log -Data "Update $UpdateCab is superseded. Deleting file..." -Class Warning
                    Remove-Item -Path "$PSScriptRoot\updates\$Prod\$ver\$FolderFirstLevel\$FolderSecondLevel\$UpdateCab" 
                    }          
                }
            }
        }

        update-log -Data "Cleaning folders..." -Class Information
        $FolderFirstLevels = get-childitem -Path "$PSScriptRoot\updates\$Prod\$ver\"
        foreach ($FolderFirstLevel in $FolderFirstLevels){

        #For every folder under updates\prod\ver\class
        $FolderSecondLevels = get-childitem -Path "$PSScriptRoot\updates\$Prod\$ver\$FolderFirstLevel"
        foreach ($FolderSecondLevel in $FolderSecondLevels){

        #for every cab under updates\prod\ver\class\update
        $UpdateCabs = (Get-ChildItem -Path "$PSScriptRoot\updates\$Prod\$ver\$FolderFirstLevel\$FolderSecondLevel")
        
        if($UpdateCabs -eq $null){
            update-log -Data "$FolderSecondLevel is empty. Deleting...." -Class Warning
            Remove-Item -Path "$PSScriptRoot\updates\$Prod\$ver\$FolderFirstLevel\$FolderSecondLevel"
            }
        }
    }
    
    cd $PSSCriptRoot
}

#Function to update source from ConfigMgr when Making It So
function invoke-MISUpdates{
    
    $OS = get-Windowstype
    $ver = get-winvernum

    if ($ver -eq "2009"){$ver = "20H2"}

    invoke-MEMCMUpdateSupersedence -prod $OS -Ver $ver
    invoke-MEMCMUpdatecatalog -prod $OS -ver $ver

    #fucking 2009 to 20h2

}

#Function to run the osdsus and osdupdate update check functions
function invoke-OSDCheck{

        Get-OSDBInstallation #Sets OSDUpate version info
        Get-OSDBCurrentVer #Discovers current version of OSDUpdate
        compare-OSDBuilderVer #determines if an update of OSDUpdate can be applied
        get-osdsusinstallation #Sets OSDSUS version info
        Get-OSDSUSCurrentVer #Discovers current version of OSDSUS
        compare-OSDSUSVer #determines if an update of OSDSUS can be applied
}

#Function to update image version, properties, and binary delta replication
function set-imageproperties($PackageID){
    #write-host $PackageID
    #set-ConfigMgrConnection
    cd $CMDrive
    
    #Version Text Box
    if ($WPFCMCBImageVerAuto.IsChecked -eq $true)
        {
        $string = "Built " + (get-date -DisplayHint Date)
        update-log -Data "Updating image version to $string" -Class Information
        Set-CMOperatingSystemImage -Id $PackageID -Version $string
        }

    if ($WPFCMCBImageVerAuto.IsChecked -eq $false)
        {
    
        if ($WPFCMTBImageVer.text -ne $null){
            Update-Log -Data "Updating version of the image..." -Class Information
            Set-CMOperatingSystemImage -Id $PackageID -Version $WPFCMTBImageVer.text}
        }

    #Description Text Box
    if ($WPFCMCBDescriptionAuto.IsChecked -eq $true)
        {
        $string = "This image contains the following customizations: "
        if ($WPFUpdatesEnableCheckBox.IsChecked -eq $true){$string = $string + "Software Updates, "}
        if ($WPFCustomCBLangPacks.IsChecked -eq $true){$string = $string + "Language Packs, "}
        if ($WPFCustomCBLEP.IsChecked -eq $true){$string = $string + "Local Experience Packs, "}
        if ($WPFCustomCBFOD.IsChecked -eq $true){$string = $string + "Features on Demand, "}
        if ($WPFMISDotNetCheckBox.IsChecked -eq $true){$string = $string + ".Net 3.5, "}
        if ($WPFMISOneDriveCheckBox.IsChecked -eq $true){$string = $string + "OneDrive Consumer, "}
        if ($WPFAppxCheckBox.IsChecked -eq $true){$string = $string + "APPX Removal, "}
        if ($WPFDriverCheckBox.IsChecked -eq $true){$string = $string + "Drivers, "}
        if ($WPFJSONEnableCheckBox.IsChecked -eq $true){$string = $string + "Autopilot, "}
        if ($WPFCustomCBRunScript.IsChecked -eq $true){$string = $string + "Custom Script, "}
        update-log -data "Setting image description..." -Class Information
        Set-CMOperatingSystemImage -Id $PackageID -Description $string
        }

    if ($WPFCMCBDescriptionAuto.IsChecked -eq $false){
 
        if ($WPFCMTBDescription.Text -ne $null){
            update-log -Data "Updating description of the image..." -Class Information
            Set-CMOperatingSystemImage -Id $PackageID -Description $WPFCMTBDescription.Text}
    }

    #Check Box properties
    #Binary Differnential Replication
    if ($WPFCMCBBinDirRep.IsChecked -eq $true){
        update-log -Data "Enabling Binary Differential Replication" -Class Information
        Set-CMOperatingSystemImage -Id $PackageID -EnableBinaryDeltaReplication $true}
        else{
        update-log -Data "Disabling Binary Differential Replication" -Class Information
        Set-CMOperatingSystemImage -Id $PackageID -EnableBinaryDeltaReplication $false}
 
    #Package Share
    if ($WPFCMCBDeploymentShare.IsChecked -eq $true){
        update-log -Data "Enabling Package Share" -Class Information
        Set-CMOperatingSystemImage -Id $PackageID -CopyToPackageShareOnDistributionPoint $true}
        else{
        update-log -Data "Disabling Package Share" -Class Information
        Set-CMOperatingSystemImage -Id $PackageID -CopyToPackageShareOnDistributionPoint $false}


        }

#Function to detect and set CM site properties
function detect-configmgr(){

try{

    $MEMCMsiteinfo = Get-ItemProperty -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\SMS\Identification" -ErrorAction Stop
   
    $WPFCMTBSiteServer.text = $MEMCMsiteinfo.'Site Server'
    $WPFCMTBSitecode.text = $MEMCMsiteinfo.'Site Code'

    $global:SiteCode = $WPFCMTBSitecode.text
    $global:SiteServer = $WPFCMTBSiteServer.Text
    $global:CMDrive = $WPFCMTBSitecode.text + ':' 

    update-log -Data "ConfigMgr detected and properties set" -Class Information
    update-log -Data "ConfigMgr feature enabled" -Class Information
    $sitecodetext = "Site Code - " + $WPFCMTBSitecode.text
    update-log -Data $sitecodetext -Class Information
    $siteservertext = "Site Server - " + $WPFCMTBSiteServer.text
    update-log -Data $siteservertext -Class Information
    if ($CM -eq "New"){
        $WPFCMCBImageType.SelectedIndex = 1
        enable-ConfigMgrOptions}

    return 0
}

catch
{
    update-log -Data "ConfigMgr not detected" -Class Information
    $WPFCMTBSiteServer.text = "Not Detected"
    $WPFCMTBSitecode.text = "Not Detected"
    return 1
}

}

#Function to detect and import CM PowerShell module
function import-CMModule(){
        try
        {
            $path = (($env:SMS_ADMIN_UI_PATH -replace "i386", "") + "ConfigurationManager.psd1")
            Import-Module $path -ErrorAction Stop
            update-log -Data "ConfigMgr PowerShell module imported" -Class Information
            return 0
        }

        catch
        {
                Update-Log -Data "Could not import CM PowerShell module." -Class Warning
                return 1}
        }

#function to apply the start menu layout
function apply-startlayout{
    try{
    $startpath = $WPFMISMountTextBox.Text + "\users\default\appdata\local\microsoft\windows\shell"
    update-log -Data "Copying the start menu file..." -Class Information
    copy-item $WPFCustomTBStartMenu.Text -Destination $startpath -ErrorAction Stop
    $filename = (Split-Path -Path $WPFCustomTBStartMenu.Text -Leaf)

    $OS = $Windowstype

    if ($os -eq "Windows 11"){
        if ($filename -ne "LayoutModification.json"){
            $newpath = $startpath + "\" + $filename
            Update-Log -Data "Renaming json file..." -Class Warning
            Rename-Item -Path $newpath -NewName "LayoutModification.json"
            update-log -Data "file renamed to LayoutModification.json" -Class Information
        }
    }        

    if ($os -ne "Windows 11"){
        if ($filename -ne "LayoutModification.xml"){
            $newpath = $startpath + "\" + $filename
            Update-Log -Data "Renaming xml file..." -Class Warning
            Rename-Item -Path $newpath -NewName "LayoutModification.xml"
            update-log -Data "file renamed to LayoutModification.xml" -Class Information
        }
    }  

 
 
    }
    catch{
    update-log -Data "Couldn't apply the start menu XML" -Class Error
    Update-Log -data $_.Exception.Message -Class Error
    }
}

#function to apply the default application association
function apply-defaultapp{
    try{
    Update-Log -Data "Applying Default Application Association XML..."
    "Dism.exe /image:$WPFMISMountTextBox.text /Import-DefaultAppAssociations:$WPFCustomTBDefaultApp.text"
    Update-log -data "Default Application Association applied" -Class Information

    }
    catch{
    Update-Log -Data "Could not apply Default Appklication Association XML..." -Class Error
    Update-Log -data $_.Exception.Message -Class Error
    }
}

#function to select default app association xml
function select-defaultapp{

    $Sourcexml = New-Object System.Windows.Forms.OpenFileDialog -Property @{ 
        InitialDirectory = [Environment]::GetFolderPath('Desktop') 
        Filter           = 'XML (*.xml)|'
    }
    $null = $Sourcexml.ShowDialog()
    $WPFCustomTBDefaultApp.text = $Sourcexml.FileName


    if ($Sourcexml.FileName -notlike "*.xml") {
        update-log -Data "A XML file not selected. Please select a valid file to continue." -Class Warning
        return
    }
    $text = $WPFCustomTBDefaultApp.text + " selected as the default application XML"
    Update-Log -Data $text -class Information
}

#function to select start menu xml
function select-startmenu{
    
    $OS = get-windowstype
    
    if ($OS -ne "Windows 11"){
    $Sourcexml = New-Object System.Windows.Forms.OpenFileDialog -Property @{ 
        InitialDirectory = [Environment]::GetFolderPath('Desktop') 
        Filter           = 'XML (*.xml)|'
        }
    }
    
    if ($OS -eq "Windows 11"){
    $Sourcexml = New-Object System.Windows.Forms.OpenFileDialog -Property @{ 
        InitialDirectory = [Environment]::GetFolderPath('Desktop') 
        Filter           = 'JSON (*.JSON)|'
        }
    }

    $null = $Sourcexml.ShowDialog()
    $WPFCustomTBStartMenu.text = $Sourcexml.FileName

    if ($OS -ne "Windows 11"){
        if ($Sourcexml.FileName -notlike "*.xml") {
            update-log -Data "A XML file not selected. Please select a valid file to continue." -Class Warning
            return
        }
    }

    if ($OS -eq "Windows 11"){
        if ($Sourcexml.FileName -notlike "*.json") {
            update-log -Data "A JSON file not selected. Please select a valid file to continue." -Class Warning
            return
        }
    }




    $text = $WPFCustomTBStartMenu.text + " selected as the start menu file"
    Update-Log -Data $text -class Information
}

#function to select registry files
function select-regfiles{
    
    $Regfiles = New-Object System.Windows.Forms.OpenFileDialog -Property @{ 
        InitialDirectory = [Environment]::GetFolderPath('Desktop')
        Multiselect = $true # Multiple files can be chosen
        Filter           = 'REG (*.reg)|'
    }
    $null = $Regfiles.ShowDialog()

    $filepaths = $regfiles.FileNames
    update-log -data "Importing REG files..." -class information
    foreach ($filepath in $filepaths){
        if ($filepath -notlike "*.reg"){
            update-log -Data $filepath -Class Warning
            update-log -Data "Ignoring this file as it is not a .REG file...." -Class Warning
            return }
        update-log -Data $filepath -Class Information
        $WPFCustomLBRegistry.Items.Add($filepath)
        }
    update-log -data "REG file importation complete" -class information
       
    #Fix this shit, then you can release her.
}

#function to apply registry files to mounted image
function apply-regfiles{
    
    #mount offline hives
    update-log -Data "Mounting the offline registry hives..." -Class Information
   
    try{
        $Path = $WPFMISMountTextBox.text + "\Users\Default\NTUser.dat"
        Update-Log -Data $path -Class Information
        Invoke-Command {reg load HKLM\OfflineDefaultUser $Path} -ErrorAction Stop | Out-Null
    
        $Path = $WPFMISMountTextBox.text + "\Windows\System32\Config\DEFAULT"
        Update-Log -Data $path -Class Information
        Invoke-Command {reg load HKLM\OfflineDefault $Path} -ErrorAction Stop | Out-Null
    
        $Path = $WPFMISMountTextBox.text + "\Windows\System32\Config\SOFTWARE"
        Update-Log -Data $path -Class Information
        Invoke-Command {reg load HKLM\OfflineSoftware $Path} -ErrorAction Stop | Out-Null
    
        $Path = $WPFMISMountTextBox.text + "\Windows\System32\Config\SYSTEM"
        Update-Log -Data $path -Class Information
        Invoke-Command {reg load HKLM\OfflineSystem $Path} -ErrorAction Stop | Out-Null
        }
    catch{
        update-log -Data "Failed to mount $Path" -Class Error
        Update-Log -data $_.Exception.Message -Class Error
        }

    #get reg files from list box
    $RegFiles = $WPFCustomLBRegistry.items

    #For Each to process Reg Files and Apply
    Update-Log -Data "Processing Reg Files..." -Class Information
    foreach ($RegFile in $Regfiles){
 
        update-log -Data $RegFile -Class Information 
        #write-host $RegFile

        Try{
            $Destination = $PSScriptRoot + "\staging\"
            Update-Log -Data "Copying file to staging folder..." -Class Information
            Copy-Item -Path $regfile -Destination $Destination -Force -ErrorAction Stop  #Copy Source Registry File to staging
            }
        Catch{
            Update-Log -Data "Couldn't copy reg file" -Class Error
            Update-Log -data $_.Exception.Message -Class Error
            }
        
        $regtemp = Split-Path $regfile -leaf #get file name
        $regpath = $PSScriptRoot + '\staging' + '\' + $regtemp

       # Write-Host $regpath
       Try{
            Update-Log -Data "Parsing reg file..."
           ((Get-Content -path $regpath -Raw) -replace 'HKEY_CURRENT_USER','HKEY_LOCAL_MACHINE\OfflineDefaultUser') | Set-Content -Path $regpath -ErrorAction Stop
           ((Get-Content -path $regpath -Raw) -replace 'HKEY_LOCAL_MACHINE\\SOFTWARE','HKEY_LOCAL_MACHINE\OfflineSoftware') | Set-Content -Path $regpath -ErrorAction Stop
           ((Get-Content -path $regpath -Raw) -replace 'HKEY_LOCAL_MACHINE\\SYSTEM','HKEY_LOCAL_MACHINE\OfflineSystem') | Set-Content -Path $regpath -ErrorAction Stop
           ((Get-Content -path $regpath -Raw) -replace 'HKEY_USERS\\.DEFAULT','HKEY_LOCAL_MACHINE\OfflineDefault') | Set-Content -Path $regpath -ErrorAction Stop
           }
        Catch{
            Update-log -Data "Couldn't read or update reg file $regpath" -Class Error
            Update-Log -data $_.Exception.Message -Class Error
        }

        update-log -Data "Reg file has been parsed" -Class Information

        #import the registry file
        
        Try{
            update-log -Data "Importing registry file into mounted wim" -Class Information
            Start-Process reg -ArgumentList ('import',"`"$RegPath`"") -Wait -WindowStyle Hidden -ErrorAction stop
            update-log -Data "Import successful" -Class Information
            }
        Catch{
            update-log -Data "Couldn't import $Regpath" -Class Error
            Update-Log -data $_.Exception.Message -Class Error

        }
    }


    #dismount offline hives
    try{
        Update-Log -Data "Dismounting registry..." -Class Information
        Invoke-Command {reg unload HKLM\OfflineDefaultUser} -ErrorAction Stop | Out-Null
        Invoke-Command {reg unload HKLM\OfflineDefault} -ErrorAction Stop | Out-Null
        Invoke-Command {reg unload HKLM\OfflineSoftware} -ErrorAction Stop | Out-Null
        Invoke-Command {reg unload HKLM\OfflineSystem} -ErrorAction Stop | Out-Null
        update-log -Data "Dismount complete" -Class Information
        }
    catch{
        update-log -Data "Couldn't dismount the registry hives" -Class Error
        update-log -Data "This will prevent the Windows image from properly dismounting" -Class Error
        Update-Log -data $_.Exception.Message -Class Error

    }

}

#function to augment close out window text
function invoke-dadjoke {
$header = @{accept="Application/json"}
$joke =  Invoke-RestMethod -Uri "https://icanhazdadjoke.com" -Method Get -Headers $header
return $joke.joke
}

#Function to stage and build installer media
function stage-isomedia{
    if($WPFSourceWIMImgDesTextBox.Text -like '*Windows 10*'){$OS = 'Windows 10'}
    if($WPFSourceWIMImgDesTextBox.Text -like '*Server*'){$OS = 'Windows Server'}
   
   
    #$Ver = (get-winvernum)
    $Ver = $MISWinVer

    
    #create staging folder
    try{
        update-log -Data "Creating staging folder for media" -Class Information
        new-item -path $PSScriptRoot\staging -name "Media" -ItemType Directory -ErrorAction Stop | out-null
        update-log -Data "Media staging folder has been created" -Class Information
        }
    catch{
        Update-Log -Data "Could not create staging folder" -Class Error
        Update-Log -data $_.Exception.Message -class Error
    }

    #copy source to staging
    try{
        update-log -data "Staging media binaries..." -Class Information
        copy-item -Path $PSScriptRoot\imports\iso\$OS\$Ver\* -Destination $PSScriptRoot\staging\media -Force -Recurse -ErrorAction Stop
        update-log -data "Media files have been staged" -Class Information
        }
    catch{
        Update-Log -Data "Failed to stage media binaries..." -Class Error
        Update-Log -data $_.Exception.Message -class Error
        }

}

#function to create the ISO file from staged installer media
function create-iso{
       
    if ((Test-Path -Path ${env:ProgramFiles(x86)}'\Windows Kits\10\Assessment and Deployment Kit\Deployment Tools\amd64\Oscdimg\oscdimg.exe' -PathType Leaf) -eq $false){
        update-log -Data "The file oscdimg.exe was not found. Skipping ISO creation..." -Class Error
        return 
    }

    If ($WPFMISTBISOFileName.Text -notlike "*.iso") {

        $WPFMISTBISOFileName.Text = $WPFMISTBISOFileName.Text + ".iso"
        update-log -Data "Appending new file name with an extension" -Class Information
    }

    $Location = ${env:ProgramFiles(x86)}
    $executable = $location + '\Windows Kits\10\Assessment and Deployment Kit\Deployment Tools\amd64\Oscdimg\oscdimg.exe'
    $bootbin = $PSScriptRoot + '\staging\media\efi\microsoft\boot\efisys.bin'
    $source = $PSScriptRoot + '\staging\media'
    $folder = $WPFMISTBFilePath.text
    $file = $WPFMISTBISOFileName.text
    $dest = "$folder\$file"
    $text = "-b$bootbin"

    if ((test-path -Path $dest) -eq $true){replace-name -file $dest -extension ".iso"}
    try{
        update-log -Data "Starting to build ISO..." -Class Information
       # write-host $executable
        Start-Process $executable -args @("`"$text`"",'-pEF','-u1','-udfver102',"`"$source`"","`"$dest`"") -wait -ErrorAction Stop
        update-log -Data "ISO has been built" -Class Information
    }
    catch
    {
        update-log -Data "Couldn't create the ISO file" -Class Error
        Update-Log -data $_.Exception.Message -class Error
    }
}

#function to copy staged installer media to CM Package Share
function copy-upgradepackage{
    #copy staging folder to destination with force parameter
    try{
        update-log -data "Copying updated media to Upgrade Package folder..." -Class Information
        Copy-Item -Path $PSScriptRoot\staging\media\* -Destination $WPFMISTBUpgradePackage.text -Force -Recurse -ErrorAction Stop
        update-log -Data "Updated media has been copied" -Class Information
    }
    catch
    {
        update-log -Data "Couldn't copy the updated media to the upgrade package folder" -Class Error
        Update-Log -data $_.Exception.Message -class Error
    }

}

#function to update the boot wim in the staged installer media folder
function update-bootwim{
    #create mount point in staging
    
    try{
        update-log -Data "Creating mount point in staging folder..."
        New-Item -Path $PSScriptRoot\staging -Name "mount" -ItemType Directory -ErrorAction Stop
        update-log -Data "Staging folder mount point created successfully" -Class Information
        }
    catch{
        update-log -data "Failed to create the staging folder mount point" -Class Error
        Update-Log -data $_.Exception.Message -class Error
        return    
    }


    #change attribute of boot.wim
    #Change file attribute to normal
    Update-Log -Data "Setting file attribute of boot.wim to Normal" -Class Information
    $attrib = Get-Item $PSScriptRoot\staging\media\sources\boot.wim
    $attrib.Attributes = 'Normal'
    
    $BootImages = Get-WindowsImage -ImagePath $PSScriptRoot\staging\media\sources\boot.wim
    Foreach ($BootImage in $BootImages){
        
        #Mount the PE Image
        try{
            $text = "Mounting PE image number " + $BootImage.ImageIndex
            update-log -data $text -Class Information
            Mount-WindowsImage -ImagePath $PSScriptRoot\staging\media\sources\boot.wim -Path $PSScriptRoot\staging\mount -Index $BootImage.ImageIndex -ErrorAction Stop
        }
        catch{
            Update-Log -Data "Could not mount the boot.wim" -Class Error
            Update-Log -data $_.Exception.Message -class Error
            return
        }

        update-log -data "Applying SSU Update" -Class Information
        Apply-Updates -class 'PESSU'
        update-log -data "Applying LCU Update" -Class Information
        Apply-Updates -class 'PELCU'

        #Dismount the PE Image
        try{
            update-log -data "Dismounting Windows PE image..." -Class Information
            Dismount-WindowsImage -Path $PSScriptRoot\staging\mount -Save -ErrorAction Stop
        }
        catch{
            update-log -data "Could not dismount the winpe image." -Class Error
            Update-Log -data $_.Exception.Message -class Error
        }
        
        #Export the WinPE Image
        Try{
            update-log -data "Exporting WinPE image index..." -Class Information
            Export-WindowsImage -SourceImagePath $PSScriptRoot\staging\media\sources\boot.wim -SourceIndex $BootImage.ImageIndex -DestinationImagePath $PSScriptRoot\staging\tempboot.wim -ErrorAction Stop
        }
        catch{
            Update-Log -Data "Failed to export WinPE image" -Class Error
            Update-Log -data $_.Exception.Message -class Error
            }

    }

    #Overwrite the stock boot.wim file with the updated one
    try{
        update-log -Data "Overwriting boot.wim with updated and optimized version..." -Class Information
        move-item -path $PSScriptRoot\staging\tempboot.wim -Destination $PSScriptRoot\staging\media\sources\boot.wim -Force -ErrorAction Stop
        update-log -Data "Boot.WIM updated successfully" -Class Information
        }
    catch{
        update-log -Data "Could not copy the updated boot.wim" -Class Error
        Update-Log -data $_.Exception.Message -class Error
        }
}

#function to update windows recovery in the mounted offline image
function update-winrewim {
    #create mount point in staging
    #copy winre from mounted offline image
    #change attribute of winre.wim
    #mount staged winre.wim
    #update, dismount
    #copy wim back to mounted offline image
}

#function to retrieve windows version
function get-winvernum{
    If ($WPFSourceWimVerTextBox.text -like "10.0.14393.*") { $buildnum = 1607 }
    If ($WPFSourceWimVerTextBox.text -like "10.0.17763.*") { $buildnum = 1809 }
    If ($WPFSourceWimVerTextBox.text -like "10.0.17134.*") { $buildnum = 1803 }
    If ($WPFSourceWimVerTextBox.text -like "10.0.16299.*") { $buildnum = 1709 }
# If ($WPFSourceWimVerTextBox.text -like "10.0.19041.*") { $buildnum = 2004 }
    If ($WPFSourceWimVerTextBox.text -like "10.0.22000.*") { $buildnum = "21H2" }
    If ($WPFSourceWimVerTextBox.text -like "10.0.20348.*") { $buildnum = "21H2" }

  
    If ($WPFSourceWimVerTextBox.text -like "10.0.18362.*") { 
            $IsMountPoint = $False
            $currentmounts = get-windowsimage -Mounted
            foreach ($currentmount in $currentmounts) {
                if ($currentmount.path -eq $WPFMISMountTextBox.text) { $IsMountPoint = $true } 
    }

        #IS a mount path
        If ($IsMountPoint -eq $true){
            $mountdir = $WPFMISMountTextBox.Text
            reg LOAD HKLM\OFFLINE $mountdir\Windows\System32\Config\SOFTWARE | Out-Null
            $regvalues = (Get-ItemProperty -Path "Registry::HKEY_LOCAL_MACHINE\OFFLINE\Microsoft\Windows NT\CurrentVersion\" )
            $buildnum = $regvalues.ReleaseId
            reg UNLOAD HKLM\OFFLINE | Out-Null}

        If ($IsMountPoint -eq $False){
            # $windowsver = Get-WindowsImage -ImagePath ($PSScriptRoot + '\staging\' + $WPFMISWimNameTextBox.text) -Index 1
              $windowsver = Get-WindowsImage -ImagePath ($WPFSourceWIMSelectWIMTextBox.text) -Index 1
              $Vardate = (Get-Date -Year 2019 -Month 10 -Day 01)
              if ($windowsver.CreatedTime -gt $vardate){$buildnum = 1909}
                else
                {$buildnum = 1903}
        } 
    }

    If ($WPFSourceWimVerTextBox.text -like "10.0.19041.*") { 
            $IsMountPoint = $False
            $currentmounts = get-windowsimage -Mounted
            foreach ($currentmount in $currentmounts) {
                if ($currentmount.path -eq $WPFMISMountTextBox.text) { $IsMountPoint = $true } 
            }

        #IS a mount path
        If ($IsMountPoint -eq $true){
            $mountdir = $WPFMISMountTextBox.Text
            reg LOAD HKLM\OFFLINE $mountdir\Windows\System32\Config\SOFTWARE | Out-Null
            $regvalues = (Get-ItemProperty -Path "Registry::HKEY_LOCAL_MACHINE\OFFLINE\Microsoft\Windows NT\CurrentVersion\" )
            $buildnum = $regvalues.ReleaseId
            if ($regvalues.ReleaseId -eq "2009"){
                if ($regvalues.CurrentBuild -eq "19042"){$buildnum = "2009"}
                if ($regvalues.CurrentBuild -eq "19043"){$buildnum = "21H1"}
                }
            
            reg UNLOAD HKLM\OFFLINE | Out-Null
           
            
            }

        If ($IsMountPoint -eq $False){
# $windowsver = Get-WindowsImage -ImagePath ($PSScriptRoot + '\staging\' + $WPFMISWimNameTextBox.text) -Index 1
              $windowsver = Get-WindowsImage -ImagePath ($WPFSourceWIMSelectWIMTextBox.text) -Index 1

              $Vardate = (Get-Date -Year 2020 -Month 09 -Day 01)

              if ($windowsver.CreatedTime -gt $vardate){$buildnum = 2009}
                else
                {$buildnum = 2004}
        } 
    }
    return $buildnum
}

#funcation to select ISO creation path
Function SelectISODir {

    Add-Type -AssemblyName System.Windows.Forms
    $browser = New-Object System.Windows.Forms.FolderBrowserDialog
    $browser.Description = "Select the folder to save the ISO"
    $null = $browser.ShowDialog()
    $MountDir = $browser.SelectedPath
    $WPFMISTBFilePath.text = $MountDir 
    #check-mountpath -path $WPFMISMountTextBox.text
    update-log -Data "ISO directory selected" -Class Information
}

#function to determine if WIM is Win10 or Windows Server
function get-windowstype{
    if ($WPFSourceWIMImgDesTextBox.text -like "*Windows 10*"){$type = "Windows 10"}
    if ($WPFSourceWIMImgDesTextBox.text -like "*Windows Server*"){$type = "Windows Server"}
    if ($WPFSourceWIMImgDesTextBox.text -like "*Windows 11*"){$type = "Windows 11"}

    Return $type
    }

#function to check if ISO binaries exist
function check-isobinariesexist{
    $buildnum = get-winvernum
    $OSType = get-Windowstype


    $ISOFiles = $PSScriptRoot + '\imports\iso\' + $OSType + '\' + $buildnum + '\'

    Test-Path -Path $ISOFiles\* 
    if ((Test-Path -Path $ISOFiles\*) -eq $false) {
        $text = "ISO Binaries are not present for " + $OSType + " " + $buildnum
        update-log -Data $text -Class Warning
        update-log -data "Import ISO Binaries from an ISO or disable ISO/Upgrade Package creation" -Class Warning
        return $false
        }
}

#function to clear partial checkboxes when importing config file
function invoke-checkboxcleanup{
    update-log -Data "Cleaning null checkboxes..." -Class Information
    $Variables = Get-Variable WPF*
    foreach ($variable in $variables){

        if ($variable.value -like "*.CheckBox*"){
            #write-host $variable.name
            #write-host $variable.value.IsChecked
            if ($variable.value.IsChecked -ne $true){$variable.value.IsChecked = $false}
        }
    }
} 

#Function to really make sure the ISO mount is gone!
Function invoke-removeISOmount ($inputObject) {
    DO{
        Dismount-DiskImage -InputObject $inputObject
    }
    while(Dismount-DiskImage -InputObject $inputObject)
    #He's dead Jim!
    update-log -data "Dismount complete" -class Information
}

#Function to check for available free space
function check-freespace{

    $Drive = $PSScriptRoot.Substring(0,2)

    $DriveInfo = (Get-WmiObject -Class Win32_logicaldisk -filter "DeviceID = '$Drive'")

    if ($driveinfo.freespace -lt 20000000000){return 1}
        Else
        {return 0}
}

#Function to install CM Console extensions
function install-WWCMConsoleExtension{
    $UpdateWWXML = @"
<ActionDescription Class ="Executable" DisplayName="Update with WIM Witch" MnemonicDisplayName="Update with WIM Witch" Description="Click to update the image with WIM Witch">
    <ShowOn>
        <string>ContextMenu</string>
        <string>DefaultHomeTab</string>
    </ShowOn>
    <Executable>
        <FilePath>$env:SystemRoot\System32\WindowsPowerShell\v1.0\powershell.exe</FilePath>
        <Parameters> -ExecutionPolicy Bypass -File "$PSCommandPath" -auto -autofile "$PSScriptRoot\ConfigMgr\PackageInfo\##SUB:PackageID##"</Parameters>
    </Executable>
</ActionDescription>
"@


    $EditWWXML = @"
<ActionDescription Class ="Executable" DisplayName="Edit WIM Witch Image Config" MnemonicDisplayName="Edit WIM Witch Image Config" Description="Click to edit the WIM Witch image configuration">
    <ShowOn>
        <string>ContextMenu</string>
        <string>DefaultHomeTab</string>
    </ShowOn>
    <Executable>
        <FilePath>$env:SystemRoot\System32\WindowsPowerShell\v1.0\powershell.exe</FilePath>
        <Parameters> -ExecutionPolicy Bypass -File "$PSCommandPath" -CM "Edit" -autofile "$PSScriptRoot\ConfigMgr\PackageInfo\##SUB:PackageID##"</Parameters>
    </Executable>
</ActionDescription>
"@


    $NewWWXML = @"
<ActionDescription Class ="Executable" DisplayName="New WIM Witch Image" MnemonicDisplayName="New WIM Witch Image" Description="Click to create a new WIM Witch image">
    <ShowOn>
        <string>ContextMenu</string>
        <string>DefaultHomeTab</string>
    </ShowOn>
    <Executable>
        <FilePath>$env:SystemRoot\System32\WindowsPowerShell\v1.0\powershell.exe</FilePath>
        <Parameters> -ExecutionPolicy Bypass -File "$PSCommandPath" -CM "New"</Parameters>
    </Executable>
</ActionDescription>
"@

    
    update-log -Data "Installing ConfigMgr console extension..." -Class Information

    $ConsoleFolderImage = "828a154e-4c7d-4d7f-ba6c-268443cdb4e8" #folder for update and edit

    $ConsoleFolderRoot = "ac16f420-2d72-4056-a8f6-aef90e66a10c" #folder for new

    $path = ($env:SMS_ADMIN_UI_PATH -replace "bin\\i386", "") + "XmlStorage\Extensions\Actions"

    Update-Log -Data "Creating folders if needed..." -Class Information

    if ((Test-Path -Path (Join-Path -Path $path -ChildPath $ConsoleFolderImage)) -eq $false){New-Item -Path $path -Name $ConsoleFolderImage -ItemType "directory" | out-null}

    update-log -data "Creating extension files..." -Class Information

    $UpdateWWXML | out-file ((Join-Path -Path $path -ChildPath $ConsoleFolderImage) + "\UpdateWWImage.xml") -Force
    $EditWWXML | out-file ((Join-Path -Path $path -ChildPath $ConsoleFolderImage) + "\EditWWImage.xml") -Force

    Update-Log -Data "Creating folders if needed..." -Class Information

    if ((Test-Path -Path (Join-Path -Path $path -ChildPath $ConsoleFolderRoot)) -eq $false){New-Item -Path $path -Name $ConsoleFolderRoot -ItemType "directory" | out-null}
    update-log -data "Creating extension files..." -Class Information
    
    $NewWWXML | out-file ((Join-Path -Path $path -ChildPath $ConsoleFolderRoot) + "\NewWWImage.xml") -Force

    update-log -Data "Console extension installation complete!" -Class Information
}

#Function to handle 32-Bit PowerSehell
function invoke-architecturecheck{
 if ([Environment]::Is64BitProcess -ne [Environment]::Is64BitOperatingSystem)
        {
            
            Update-Log -Data "This is 32-bit PowerShell session. Will relaunch as 64-bit..." -Class Warning

            #The following If statment was pilfered from Michael Niehaus
            if (Test-Path "$($env:WINDIR)\SysNative\WindowsPowerShell\v1.0\powershell.exe")
                {
                
                if (($auto -eq $false) -and ($CM -eq "None")){& "$($env:WINDIR)\SysNative\WindowsPowerShell\v1.0\powershell.exe" -ExecutionPolicy bypass -NoProfile -File "$PSCommandPath"}
                if (($auto -eq $true) -and ($autofile -ne $null)){& "$($env:WINDIR)\SysNative\WindowsPowerShell\v1.0\powershell.exe" -ExecutionPolicy bypass -NoProfile -File "$PSCommandPath" -auto -autofile $autofile}
                if (($CM -eq "Edit") -and ($autofile -ne $null)){& "$($env:WINDIR)\SysNative\WindowsPowerShell\v1.0\powershell.exe" -ExecutionPolicy bypass -NoProfile -File "$PSCommandPath" -CM Edit -autofile $autofile}
                if ($CM -eq "New"){& "$($env:WINDIR)\SysNative\WindowsPowerShell\v1.0\powershell.exe" -ExecutionPolicy bypass -NoProfile -File "$PSCommandPath" -CM New}

                Exit $lastexitcode
                }


            ###end here


        }
        
            else
        {
            update-log -Data "This is a 64 bit PowerShell session" -Class Information


        }
}

#function to handle admin rights escalation
function invoke-admincheck{
$editscript = @"
Start-Process powershell -ArgumentList '-noprofile -file "$PSCommandPath" -CM Edit -autofile "$autofile"' -verb RunAs
"@


$UpdateScript = @"
Start-Process powershell -ArgumentList '-noprofile -File "$PSCommandPath" -auto -autofile "$autofile"' -verb RunAs
"@


$NewScript = @"
Start-Process powershell -ArgumentList '-noprofile -file "$PSCommandPath" -CM "New"' -verb RunAs
"@


$LaunchScript = @"
Start-Process powershell -ArgumentList '-noprofile -file "$PSCommandPath"' -verb RunAs
"@


    if((test-path $PSScriptRoot\temp) -eq $false){New-Item -Path $PSScriptRoot -Name "Temp" -ItemType Directory}


    If([bool](([System.Security.Principal.WindowsIdentity]::GetCurrent()).groups -match "S-1-5-32-544")-ne $true)
        {
            
            Update-Log -Data "This session is not running as admin. Will relaunch as admin..." -Class Warning

           
            if (Test-Path "$($env:WINDIR)\SysNative\WindowsPowerShell\v1.0\powershell.exe")
                {
                

                


             # if (($auto -eq $false) -and ($CM -eq "None")){& "$($env:WINDIR)\SysNative\WindowsPowerShell\v1.0\powershell.exe" -ExecutionPolicy bypass -NoProfile -File "$PSCommandPath"}
                if (($auto -eq $false) -and ($CM -eq "None")){
                    $launchscript | out-file $PSScriptRoot\temp\launch.ps1
                    & "$($env:WINDIR)\SysNative\WindowsPowerShell\v1.0\powershell.exe" -ExecutionPolicy bypass -NoProfile -File "$PSScriptRoot\temp\launch.ps1" 
                }
             
                #if (($auto -eq $true) -and ($autofile -ne $null)){& "$($env:WINDIR)\SysNative\WindowsPowerShell\v1.0\powershell.exe" -ExecutionPolicy bypass -NoProfile -File "$PSCommandPath" -auto -autofile $autofile}
                if (($auto -eq $true) -and ($autofile -ne $null)){
                    $updatescript | out-file $PSScriptRoot\temp\launch.ps1
                    & "$($env:WINDIR)\SysNative\WindowsPowerShell\v1.0\powershell.exe" -ExecutionPolicy bypass -NoProfile -File "$PSScriptRoot\temp\launch.ps1" 
                }
     
                #if (($CM -eq "Edit") -and ($autofile -ne $null)){& "$($env:WINDIR)\SysNative\WindowsPowerShell\v1.0\powershell.exe" -ExecutionPolicy bypass -NoProfile -File "$PSCommandPath" -CM Edit -autofile $autofile}
                if (($CM -eq "Edit") -and ($autofile -ne $null)){
                    $editscript | out-file $PSScriptRoot\temp\launch.ps1 
                    & "$($env:WINDIR)\SysNative\WindowsPowerShell\v1.0\powershell.exe" -ExecutionPolicy bypass -NoProfile -File "$PSScriptRoot\temp\launch.ps1"
                    }


                #if ($CM -eq "New"){& "$($env:WINDIR)\SysNative\WindowsPowerShell\v1.0\powershell.exe" -ExecutionPolicy bypass -NoProfile -File "$PSCommandPath" -CM New}
                if ($CM -eq "New"){                    
                    $NewScript | out-file $PSScriptRoot\temp\launch.ps1 
                    & "$($env:WINDIR)\SysNative\WindowsPowerShell\v1.0\powershell.exe" -ExecutionPolicy bypass -NoProfile -File "$PSScriptRoot\temp\launch.ps1"
                    }
                
                Exit $lastexitcode
                }


            ###end here


        }
        
            else
        {
            update-log -Data "This session is running as admin" -Class Information


        }


}

#function to download and extract the SSU required for 2004/20H2 June '21 LCU
function invoke-2XXXprereq{
    $KB_URI = "http://download.windowsupdate.com/c/msdownload/update/software/secu/2021/05/windows10.0-kb5003173-x64_375062f9d88a5d9d11c5b99673792fdce8079e09.cab"
    $executable = "$env:windir\system32\expand.exe"
    $mountdir = $WPFMISMountTextBox.Text

    update-log -data  "Mounting offline registry and validating UBR / Patch level..." -class Information
    reg LOAD HKLM\OFFLINE $mountdir\Windows\System32\Config\SOFTWARE | Out-Null
    $regvalues = (Get-ItemProperty -Path "Registry::HKEY_LOCAL_MACHINE\OFFLINE\Microsoft\Windows NT\CurrentVersion\" )
    
   
    update-log -data "The UBR (Patch Level) is:" -class Information
    update-log -data $regvalues.ubr -class information
    reg UNLOAD HKLM\OFFLINE | Out-Null

    if ($regvalues.ubr -eq $null){
        update-log -data "Registry key wasn't copied. Can't continue." -class Error
        return 1
        }

    if ($regvalues.UBR -lt "985"){
         
        update-log -data "The image requires an additional required SSU." -class Information
        update-log -data "Checking to see if the required SSU exists..." -class Information
        if ((test-path "$PSScriptRoot\updates\Windows 10\2XXX_prereq\SSU-19041.985-x64.cab") -eq $false){
            update-log -data "The required SSU does not exist. Downloading it now..." -class Information
            
            try
            {
                Invoke-WebRequest -Uri $KB_URI -OutFile "$PSScriptRoot\staging\extract_me.cab" -erroraction stop
            }
            catch
            {
                update-log -data "Failed to download the update" -class Error
                Update-Log -data $_.Exception.Message -Class Error
            return 1
            }
            
            if ((test-path "$PSScriptRoot\updates\Windows 10\2XXX_prereq") -eq $false){
               
               
               try
                    {
                    update-log -data "The folder for the required SSU does not exist. Creating it now..." -class Information
                    new-item -Path "$PSScriptRoot\updates\Windows 10" -Name "2XXX_prereq" -ItemType Directory -erroraction stop |Out-Null
                    update-log -data "The folder has been created" -class information
                    }
               catch
                    {
                    update-log -data "Could not create the required folder." -class error
                    Update-Log -data $_.Exception.Message -Class Error
                    return 1
                    }
              }          
            
            try
                {
                update-log -data "Extracting the SSU from the May 2021 LCU..." -class Information
                Start-Process $executable -args @("`"$PSScriptRoot\staging\extract_me.cab`"",'/f:*SSU*.CAB',"`"$PSScriptRoot\updates\Windows 10\2XXX_prereq`"") -wait -ErrorAction Stop
                update-log "Extraction of SSU was success" -class information
                }
            catch
                {
                update-log -data "Couldn't extract the SSU from the LCU" -class error
                Update-Log -data $_.Exception.Message -Class Error
                return 1

                }
            
            
            try
                {
                update-log -data "Deleting the staged LCU file..." -class Information
                Remove-Item -Path $PSScriptRoot\staging\extract_me.cab -Force -ErrorAction stop | out-null 
                update-log -data "The source file for the SSU has been Baleeted!" -Class Information
                }
            catch
                {
                update-log -data "Could not delete the source package" -Class Error
                Update-Log -data $_.Exception.Message -Class Error
                return 1
                }
            }
            else
                { 
                update-log -data "The required SSU exists. No need to download" -Class Information
                }
            
            try
            {
                update-log -data "Applying the SSU..." -class Information
                add-windowspackage -PackagePath "$PSScriptRoot\updates\Windows 10\2XXX_prereq" -Path $WPFMISMountTextBox.Text -erroraction Stop |out-null
                update-log -data "SSU applied successfully" -class Information

            }
            catch
            {
                update-log -data "Couldn't apply the SSU update"  -class error
                Update-Log -data $_.Exception.Message -Class Error
                return 1
            }
        }
        else
            {
            update-log -Data "Image doesn't require the prereq SSU" -Class Information
            }

    update-log -data "SSU remdiation complete" -Class Information
    return 0
    }

#Function to display text notification to end user
function invoke-textnotification{
    update-log -data "*********************************" -class warning
    update-log -data " " -class warning
    update-log -data "There are breaking changes to Windows Server servicing." -class warning
    update-log -data " " -class warning
    update-log -data ".Net 3.5 binaries will need to be re-imported." -class warning
    update-log -data " " -class warning
    update-log -data "Updates for Server OS's will need to be re-downloaded" -class warning
    update-log -data " " -class warning
    update-log -data "Please read the following post for more information" -class warning
    update-log -data " " -class warning
    update-log -data "https://msendpointmgr.com/2021/10/22/wim-witch-v3-2-0---windows-11-and-server-2022-support/" -class warning
    update-log -data " " -class warning
    update-log -data "*********************************" -class warning
    update-log -data " " -class warning
}
            

#===========================================================================
# Run commands to set values of files and variables, etc.
#===========================================================================

#calls fuction to display the opening text blurb


display-openingtext
#Get-FormVariables #lists all WPF variables
check-install
#Set the path and name for logging
$Log = "$PSScriptRoot\logging\WIMWitch.log"

Set-Logging #Clears out old logs from previous builds and checks for other folders

##################
# Prereq Check segment

#Check for installed PowerShell version
 if ($PSVersionTable.PSVersion.Major -ge 5){Update-Log -Data "PowerShell v5 or greater installed." -Class Information}
        else
        {
        update-log -data "PowerShell v5 or greater is required. Please upgrade PowerShell and try again." -Class Error
        display-closingtext
        exit 0
        }

   
#Check for available space
if($SkipFreeSpaceCheck -eq $false){

    if (check-freespace -eq 1){
        update-log -Data "Insufficient free space. Please clean up disk and try again" -Class Error
        update-log -Data "If you would like to bypass the free space check, please run" -Class Error
        update-log -data "with the parameter -SkipFreeSpaceCheck" -Class Error
        update-log -data "Example: .\WimWitch.ps1 -SkipFreeSpaceCheck" -Class Error
        display-closingtext
        exit 0       
        }
        Else
        {update-log -Data "Plenty of HDD space available!" -class Information}
}

#Check for admin rights
invoke-admincheck

#Check for 32 bit architecture
invoke-architecturecheck



#End Prereq segment
###################


#===========================================================================
Check-WIMWitchVer #Checks installed version of WIM Witch and updates if selected

#This randon line was inserted on 7/3/2020.


#===========================================================================

#===========================================================================
# Set default values for certain variables
#===========================================================================

#Set the value of the JSON field in Make It So tab
$WPFMISJSONTextBox.Text = "False"

#Set the value of the Driver field in the Make It So tab
$WPFMISDriverTextBox.Text = "False"

#Set the value of the Updates field in the Make It So tab
$WPFMISUpdatesTextBox.Text = "False"

$WPFMISAppxTextBox.Text = "False"

#$WPFAppTab.IsEnabled = $False

#===========================================================================
# Section for Combo box functions
#===========================================================================

#Set the combo box values of the other import tab

$ObjectTypes = @("Language Pack","Local Experience Pack","Feature On Demand")
$WinOS = @("Windows Server","Windows 10","Windows 11")
$WinSrvVer = @("2019","21H2")
$Win10Ver = @("1809","1903","1909","2004")
$Win11Ver = @("21H2")

Foreach ($ObjectType in $ObjectTypes){$WPFImportOtherCBType.Items.Add($ObjectType) | out-null}
Foreach ($WinOS in $WinOS){$WPFImportOtherCBWinOS.Items.Add($WinOS) | out-null}  

#Run Script Timing combox box
$RunScriptActions = @("After image mount","Before image dismount","On build completion")
Foreach ($RunScriptAction in $RunScriptActions){$WPFCustomCBScriptTiming.Items.add($RunScriptAction) | out-null}

#ConfigMgr Tab Combo boxes
$ImageTypeCombos = @("Disabled","New Image","Update Existing Image")
$DPTypeCombos = @("Distribution Points","Distribution Point Groups")
foreach ($ImageTypeCombo in $ImageTypeCombos){$WPFCMCBImageType.Items.Add($ImageTypeCombo) | out-null}
foreach ($DPTypeCombo in $DPTypeCombos){$WPFCMCBDPDPG.Items.Add($DPTypeCombo) | out-null}
$WPFCMCBDPDPG.SelectedIndex = 0
$WPFCMCBImageType.SelectedIndex = 0


enable-ConfigMgrOptions 

#Software Update Catalog Source combo box
$UpdateSourceCombos = @("None","OSDSUS","ConfigMgr")
foreach ($UpdateSourceCombo in $UpdateSourceCombos){$WPFUSCBSelectCatalogSource.Items.Add($UpdateSourceCombo)| out-null}
$WPFUSCBSelectCatalogSource.SelectedIndex = 0
invoke-UpdateTabOptions

#Check for ConfigMgr and set integration
if((detect-configmgr) -eq 0){
    
    if((import-CMModule) -eq 0){
        $WPFUSCBSelectCatalogSource.SelectedIndex = 2
        invoke-UpdateTabOptions
        } 
    }
    else
    {Update-Log -Data "Skipping ConfigMgr PowerShell module importation"}

#Set OSDSUS to Patch Catalog if CM isn't integratedg

if ($WPFUSCBSelectCatalogSource.SelectedIndex -eq 0){
    update-log -Data "Setting OSDSUS as the Update Catalog" -Class Information
    $WPFUSCBSelectCatalogSource.SelectedIndex = 1
    invoke-UpdateTabOptions
    }

#Function download-patches($build,$OS)

if ($DownloadUpdates -eq $true) {
# If (($UpdatePoShModules -eq $true) -and ($WPFUpdatesOSDBOutOfDateTextBlock.Visibility -eq "Visible")) {
    If ($UpdatePoShModules -eq $true ) { 
        update-OSDB
        Update-OSDSUS 
    }

   
    if ($Server2016 -eq $true){
        if ($WPFUSCBSelectCatalogSource.SelectedIndex -eq 1){
            check-superceded -action delete -OS "Windows Server" -Build 1607
            download-patches -OS "Windows Server" -build 1607}


        if ($WPFUSCBSelectCatalogSource.SelectedIndex -eq 2){
            invoke-MEMCMUpdateSupersedence -prod "Windows Server" -Ver 1607
            invoke-MEMCMUpdatecatalog -prod "Windows Server" -Ver 1607}
    }

    if ($Server2019 -eq $true){
        if ($WPFUSCBSelectCatalogSource.SelectedIndex -eq 1){
            check-superceded -action delete -OS "Windows Server" -Build 1809
            download-patches -OS "Windows Server" -build 1809}

        if ($WPFUSCBSelectCatalogSource.SelectedIndex -eq 2){
            invoke-MEMCMUpdateSupersedence -prod "Windows Server" -Ver 1809
            invoke-MEMCMUpdatecatalog -prod "Windows Server" -Ver 1809}
    }

    if ($Server2022 -eq $true){
        if ($WPFUSCBSelectCatalogSource.SelectedIndex -eq 1){
            check-superceded -action delete -OS "Windows Server" -Build 21H2
            download-patches -OS "Windows Server" -build 21H2}


        if ($WPFUSCBSelectCatalogSource.SelectedIndex -eq 2){
            invoke-MEMCMUpdateSupersedence -prod "Windows Server" -Ver 21H2
            invoke-MEMCMUpdatecatalog -prod "Windows Server" -Ver 21H2}
    }

        
    if ($Win10Version -ne "none"){
        if (($Win10Version -eq "1709")){# -or ($Win10Version -eq "all")){
            if ($WPFUSCBSelectCatalogSource.SelectedIndex -eq 1){
                check-superceded -action delete -OS "Windows 10" -Build 1709
                download-patches -OS "Windows 10" -build 1709}
            if ($WPFUSCBSelectCatalogSource.SelectedIndex -eq 2){
                invoke-MEMCMUpdateSupersedence -prod "Windows 10" -Ver 1709
                invoke-MEMCMUpdatecatalog -prod "Windows 10" -Ver 1709}
        }

        if (($Win10Version -eq "1803")){# -or ($Win10Version -eq "all")){
            if ($WPFUSCBSelectCatalogSource.SelectedIndex -eq 1){
                check-superceded -action delete -OS "Windows 10" -Build 1803
                download-patches -OS "Windows 10" -build 1803}
            if ($WPFUSCBSelectCatalogSource.SelectedIndex -eq 2){
                invoke-MEMCMUpdateSupersedence -prod "Windows 10" -Ver 1803
                invoke-MEMCMUpdatecatalog -prod "Windows 10" -Ver 1803}
        }

        if (($Win10Version -eq "1809") -or ($Win10Version -eq "all")){
            if ($WPFUSCBSelectCatalogSource.SelectedIndex -eq 1){
                check-superceded -action delete -OS "Windows 10" -Build 1809
                download-patches -OS "Windows 10" -build 1809}
            if ($WPFUSCBSelectCatalogSource.SelectedIndex -eq 2){
                invoke-MEMCMUpdateSupersedence -prod "Windows 10" -Ver 1809
                invoke-MEMCMUpdatecatalog -prod "Windows 10" -Ver 1809}
        }


        if (($Win10Version -eq "1903")){# -or ($Win10Version -eq "all")){
            if ($WPFUSCBSelectCatalogSource.SelectedIndex -eq 1){
                check-superceded -action delete -OS "Windows 10" -Build 1903
                download-patches -OS "Windows 10" -build 1903}
            if ($WPFUSCBSelectCatalogSource.SelectedIndex -eq 2){
                invoke-MEMCMUpdateSupersedence -prod "Windows 10" -Ver 1903
                invoke-MEMCMUpdatecatalog -prod "Windows 10" -Ver 1903}
        }


        if (($Win10Version -eq "1909") -or ($Win10Version -eq "all")){
            if ($WPFUSCBSelectCatalogSource.SelectedIndex -eq 1){
                check-superceded -action delete -OS "Windows 10" -Build 1909
                download-patches -OS "Windows 10" -build 1909}
            if ($WPFUSCBSelectCatalogSource.SelectedIndex -eq 2){
                invoke-MEMCMUpdateSupersedence -prod "Windows 10" -Ver 1909
                invoke-MEMCMUpdatecatalog -prod "Windows 10" -Ver 1909}
        }

        if (($Win10Version -eq "2004") -or ($Win10Version -eq "all")){
            if ($WPFUSCBSelectCatalogSource.SelectedIndex -eq 1){
                check-superceded -action delete -OS "Windows 10" -Build 2004
                download-patches -OS "Windows 10" -build 2004}
            if ($WPFUSCBSelectCatalogSource.SelectedIndex -eq 2){
                invoke-MEMCMUpdateSupersedence -prod "Windows 10" -Ver 2004
                invoke-MEMCMUpdatecatalog -prod "Windows 10" -Ver 2004}
        }

        if (($Win10Version -eq "20H2") -or ($Win10Version -eq "all")){
            if ($WPFUSCBSelectCatalogSource.SelectedIndex -eq 1){
                check-superceded -action delete -OS "Windows 10" -Build 2009
                download-patches -OS "Windows 10" -build 2009}
            if ($WPFUSCBSelectCatalogSource.SelectedIndex -eq 2){
                invoke-MEMCMUpdateSupersedence -prod "Windows 10" -Ver 2009
                invoke-MEMCMUpdatecatalog -prod "Windows 10" -Ver 2009}
        }

        if (($Win10Version -eq "21H1") -or ($Win10Version -eq "all")){
            if ($WPFUSCBSelectCatalogSource.SelectedIndex -eq 1){
                check-superceded -action delete -OS "Windows 10" -Build 21H1
                download-patches -OS "Windows 10" -build 21H1}
            if ($WPFUSCBSelectCatalogSource.SelectedIndex -eq 2){
                invoke-MEMCMUpdateSupersedence -prod "Windows 10" -Ver 21H1
                invoke-MEMCMUpdatecatalog -prod "Windows 10" -Ver 21H1}
        }

        if ($Win11Version -eq "21H2"){
            if ($WPFUSCBSelectCatalogSource.SelectedIndex -eq 1){
                check-superceded -action delete -OS "Windows 11" -Build 21H2
                download-patches -OS "Windows 11" -build 21H2}
            if ($WPFUSCBSelectCatalogSource.SelectedIndex -eq 2){
                invoke-MEMCMUpdateSupersedence -prod "Windows 11" -Ver 21H2
                invoke-MEMCMUpdatecatalog -prod "Windows 11" -Ver 21H2}
        }


        download-onedrive
     }
  }

#===========================================================================
# Section for Buttons to call functions
#===========================================================================

#Mount Dir Button
$WPFMISMountSelectButton.Add_Click( { SelectMountdir }) 

#Source WIM File Button
$WPFSourceWIMSelectButton.Add_Click( { SelectSourceWIM }) 

#JSON File selection Button
$WPFJSONButton.Add_Click( { SelectJSONFile }) 

#Target Folder selection Button
$WPFMISFolderButton.Add_Click( { SelectTargetDir }) 

#Driver Directory Buttons
$WPFDriverDir1Button.Add_Click( { SelectDriverSource -DriverTextBoxNumber $WPFDriverDir1TextBox }) 
$WPFDriverDir2Button.Add_Click( { SelectDriverSource -DriverTextBoxNumber $WPFDriverDir2TextBox }) 
$WPFDriverDir3Button.Add_Click( { SelectDriverSource -DriverTextBoxNumber $WPFDriverDir3TextBox }) 
$WPFDriverDir4Button.Add_Click( { SelectDriverSource -DriverTextBoxNumber $WPFDriverDir4TextBox }) 
$WPFDriverDir5Button.Add_Click( { SelectDriverSource -DriverTextBoxNumber $WPFDriverDir5TextBox }) 

#Make it So Button, which builds the WIM file
$WPFMISMakeItSoButton.Add_Click( { MakeItSo -appx $global:SelectedAppx }) 

#Update OSDBuilder Button
$WPFUpdateOSDBUpdateButton.Add_Click( {
        update-OSDB
        Update-OSDSUS 
    }) 

#Update patch source
$WPFUpdatesDownloadNewButton.Add_Click( { update-patchsource })

#Select Appx packages to remove
$WPFAppxButton.Add_Click( { $global:SelectedAppx = Select-Appx })

#Select Autopilot path to save button
$WPFJSONButtonSavePath.Add_Click( { SelectNewJSONDir })

#retrieve autopilot profile from intune
$WPFJSONButtonRetrieve.Add_click( { get-wwautopilotprofile -login $WPFJSONTextBoxAADID.Text -path $WPFJSONTextBoxSavePath.Text })

#Button to save configuration file
$WPFSLSaveButton.Add_click( { save-config -filename $WPFSLSaveFileName.text })

#Button to load configuration file
$WPFSLLoadButton.Add_click( { select-config })

#Button to select ISO for importation
$WPFImportImportSelectButton.Add_click( { select-iso })

#Button to import content from iso
$WPFImportImportButton.Add_click( {import-iso})

#Combo Box dynamic change for Winver combo box
$WPFImportOtherCBWinOS.add_SelectionChanged({update-importverCB})

#Button to select the import path in the other components
$WPFImportOtherBSelectPath.add_click({select-importotherpath
       
        if ($WPFImportOtherCBType.SelectedItem -ne "Feature On Demand"){
            if ($WPFImportOtherCBWinOS.SelectedItem -ne "Windows 11"){$items = (Get-ChildItem -path $WPFImportOtherTBPath.text | Select-Object -Property Name | Out-GridView -title "Select Objects" -PassThru)}
            if (($WPFImportOtherCBWinOS.SelectedItem -eq "Windows 11") -and ($WPFImportOtherCBType.SelectedItem -eq "Language Pack")){$items = (Get-ChildItem -path $WPFImportOtherTBPath.text | Select-Object -Property Name | Where-Object { ($_.Name -like "*Windows-Client-Language-Pack*") } | Out-GridView -title "Select Objects" -PassThru)}
            if (($WPFImportOtherCBWinOS.SelectedItem -eq "Windows 11") -and ($WPFImportOtherCBType.SelectedItem -eq "Local Experience Pack")){$items = (Get-ChildItem -path $WPFImportOtherTBPath.text | Select-Object -Property Name | Out-GridView -title "Select Objects" -PassThru)}
        
        }

        if ($WPFImportOtherCBType.SelectedItem -eq "Feature On Demand"){
                if ($WPFImportOtherCBWinOS.SelectedItem -ne "Windows 11"){$items = (get-Childitem -path $WPFImportOtherTBPath.text)}
                if ($WPFImportOtherCBWinOS.SelectedItem -eq "Windows 11"){$items = (Get-ChildItem -path $WPFImportOtherTBPath.text | Select-Object -Property Name | Where-Object { ($_.Name -notlike "*Windows-Client-Language-Pack*") } | Out-GridView -title "Select Objects" -PassThru)}
                
                }    


        $WPFImportOtherLBList.Items.Clear()
        $count = 0
        $path = $WPFImportOtherTBPath.text
        foreach ($item in $items){
            $WPFImportOtherLBList.Items.Add($item.name)
            $count = $count + 1
            }

        if ($wpfImportOtherCBType.SelectedItem -eq "Language Pack"){update-log -data "$count Language Packs selected from $path" -Class Information}
        if ($wpfImportOtherCBType.SelectedItem -eq "Local Experience Pack"){update-log -data "$count Local Experience Packs selected from $path" -Class Information}
        if ($wpfImportOtherCBType.SelectedItem -eq "Feature On Demand"){update-log -data "Features On Demand source selected from $path" -Class Information}

    })

#Button to import Other Components content
$WPFImportOtherBImport.add_click({
    if ($WPFImportOtherCBWinOS.SelectedItem -eq "Windows Server"){
        if ($WPFImportOtherCBWinVer.SelectedItem -eq "2019"){$WinVerConversion = "1809"}
        }
        else
        {
        $WinVerConversion = $WPFImportOtherCBWinVer.SelectedItem
        }
          
     if ($WPFImportOtherCBType.SelectedItem -eq "Language Pack"){import-LanguagePacks -Winver $WinVerConversion -WinOS $WPFImportOtherCBWinOS.SelectedItem -LPSourceFolder $WPFImportOtherTBPath.text}
     if ($WPFImportOtherCBType.SelectedItem -eq "Local Experience Pack"){import-LocalExperiencePack -Winver $WinVerConversion -WinOS $WPFImportOtherCBWinOS.SelectedItem -LPSourceFolder $WPFImportOtherTBPath.text}
     if ($WPFImportOtherCBType.SelectedItem -eq "Feature On Demand"){import-FOD -Winver $WinVerConversion -WinOS $WPFImportOtherCBWinOS.SelectedItem -LPSourceFolder $WPFImportOtherTBPath.text}})
     
#Button Select LP's for importation
$WPFCustomBLangPacksSelect.add_click({select-LPFODCriteria -type "LP"})

#Button to select FODs for importation
$WPFCustomBFODSelect.add_click({select-LPFODCriteria -type "FOD"})

#Button to select LXPs for importation
$WPFCustomBLEPSelect.add_click({select-LPFODCriteria -type "LXP" })

#Button to select PS1 script
$WPFCustomBSelectPath.add_click({    
    $Script = New-Object System.Windows.Forms.OpenFileDialog -Property @{ 
    InitialDirectory = [Environment]::GetFolderPath('Desktop') 
    Filter           = 'PS1 (*.ps1)|'
    }
    $null = $Script.ShowDialog()
    $WPFCustomTBFile.text = $Script.FileName }) 

#Button to Select ConfigMgr Image Package
$WPFCMBSelectImage.Add_Click({
    $image = (Get-WmiObject -Namespace "root\SMS\Site_$($global:SiteCode)" -Class SMS_ImagePackage -ComputerName $global:SiteServer) | Select-Object -Property Name,version, language, ImageOSVersion, PackageID, Description| Out-GridView -title "Pick an image" -PassThru 
    $path = $PSScriptRoot + '\ConfigMgr\PackageInfo\' + $image.packageid
    if ((Test-Path -path $path ) -eq $True){
       # write-host "True"
        load-config -filename $path}
    else
    {
    get-imageinfo -PackID $image.PackageID}
    })

#Button to select new file path (may not need)
#$WPFCMBFilePathSelect.Add_Click({ })

#Button to add DP/DPG to list box on ConfigMgr tab
$WPFCMBAddDP.Add_Click({select-DPs })

#Button to remove DP/DPG from list box on ConfigMgr tab
$WPFCMBRemoveDP.Add_Click({
 
    while($WPFCMLBDPs.SelectedItems) {
        $WPFCMLBDPs.Items.Remove($WPFCMLBDPs.SelectedItems[0])}

}) 

#Combo Box dynamic change ConfigMgr type
$WPFCMCBImageType.add_SelectionChanged({enable-ConfigMgrOptions })

#Combo Box Software Update Catalog source
$WPFUSCBSelectCatalogSource.add_SelectionChanged({invoke-UpdateTabOptions})

#Button to remove items from Language Packs List Box
$WPFCustomBLangPacksRemove.Add_Click({

    while($WPFCustomLBLangPacks.SelectedItems) {
        $WPFCustomLBLangPacks.Items.Remove($WPFCustomLBLangPacks.SelectedItems[0])}
})

#Button to remove items from LXP List Box
$WPFCustomBLEPSRemove.Add_Click({

    while($WPFCustomLBLEP.SelectedItems) {
        $WPFCustomLBLEP.Items.Remove($WPFCustomLBLEP.SelectedItems[0])}

})

#Button to remove items from FOD List Box
$WPFCustomBFODRemove.Add_Click({

    while($WPFCustomLBFOD.SelectedItems) {
        $WPFCustomLBFOD.Items.Remove($WPFCustomLBFOD.SelectedItems[0])}

})

#Button to select default app association XML
$WPFCustomBDefaultApp.Add_Click({select-defaultapp})

#Button to select start menu XML
$WPFCustomBStartMenu.Add_Click({select-startmenu})

#Button to select registry files
$WPFCustomBRegistryAdd.Add_Click({select-regfiles})

#Button to remove registry files
$WPFCustomBRegistryRemove.Add_Click({
 
    while($WPFCustomLBRegistry.SelectedItems) {
        $WPFCustomLBRegistry.Items.Remove($WPFCustomLBRegistry.SelectedItems[0])}

})

#Button to select ISO save folder
$WPFMISISOSelectButton.Add_Click({SelectISODir})

#Button to install CM Console Extension
$WPFCMBInstallExtensions.Add_Click({install-WWCMConsoleExtension})

#===========================================================================
# Section for Checkboxes to call functions
#===========================================================================

#Enable JSON Selection
$WPFJSONEnableCheckBox.Add_Click( {
        If ($WPFJSONEnableCheckBox.IsChecked -eq $true) {
            $WPFJSONButton.IsEnabled = $True
            $WPFMISJSONTextBox.Text = "True"
        }
        else {
            $WPFJSONButton.IsEnabled = $False
            $WPFMISJSONTextBox.Text = "False"
        }
    })
 
#Enable Driver Selection
$WPFDriverCheckBox.Add_Click( {
        If ($WPFDriverCheckBox.IsChecked -eq $true) {
            $WPFDriverDir1Button.IsEnabled = $True
            $WPFDriverDir2Button.IsEnabled = $True
            $WPFDriverDir3Button.IsEnabled = $True
            $WPFDriverDir4Button.IsEnabled = $True
            $WPFDriverDir5Button.IsEnabled = $True
            $WPFMISDriverTextBox.Text = "True"
        }
        else {
            $WPFDriverDir1Button.IsEnabled = $False
            $WPFDriverDir2Button.IsEnabled = $False
            $WPFDriverDir3Button.IsEnabled = $False
            $WPFDriverDir4Button.IsEnabled = $False
            $WPFDriverDir5Button.IsEnabled = $False
            $WPFMISDriverTextBox.Text = "False"
        }
    })

#Enable Updates Selection
$WPFUpdatesEnableCheckBox.Add_Click( {
        If ($WPFUpdatesEnableCheckBox.IsChecked -eq $true) {
             $WPFMISUpdatesTextBox.Text = "True"
        }
        else {
            $WPFMISUpdatesTextBox.Text = "False"
        }
    })

#Enable AppX Selection
$WPFAppxCheckBox.Add_Click( {
        If ($WPFAppxCheckBox.IsChecked -eq $true) {
            $WPFAppxButton.IsEnabled = $True
            $WPFMISAppxTextBox.Text = "True"
        }
        else {
            $WPFAppxButton.IsEnabled = $False
        }
    })

#Enable install.wim selection in import
$WPFImportWIMCheckBox.Add_Click( {
        If ($WPFImportWIMCheckBox.IsChecked -eq $true) {
            $WPFImportNewNameTextBox.IsEnabled = $True
            $WPFImportImportButton.IsEnabled = $True
        }
        else {
            $WPFImportNewNameTextBox.IsEnabled = $False
            if ($WPFImportDotNetCheckBox.IsChecked -eq $False) { $WPFImportImportButton.IsEnabled = $False }
        }
    })

#Enable .Net binaries selection in import
$WPFImportDotNetCheckBox.Add_Click( {
        If ($WPFImportDotNetCheckBox.IsChecked -eq $true) {
            $WPFImportImportButton.IsEnabled = $True
        }
        else {
            if ($WPFImportWIMCheckBox.IsChecked -eq $False) { $WPFImportImportButton.IsEnabled = $False }
        }
    })

#Enable Win10 version selection
$WPFUpdatesW10Main.Add_Click( {
        If ($WPFUpdatesW10Main.IsChecked -eq $true) {
            $WPFUpdatesW10_1909.IsEnabled = $True
            $WPFUpdatesW10_1903.IsEnabled = $True
            $WPFUpdatesW10_1809.IsEnabled = $True
            $WPFUpdatesW10_1803.IsEnabled = $True
            $WPFUpdatesW10_1709.IsEnabled = $True
            $WPFUpdatesW10_2004.IsEnabled = $True
            $WPFUpdatesW10_20H2.IsEnabled = $True
            $WPFUpdatesW10_21H1.IsEnabled = $True
        }
        else {
            $WPFUpdatesW10_1909.IsEnabled = $False
            $WPFUpdatesW10_1903.IsEnabled = $False
            $WPFUpdatesW10_1809.IsEnabled = $False
            $WPFUpdatesW10_1803.IsEnabled = $False
            $WPFUpdatesW10_1709.IsEnabled = $False
            $WPFUpdatesW10_2004.IsEnabled = $False
            $WPFUpdatesW10_20H2.IsEnabled = $False
            $WPFUpdatesW10_21H1.IsEnabled = $False
           
        }
    })

#Enable LP Selection
$WPFCustomCBLangPacks.Add_Click({
    If ($WPFCustomCBLangPacks.IsChecked -eq $true){
        $WPFCustomBLangPacksSelect.IsEnabled = $True
        $WPFCustomBLangPacksRemove.IsEnabled = $True
        }
        else
        {
        $WPFCustomBLangPacksSelect.IsEnabled = $False
        $WPFCustomBLangPacksRemove.IsEnabled = $False
        }
 })

#ENable Language Experience Pack selection
$WPFCustomCBLEP.Add_Click({
    If ($WPFCustomCBLEP.IsChecked -eq $true){
        $WPFCustomBLEPSelect.IsEnabled = $True
        $WPFCustomBLEPSRemove.IsEnabled = $True
        }
        else
        {
        $WPFCustomBLEPSelect.IsEnabled = $False
        $WPFCustomBLEPSRemove.IsEnabled = $False
        }
 })

#Enable Feature On Demand selection
$WPFCustomCBFOD.Add_Click({
    If ($WPFCustomCBFOD.IsChecked -eq $true){
        $WPFCustomBFODSelect.IsEnabled = $True
        $WPFCustomBFODRemove.IsEnabled = $True
        }
        else
        {
        $WPFCustomBFODSelect.IsEnabled = $False
        $WPFCustomBFODRemove.IsEnabled = $False
        }
 })
 
#Enable Run Script settings
$WPFCustomCBRunScript.Add_Click({ 
    If ($WPFCustomCBRunScript.IsChecked -eq $true){
        $WPFCustomTBFile.IsEnabled = $True
        $WPFCustomBSelectPath.IsEnabled = $True
        $WPFCustomTBParameters.IsEnabled = $True
        $WPFCustomCBScriptTiming.IsEnabled = $True 
        }
      else
        {$WPFCustomTBFile.IsEnabled = $False
        $WPFCustomBSelectPath.IsEnabled = $False
        $WPFCustomTBParameters.IsEnabled = $False
        $WPFCustomCBScriptTiming.IsEnabled = $False}  })

#Enable Default App Association
$WPFCustomCBEnableApp.Add_Click({ 
    If ($WPFCustomCBEnableApp.IsChecked -eq $true){
        $WPFCustomBDefaultApp.IsEnabled = $True

        }
      else
        {
        $WPFCustomBDefaultApp.IsEnabled = $False
        }  
})

#Enable Start Menu Layout
$WPFCustomCBEnableStart.Add_Click({ 
    If ($WPFCustomCBEnableStart.IsChecked -eq $true){
        $WPFCustomBStartMenu.IsEnabled = $True

        }
      else
        {
        $WPFCustomBStartMenu.IsEnabled = $False
        }  
})

#Enable Registry selection list box buttons
$WPFCustomCBEnableRegistry.Add_Click({ 
    If ($WPFCustomCBEnableRegistry.IsChecked -eq $true){
        $WPFCustomBRegistryAdd.IsEnabled = $True
        $WPFCustomBRegistryRemove.IsEnabled = $True
        $WPFCustomLBRegistry.IsEnabled = $True
      
        }
      else
        {
        $WPFCustomBRegistryAdd.IsEnabled = $False
        $WPFCustomBRegistryRemove.IsEnabled = $False
        $WPFCustomLBRegistry.IsEnabled = $False
       
        }  
})

#Enable ISO/Upgrade Package selection in import
$WPFImportISOCheckBox.Add_Click( {
        If ($WPFImportISOCheckBox.IsChecked -eq $true) {
            $WPFImportImportButton.IsEnabled = $True
        }
        else {
            if (($WPFImportWIMCheckBox.IsChecked -eq $False) -and ($WPFImportDotNetCheckBox.IsChecked -eq $False)){ $WPFImportImportButton.IsEnabled = $False }
        }
    })

#Enable not creating stand alone wim
$WPFMISCBNoWIM.Add_Click( {
        If ($WPFMISCBNoWIM.IsChecked -eq $true) {
            $WPFMISWimNameTextBox.IsEnabled = $False
            $WPFMISWimFolderTextBox.IsEnabled = $False
            $WPFMISFolderButton.IsEnabled = $False

             $WPFMISWimNameTextBox.text = "install.wim"
        }
        else {
            $WPFMISWimNameTextBox.IsEnabled = $True
            $WPFMISWimFolderTextBox.IsEnabled = $True
            $WPFMISFolderButton.IsEnabled = $True
        }
    })

#Enable ISO creation fields
$WPFMISCBISO.Add_Click( {
        If ($WPFMISCBISO.IsChecked -eq $true) {
            $WPFMISTBISOFileName.IsEnabled = $True
            $WPFMISTBFilePath.IsEnabled = $True
            $WPFMISCBDynamicUpdates.IsEnabled = $True
            $WPFMISCBNoWIM.IsEnabled = $True
            $WPFMISCBBootWIM.IsEnabled = $True
            $WPFMISISOSelectButton.IsEnabled = $true

        }
        else {
            $WPFMISTBISOFileName.IsEnabled = $False
            $WPFMISTBFilePath.IsEnabled = $False
            $WPFMISISOSelectButton.IsEnabled = $false

        }
        if (($WPFMISCBISO.IsChecked -eq $false) -and ($WPFMISCBUpgradePackage.IsChecked -eq $false)){
            $WPFMISCBDynamicUpdates.IsEnabled = $False
            $WPFMISCBDynamicUpdates.IsChecked = $False
            $WPFMISCBNoWIM.IsEnabled = $False
            $WPFMISCBNoWIM.IsChecked = $False
            $WPFMISWimNameTextBox.IsEnabled = $true
            $WPFMISWimFolderTextBox.IsEnabled = $true
            $WPFMISFolderButton.IsEnabled = $true
            $WPFMISCBBootWIM.IsChecked = $false
            $WPFMISCBBootWIM.IsEnabled = $false
            }
    })

#Enable upgrade package path option
$WPFMISCBUpgradePackage.Add_Click( {
        If ($WPFMISCBUpgradePackage.IsChecked -eq $true) {
            $WPFMISTBUpgradePackage.IsEnabled = $True
            $WPFMISCBDynamicUpdates.IsEnabled = $True
            $WPFMISCBNoWIM.IsEnabled = $True
            $WPFMISCBBootWIM.IsEnabled = $True

        }
        else {
            $WPFMISTBUpgradePackage.IsEnabled = $False
        }
        if (($WPFMISCBISO.IsChecked -eq $false) -and ($WPFMISCBUpgradePackage.IsChecked -eq $false)){
            $WPFMISCBDynamicUpdates.IsEnabled = $False
            $WPFMISCBDynamicUpdates.IsChecked = $False
            $WPFMISCBNoWIM.IsEnabled = $False
            $WPFMISCBNoWIM.IsChecked = $False
            $WPFMISWimNameTextBox.IsEnabled = $true
            $WPFMISWimFolderTextBox.IsEnabled = $true
            $WPFMISFolderButton.IsEnabled = $true
            $WPFMISCBBootWIM.IsChecked = $false
            $WPFMISCBBootWIM.IsEnabled = $false
            }
    })

#Enable option to include Optional Updates
$WPFUpdatesEnableCheckBox.Add_Click({
    if ($WPFUpdatesEnableCheckBox.IsChecked -eq $true){$WPFUpdatesOptionalEnableCheckBox.IsEnabled = $True}
    else {
        $WPFUpdatesOptionalEnableCheckBox.IsEnabled = $False
        $WPFUpdatesOptionalEnableCheckBox.IsChecked = $False}
})

#==========================================================
#Run WIM Witch below
#==========================================================

#Runs WIM Witch from a single file, bypassing the GUI
if (($auto -eq $true) -and ($autofile -ne "")) { 
    run-configfile -filename $autofile
    display-closingtext
    exit 0
}

#Runs WIM from a path with multiple files, bypassing the GUI
if (($auto -eq $true) -and ($autopath -ne "")) {
    Update-Log -data "Running batch job from config folder $autopath" -Class Information
    $files = Get-ChildItem -Path $autopath
    Update-Log -data "Setting batch job for the folling configs:" -Class Information
    foreach ($file in $files) { Update-Log -Data $file -Class Information }
    foreach ($file in $files) {
        $fullpath = $autopath + '\' + $file
        run-configfile -filename $fullpath
    }
    Update-Log -Data "Work complete" -Class Information
    display-closingtext
    exit 0
}

#Loads the specified ConfigMgr config file from CM Console
if (($CM -eq "Edit") -and ($autofile -ne "")){
    update-log -Data "Loading ConfigMgr OS Image Package information..." -Class Information
    load-config -filename $autofile
}

#Closing action for the WPF form
Register-ObjectEvent -InputObject $form -EventName Closed -Action ( { display-closingtext }) | Out-Null

#display text information to the user
invoke-textnotification

if ($HiHungryImDad -eq $true){
    $string = invoke-dadjoke
    Update-Log -Data $string -Class warning
}

#Start GUI
update-log -data "Starting WIM Witch GUI" -class Information
$Form.ShowDialog() | out-null #This starts the GUI