diff --git a/README.md b/README.md index f10fc5a..5bd336c 100644 --- a/README.md +++ b/README.md @@ -10,11 +10,11 @@ Contributions to this project are welcome! However, please understand that I pre - **Create New ISO File** with [`oscdimg.exe`](https://docs.microsoft.com/en-us/windows-hardware/manufacture/desktop/oscdimg-command-line-options) > [!NOTE] -> This tool is currently in alpha (v0.0.1), and it's a work in progress. Any issues can be reported using the Issues tab. +> This tool is currently in alpha, and it's a work in progress. Any issues can be reported using the Issues tab. ### Versions -[![Latest Version](https://img.shields.io/badge/Version-0.0.1Alpha%20Latest-0078D4?style=for-the-badge&logo=github&logoColor=white)](https://github.com/memstechtips/WIMUtil/releases/tag/v0.0.1) +[![Latest Version](https://img.shields.io/badge/Version-0.0.2Alpha%20Latest-0078D4?style=for-the-badge&logo=github&logoColor=white)](https://github.com/memstechtips/WIMUtil/releases/tag/v0.0.2) ### Support the Project @@ -46,7 +46,7 @@ To use **WIMUtil**, follow these steps to launch PowerShell as an Administrator 3. **Paste and Run the Command**: - Copy the following command: ```powershell - irm "https://github.com/memstechtips/WIMUtil/raw/main/src/WIMUtil.ps1" | iex + irm "https://github.com/memstechtips/WIMUtil/raw/main/src/WIMUtil.ps1" | iex ``` - To paste into PowerShell, **Right-Click** or press **Ctrl + V** in the PowerShell or Terminal window.
This should automatically paste your copied command. - Press **Enter** to execute the command. diff --git a/config/wimutil-settings.json b/config/wimutil-settings.json new file mode 100644 index 0000000..5a196c4 --- /dev/null +++ b/config/wimutil-settings.json @@ -0,0 +1,13 @@ +{ + "main": { + "xamlUrl": "https://github.com/memstechtips/WIMUtil/raw/main/xaml/WIMUtilGUI.xaml", + "oscdimgURL": "https://github.com/memstechtips/WIMUtil/raw/main/assets/executables/oscdimg.exe", + "expectedHash": "CACD23ABCD1E1B791F6280D7D86270FF8D4144728FF611033BAF5599D883731B" + }, + "dev": { + "xamlUrl": "https://github.com/memstechtips/WIMUtil/raw/dev/xaml/WIMUtilGUI.xaml", + "oscdimgURL": "https://github.com/memstechtips/WIMUtil/raw/dev/assets/executables/oscdimg.exe", + "expectedHash": "CACD23ABCD1E1B791F6280D7D86270FF8D4144728FF611033BAF5599D883731B" + }, + "defaultBranch": "main" +} \ No newline at end of file diff --git a/src/WIMUtil.ps1 b/src/WIMUtil.ps1 index 299510e..aab6a7e 100644 --- a/src/WIMUtil.ps1 +++ b/src/WIMUtil.ps1 @@ -3,9 +3,8 @@ If (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]: Try { Start-Process PowerShell.exe -ArgumentList ("-NoProfile -ExecutionPolicy Bypass -File `"{0}`"" -f $PSCommandPath) -Verb RunAs Exit - } - Catch { - Write-Host "Failed to run as Administrator. Please rerun with elevated privileges." + } Catch { + Write-Host "Failed to run as Administrator. Please rerun with elevated privileges." -ForegroundColor Red Exit } } @@ -33,13 +32,62 @@ function SetStatusText { $script:currentScreenIndex = 1 -# URL to the XAML file on GitHub -$xamlUrl = "https://github.com/memstechtips/WIMUtil/raw/main/xaml/WIMUtilGUI.xaml" +# Fix Internet Explorer Engine is Missing to Ensure GUI Launches +Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Internet Explorer\Main" -Name "DisableFirstRunCustomize" -Value 2 -Force + +# Explicitly define the configuration URL for the branch to use (commenting out the one not to use depending on branch) +$configUrl = "https://raw.githubusercontent.com/memstechtips/WIMUtil/main/config/wimutil-settings.json" # Main branch +# $configUrl = "https://raw.githubusercontent.com/memstechtips/WIMUtil/dev/config/wimutil-settings.json" # Dev branch + +Write-Host "Using Configuration URL: $configUrl" -ForegroundColor Cyan + +# Determine branch from the configuration URL +$currentBranch = "unknown" # Fallback value +if ($configUrl -match "https://raw.githubusercontent.com/memstechtips/WIMUtil/([^/]+)/config/wimutil-settings.json") { + $currentBranch = $matches[1] + Write-Host "Branch detected from Configuration URL: $currentBranch" -ForegroundColor Green +} else { + Write-Host "Unable to detect branch from Configuration URL. Using fallback." -ForegroundColor Yellow +} -# Download and load the XAML content +Write-Host "Using branch: $currentBranch" -ForegroundColor Cyan + +# Load the configuration from the specified URL try { + $config = (Invoke-WebRequest -Uri $configUrl -ErrorAction Stop).Content | ConvertFrom-Json + Write-Host "Configuration loaded successfully from $configUrl" -ForegroundColor Green +} catch { + Write-Host "Failed to load configuration from URL: $configUrl" -ForegroundColor Red + exit 1 +} + +# Fetch settings for the current branch +$branchConfig = $config.$currentBranch +if (-not $branchConfig) { + Write-Host "Branch $currentBranch not found in configuration file. Exiting script." -ForegroundColor Red + exit 1 +} + +Write-Host "Branch settings successfully loaded for: $currentBranch" -ForegroundColor Cyan + +# Extract configuration settings +$xamlUrl = $branchConfig.xamlUrl +$oscdimgURL = $branchConfig.oscdimgURL +$expectedHash = $branchConfig.expectedHash + +# Validate that required keys are present in the configuration +if (-not ($xamlUrl -and $oscdimgURL -and $expectedHash)) { + Write-Host "Configuration file is missing required settings. Exiting script." -ForegroundColor Red + exit 1 +} + +# Load XAML GUI +try { + if (-not $xamlUrl) { + throw "XAML URL is not set in the configuration." + } # Download XAML content as a string - $xamlContent = (Invoke-WebRequest -Uri $xamlUrl).Content + $xamlContent = (Invoke-WebRequest -Uri $xamlUrl -ErrorAction Stop).Content # Load the XAML using XamlReader.Load with a MemoryStream $encoding = [System.Text.Encoding]::UTF8 @@ -52,13 +100,12 @@ try { # Clean up stream $xamlStream.Close() -} -catch { + Write-Host "XAML GUI loaded successfully." -ForegroundColor Green +} catch { Write-Host "Error loading XAML from URL: $($_.Exception.Message)" -ForegroundColor Red - $readerOperationSuccessful = $false + exit 1 } - # Define the drag behavior for the window function Window_MouseLeftButtonDown { param ( @@ -80,7 +127,6 @@ function Update-ProgressIndicator { $ProgressStep4.Fill = if ($currentScreen -ge 4) { "#FFDE00" } else { "#FFEB99" } } - # Check if XAML loaded successfully if ($readerOperationSuccessful) { # Define Controls consistently using $window @@ -433,12 +479,6 @@ if ($readerOperationSuccessful) { [System.Windows.Forms.Application]::DoEvents() } - - # Define expected hash and signing date of oscdimg.exe file to determine if it's been tampered with - # Note: Different versions of oscdimg.exe will have different hashes and signing dates - $expectedHash = "CACD23ABCD1E1B791F6280D7D86270FF8D4144728FF611033BAF5599D883731B" - $expectedSignDate = [datetime]"2023-10-19T21:51:12" - # Function to get the SHA-256 hash of a file function Get-FileHashValue { param ( @@ -455,34 +495,6 @@ if ($readerOperationSuccessful) { } } - # Function to get the signing date of a file - function Get-SignatureDate { - param ( - [string]$filePath - ) - - if (Test-Path -Path $filePath) { - try { - $signature = Get-AuthenticodeSignature -FilePath $filePath - if ($signature.Status -eq 'Valid') { - return $signature.SignerCertificate.NotBefore - } - else { - Write-Host "The file's digital signature is not valid." - return $null - } - } - catch { - Write-Host "Error retrieving the signature date: $_" - return $null - } - } - else { - Write-Host "File not found at path: $filePath" - return $null - } - } - # Check if oscdimg exists on the system without checking hash or date function CheckOscdimg { $oscdimgPath = "C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Deployment Tools\amd64\Oscdimg\oscdimg.exe" @@ -501,62 +513,50 @@ if ($readerOperationSuccessful) { [System.Windows.Forms.Application]::DoEvents() # Refresh the UI } - # Function to download and validate oscdimg - function DownloadOscdimg { - SetStatusText -message "Preparing to download oscdimg..." -color $Script:SuccessColor -textBlock ([ref]$CreateISOStatusText) - [System.Windows.Forms.Application]::DoEvents() +# Function to download and validate oscdimg +function DownloadOscdimg { + SetStatusText -message "Preparing to download oscdimg..." -color $Script:SuccessColor -textBlock ([ref]$CreateISOStatusText) + [System.Windows.Forms.Application]::DoEvents() - $oscdimgURL = "https://github.com/memstechtips/WIMUtil/raw/main/assets/executables/oscdimg.exe" - $adkOscdimgPath = "C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Deployment Tools\amd64\Oscdimg" - $oscdimgFullPath = Join-Path -Path $adkOscdimgPath -ChildPath "oscdimg.exe" + $adkOscdimgPath = "C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Deployment Tools\amd64\Oscdimg" + $oscdimgFullPath = Join-Path -Path $adkOscdimgPath -ChildPath "oscdimg.exe" - # Ensure the ADK directory exists - if (!(Test-Path -Path $adkOscdimgPath)) { - New-Item -ItemType Directory -Path $adkOscdimgPath -Force | Out-Null - SetStatusText -message "Created directory for oscdimg at: $adkOscdimgPath" -color $Script:SuccessColor -textBlock ([ref]$CreateISOStatusText) - [System.Windows.Forms.Application]::DoEvents() - } + # Ensure the ADK directory exists + if (!(Test-Path -Path $adkOscdimgPath)) { + New-Item -ItemType Directory -Path $adkOscdimgPath -Force | Out-Null + SetStatusText -message "Created directory for oscdimg at: $adkOscdimgPath" -color $Script:SuccessColor -textBlock ([ref]$CreateISOStatusText) + [System.Windows.Forms.Application]::DoEvents() + } - # Download oscdimg to the ADK path - try { - SetStatusText -message "Downloading oscdimg to $adkOscdimgPath..." -color $Script:SuccessColor -textBlock ([ref]$CreateISOStatusText) - [System.Windows.Forms.Application]::DoEvents() + # Download oscdimg to the ADK path + try { + SetStatusText -message "Downloading oscdimg from: $oscdimgURL" -color $Script:SuccessColor -textBlock ([ref]$CreateISOStatusText) + [System.Windows.Forms.Application]::DoEvents() (New-Object System.Net.WebClient).DownloadFile($oscdimgURL, $oscdimgFullPath) - SetStatusText -message "oscdimg downloaded successfully." -color $Script:SuccessColor -textBlock ([ref]$CreateISOStatusText) - - # Verify the file's hash - $actualHash = Get-FileHashValue -filePath $oscdimgFullPath - if ($actualHash -ne $expectedHash) { - SetStatusText -message "Hash mismatch! oscdimg may not be from Microsoft." -color $Script:ErrorColor -textBlock ([ref]$CreateISOStatusText) - Write-Host "Expected Hash: $expectedHash" - Write-Host "Actual Hash: $actualHash" - Remove-Item -Path $oscdimgFullPath -Force - return - } - - # Verify the file's signature date - $actualSignDate = Get-SignatureDate -filePath $oscdimgFullPath - if ($actualSignDate -ne $expectedSignDate) { - SetStatusText -message "Signature date mismatch! oscdimg may not be from Microsoft." -color $Script:ErrorColor -textBlock ([ref]$CreateISOStatusText) - Write-Host "Expected Sign Date: $expectedSignDate" - Write-Host "Actual Sign Date: $actualSignDate" - Remove-Item -Path $oscdimgFullPath -Force - return - } - - # File is valid, enable the Create ISO button - SetStatusText -message "oscdimg verified and ready for use." -color $Script:SuccessColor -textBlock ([ref]$CreateISOStatusText) - $GetoscdimgButton.IsEnabled = $false - $CreateISOButton.IsEnabled = $true - } - catch { - SetStatusText -message "Failed to download oscdimg: $($_.Exception.Message)" -color $Script:ErrorColor -textBlock ([ref]$CreateISOStatusText) + Write-Host "oscdimg downloaded successfully from: $oscdimgURL" + + # Verify the file's hash + $actualHash = Get-FileHashValue -filePath $oscdimgFullPath + if ($actualHash -ne $expectedHash) { + SetStatusText -message "Hash mismatch! oscdimg may not be from Microsoft." -color $Script:ErrorColor -textBlock ([ref]$CreateISOStatusText) + Write-Host "Expected Hash: $expectedHash" + Write-Host "Actual Hash: $actualHash" + Remove-Item -Path $oscdimgFullPath -Force + return } - [System.Windows.Forms.Application]::DoEvents() + # File is valid, enable the Create ISO button + SetStatusText -message "oscdimg verified and ready for use." -color $Script:SuccessColor -textBlock ([ref]$CreateISOStatusText) + $GetoscdimgButton.IsEnabled = $false + $CreateISOButton.IsEnabled = $true + } catch { + SetStatusText -message "Failed to download oscdimg: $($_.Exception.Message)" -color $Script:ErrorColor -textBlock ([ref]$CreateISOStatusText) } + [System.Windows.Forms.Application]::DoEvents() +} + # Define the location selection function function SelectNewISOLocation { # Prompt the user for ISO save location @@ -619,7 +619,6 @@ if ($readerOperationSuccessful) { $SelectISOLocationButton.Add_Click({ SelectNewISOLocation }) $CreateISOButton.Add_Click({ CreateISO }) - # Event handler for the Next button # Next button to navigate to the next screen $NextButton.Add_Click({ @@ -675,4 +674,4 @@ else { Write-Host "Failed to load the XAML file. Exiting script." -ForegroundColor Red Pause exit 1 -} +} \ No newline at end of file