workflow/vNext-v2/ui/MainWindow.ps1
|
<#!
.SYNOPSIS Interactive picker for OSDCloud operating system catalog entries using WPF UI (Fluent Design). #> [CmdletBinding()] param() #================================================ Add-Type -AssemblyName PresentationCore, PresentationFramework, WindowsBase # Load Wpf.Ui.dll if not already loaded (handles the case where the module did not pre-load it) try { if (!([System.Management.Automation.PSTypeName]'Wpf.Ui.Controls.Button').Type) { $moduleBase = Split-Path (Split-Path (Split-Path $PSScriptRoot -Parent) -Parent) -Parent if ($PSVersionTable.PSEdition -eq 'Desktop') { Add-Type -Path (Join-Path $moduleBase 'types\wpfui\net481\Wpf.Ui.dll') } else { Add-Type -Path (Join-Path $moduleBase 'types\wpfui\net6.0-windows\Wpf.Ui.dll') } } } catch { Write-Warning "[MainWindow.ps1] Could not load Wpf.Ui.dll: $_" } #================================================ # Variables $deviceBiosReleaseDate = $global:OSDCloudDevice.BiosReleaseDate $deviceBiosVersion = $global:OSDCloudDevice.BiosVersion $deviceOSDManufacturer = $global:OSDCloudDevice.OSDManufacturer $deviceOSDModel = $global:OSDCloudDevice.OSDModel $deviceOSDProduct = $global:OSDCloudDevice.OSDProduct $deviceComputerSystemSKU = $global:OSDCloudDevice.ComputerSystemSKU $deviceIsAutopilotSpec = $global:OSDCloudDevice.IsAutopilotSpec $deviceIsTpmSpec = $global:OSDCloudDevice.IsTpmSpec $deviceSerialNumber = $global:OSDCloudDevice.SerialNumber $deviceUUID = $global:OSDCloudDevice.UUID $deviceHardwareHash = $global:OSDCloudDevice.HardwareHash $getOSDCloudModuleVersion = Get-OSDCloudModuleVersion #================================================ # WPFUI Fluent theme initialization # Ensure a WPF Application singleton exists (WPFUI requires it for theme resource resolution) if (-not [System.Windows.Application]::Current) { try { $null = [System.Windows.Application]::new() } catch { Write-Verbose "[$(Get-Date -format s)] [MainWindow.ps1] Could not create WPF Application: $_" } } # Merge WPFUI theme and control resource dictionaries into the Application resources. # ThemesDictionary and ControlsDictionary are WPFUI markup types that resolve their # own pack URIs, so no hard-coded Source URI is required here. if ([System.Windows.Application]::Current) { try { $themeDict = [Wpf.Ui.Markup.ThemesDictionary]::new() $themeDict.Theme = [Wpf.Ui.Appearance.ThemeType]::Light $controlsDict = [Wpf.Ui.Markup.ControlsDictionary]::new() $appResources = [System.Windows.Application]::Current.Resources $appResources.MergedDictionaries.Add($themeDict) $appResources.MergedDictionaries.Add($controlsDict) Write-Verbose "[$(Get-Date -format s)] [MainWindow.ps1] WPFUI theme merged successfully" } catch { Write-Verbose "[$(Get-Date -format s)] [MainWindow.ps1] WPFUI theme merge skipped: $_" } } #================================================ # XAML $xamlfile = Get-Item -Path "$PSScriptRoot\MainWindow.xaml" $xaml = Get-Content $xamlfile.FullName $stringReader = [System.IO.StringReader]::new($xaml) $xmlReader = [System.Xml.XmlReader]::Create($stringReader) $window = [Windows.Markup.XamlReader]::Load($xmlReader) #================================================ # Window Title $deviceTitleParts = @() if (-not [string]::IsNullOrWhiteSpace($getOSDCloudModuleVersion)) { $deviceTitleParts += $getOSDCloudModuleVersion } if ($deviceTitleParts.Count -gt 0) { $window.Title = "OSDCloud version $($deviceTitleParts -join ' - ')" } #================================================ # Logo $logoImage = $window.FindName('LogoImage') if ($logoImage) { $logoImage.Source = "$PSScriptRoot\logo.png" } #================================================ # Navigation panel switching $NavListBox = $window.FindName('NavListBox') $DevicePanel = $window.FindName('DevicePanel') $IdentityPanel = $window.FindName('IdentityPanel') $DeploymentPanel = $window.FindName('DeploymentPanel') $StepsPanel = $window.FindName('StepsPanel') $PrivacyPanel = $window.FindName('PrivacyPanel') $NavListBox.SelectedIndex = 0 $NavListBox.Add_SelectionChanged({ $tag = if ($NavListBox.SelectedItem) { [string]$NavListBox.SelectedItem.Tag } else { 'Device' } $DevicePanel.Visibility = if ($tag -eq 'Device') { [System.Windows.Visibility]::Visible } else { [System.Windows.Visibility]::Collapsed } $IdentityPanel.Visibility = if ($tag -eq 'Identity') { [System.Windows.Visibility]::Visible } else { [System.Windows.Visibility]::Collapsed } $DeploymentPanel.Visibility = if ($tag -eq 'Deployment') { [System.Windows.Visibility]::Visible } else { [System.Windows.Visibility]::Collapsed } $StepsPanel.Visibility = if ($tag -eq 'Steps') { [System.Windows.Visibility]::Visible } else { [System.Windows.Visibility]::Collapsed } $PrivacyPanel.Visibility = if ($tag -eq 'Privacy') { [System.Windows.Visibility]::Visible } else { [System.Windows.Visibility]::Collapsed } }) #================================================ # Menu Items $RunCmdPrompt = $window.FindName("RunCmdPrompt") $RunPowerShell = $window.FindName("RunPowerShell") $RunPwsh = $window.FindName("RunPwsh") $LogsMenuItem = $window.FindName("LogsMenuItem") $WMIMenuItem = $window.FindName("WMIMenuItem") $RunCmdPrompt.Add_Click({ try { Start-Process -FilePath "cmd.exe" } catch { [System.Windows.MessageBox]::Show("Failed to open CMD Prompt: $($_.Exception.Message)", "Error", "OK", "Error") | Out-Null } }) $RunPowerShell.Add_Click({ try { Start-Process -FilePath "powershell.exe" } catch { [System.Windows.MessageBox]::Show("Failed to open PowerShell: $($_.Exception.Message)", "Error", "OK", "Error") | Out-Null } }) if ($RunPwsh) { $pwshCommand = Get-Command -Name 'pwsh.exe' -ErrorAction SilentlyContinue if ($pwshCommand) { $script:PwshPath = $pwshCommand.Source $RunPwsh.Visibility = [System.Windows.Visibility]::Visible $RunPwsh.Add_Click({ try { Start-Process -FilePath $script:PwshPath } catch { [System.Windows.MessageBox]::Show("Failed to open PowerShell 7: $($_.Exception.Message)", "Error", "OK", "Error") | Out-Null } }) } else { $RunPwsh.Visibility = [System.Windows.Visibility]::Collapsed } } function Add-NoLogsMenuEntry { param( [Parameter(Mandatory)] [System.Windows.Controls.MenuItem]$MenuItem ) $noLogsItem = [System.Windows.Controls.MenuItem]::new() $noLogsItem.Header = 'No logs found' $noLogsItem.IsEnabled = $false $MenuItem.Items.Add($noLogsItem) | Out-Null } function Set-LogsMenuItems { $LogsMenuItem.Items.Clear() $logsRoot = Join-Path -Path ([System.IO.Path]::GetTempPath()) -ChildPath 'osdcloud-logs' if (-not (Test-Path -LiteralPath $logsRoot)) { Add-NoLogsMenuEntry -MenuItem $LogsMenuItem return } $logFiles = Get-ChildItem -LiteralPath $logsRoot -File -ErrorAction SilentlyContinue | Sort-Object -Property Name $logFiles = $logFiles | Where-Object { $_.Name -NotLike "Win32_*.txt" } if (-not $logFiles) { Add-NoLogsMenuEntry -MenuItem $LogsMenuItem return } foreach ($logFile in $logFiles) { $logMenuItem = [System.Windows.Controls.MenuItem]::new() $logMenuItem.Header = $logFile.Name -replace '_', '__' $logMenuItem.Tag = $logFile.FullName $logMenuItem.Add_Click({ param($menuItem, $clickArgs) $logPath = [string]$menuItem.Tag if (-not (Test-Path -LiteralPath $logPath)) { [System.Windows.MessageBox]::Show('Log file not found.', 'Open Log', 'OK', 'Warning') | Out-Null return } try { Start-Process -FilePath 'notepad.exe' -ArgumentList @("`"$logPath`"") -ErrorAction Stop } catch { [System.Windows.MessageBox]::Show("Failed to open log: $($_.Exception.Message)", 'Open Log', 'OK', 'Error') | Out-Null } }) $LogsMenuItem.Items.Add($logMenuItem) | Out-Null } } Set-LogsMenuItems function Set-WMIMenuItems { $WMIMenuItem.Items.Clear() $logsRoot = Join-Path -Path ([System.IO.Path]::GetTempPath()) -ChildPath 'osdcloud-logs' if (-not (Test-Path -LiteralPath $logsRoot)) { Add-NoLogsMenuEntry -MenuItem $WMIMenuItem return } $logFiles = Get-ChildItem -LiteralPath $logsRoot -File -ErrorAction SilentlyContinue | Sort-Object -Property Name $logFiles = $logFiles | Where-Object { $_.Name -Like "Win32_*.txt" } if (-not $logFiles) { Add-NoLogsMenuEntry -MenuItem $WMIMenuItem return } foreach ($logFile in $logFiles) { $logMenuItem = [System.Windows.Controls.MenuItem]::new() $logMenuItem.Header = $logFile.Name -replace '_', '__' $logMenuItem.Tag = $logFile.FullName $logMenuItem.Add_Click({ param($menuItem, $clickArgs) $logPath = [string]$menuItem.Tag if (-not (Test-Path -LiteralPath $logPath)) { [System.Windows.MessageBox]::Show('Log file not found.', 'Open Log', 'OK', 'Warning') | Out-Null return } try { Start-Process -FilePath 'notepad.exe' -ArgumentList @("`"$logPath`"") -ErrorAction Stop } catch { [System.Windows.MessageBox]::Show("Failed to open log: $($_.Exception.Message)", 'Open Log', 'OK', 'Error') | Out-Null } }) $WMIMenuItem.Items.Add($logMenuItem) | Out-Null } } Set-WMIMenuItems #================================================ # Task Sequence $TaskSequenceCombo = $window.FindName("TaskSequenceCombo") $taskSequenceFlows = $global:OSDCloudDeploy.Flows.Name if ($null -eq $taskSequenceFlows) { $taskSequenceFlows = @() } $TaskSequenceCombo.ItemsSource = $taskSequenceFlows $TaskSequenceCombo.SelectedIndex = 0 $TaskSequenceStepsGrid = $window.FindName("TaskSequenceStepsGrid") $script:CurrentTaskSequenceName = [string]$TaskSequenceCombo.SelectedItem $TaskSequenceStepsGrid.CanUserSortColumns = $false $TaskSequenceStepsGrid.Add_Sorting({ param($eventSource, $sortArgs) $sortArgs.Handled = $true $eventSource.Items.SortDescriptions.Clear() }) function New-StepCheckBoxColumn { param( [Parameter(Mandatory)] [string]$PropertyName ) $binding = [System.Windows.Data.Binding]::new($PropertyName) $binding.Mode = [System.Windows.Data.BindingMode]::TwoWay $binding.UpdateSourceTrigger = [System.Windows.Data.UpdateSourceTrigger]::PropertyChanged $binding.TargetNullValue = $false $binding.FallbackValue = $false $elementStyle = [System.Windows.Style]::new([System.Windows.Controls.CheckBox]) $elementStyle.Setters.Add([System.Windows.Setter]::new([System.Windows.Controls.CheckBox]::HorizontalAlignmentProperty, [System.Windows.HorizontalAlignment]::Center)) $elementStyle.Setters.Add([System.Windows.Setter]::new([System.Windows.Controls.CheckBox]::VerticalAlignmentProperty, [System.Windows.VerticalAlignment]::Center)) $elementStyle.Setters.Add([System.Windows.Setter]::new([System.Windows.Controls.CheckBox]::IsThreeStateProperty, $false)) $checkboxColumn = [System.Windows.Controls.DataGridCheckBoxColumn]::new() $checkboxColumn.Header = $PropertyName $checkboxColumn.Binding = $binding $checkboxColumn.ElementStyle = $elementStyle $checkboxColumn.EditingElementStyle = $elementStyle $checkboxColumn.IsReadOnly = $false $checkboxColumn.CanUserSort = $false $checkboxColumn.Width = [System.Windows.Controls.DataGridLength]::new(44) return $checkboxColumn } function Save-TaskSequenceSteps { param( [Parameter(Mandatory)] [string]$TaskSequenceName, [Parameter()] $Steps ) if ([string]::IsNullOrWhiteSpace($TaskSequenceName)) { return } $workflowTaskObject = $global:OSDCloudDeploy.Flows | Where-Object { $_.Name -eq $TaskSequenceName } | Select-Object -First 1 if (-not $workflowTaskObject) { return } if ($Steps) { $stepsArray = @($Steps) foreach ($step in $stepsArray) { if (-not (Get-Member -InputObject $step -Name 'skip' -ErrorAction SilentlyContinue)) { $step | Add-Member -MemberType NoteProperty -Name 'skip' -Value $false } if (-not (Get-Member -InputObject $step -Name 'debug' -ErrorAction SilentlyContinue)) { $step | Add-Member -MemberType NoteProperty -Name 'debug' -Value $false } if (-not (Get-Member -InputObject $step -Name 'pause' -ErrorAction SilentlyContinue)) { $step | Add-Member -MemberType NoteProperty -Name 'pause' -Value $false } if (-not (Get-Member -InputObject $step -Name 'verbose' -ErrorAction SilentlyContinue)) { $step | Add-Member -MemberType NoteProperty -Name 'verbose' -Value $false } } $workflowTaskObject.steps = $stepsArray } else { $workflowTaskObject.steps = @() } } $TaskSequenceStepsGrid.Add_AutoGeneratingColumn({ param($eventSource, $columnArgs) $columnArgs.Column.CanUserSort = $false if (@('debug', 'verbose', 'testinfullos') -icontains $columnArgs.PropertyName) { $columnArgs.Cancel = $true return } if ($columnArgs.PropertyName -ieq 'skip' -or $columnArgs.PropertyName -ieq 'pause') { $columnArgs.Column = New-StepCheckBoxColumn -PropertyName $columnArgs.PropertyName return } if ($columnArgs.PropertyName -ieq 'command') { $binding = [System.Windows.Data.Binding]::new($columnArgs.PropertyName) $binding.Mode = [System.Windows.Data.BindingMode]::TwoWay $binding.UpdateSourceTrigger = [System.Windows.Data.UpdateSourceTrigger]::PropertyChanged $columnArgs.Column.IsReadOnly = $false $columnArgs.Column.CanUserSort = $false if ($columnArgs.Column -is [System.Windows.Controls.DataGridTextColumn]) { $columnArgs.Column.Binding = $binding } return } if ($columnArgs.PropertyName -ieq 'name') { $binding = [System.Windows.Data.Binding]::new($columnArgs.PropertyName) $binding.Mode = [System.Windows.Data.BindingMode]::TwoWay $binding.UpdateSourceTrigger = [System.Windows.Data.UpdateSourceTrigger]::PropertyChanged $columnArgs.Column.IsReadOnly = $false $columnArgs.Column.CanUserSort = $false if ($columnArgs.Column -is [System.Windows.Controls.DataGridTextColumn]) { $columnArgs.Column.Binding = $binding } return } $columnArgs.Column.IsReadOnly = $true $columnArgs.Column.CanUserSort = $false }) $TaskSequenceStepsGrid.Add_AutoGeneratedColumns({ param($eventSource, $eventArgs) $skipColumn = $eventSource.Columns | Where-Object { [string]$_.Header -ieq 'skip' } | Select-Object -First 1 if ($skipColumn) { $skipColumn.DisplayIndex = 0 } }) function Update-TaskSequenceSteps { $selectedTaskSequence = [string]$TaskSequenceCombo.SelectedItem if ([string]::IsNullOrWhiteSpace($selectedTaskSequence)) { $TaskSequenceStepsGrid.ItemsSource = $null return } $workflowTaskObject = $global:OSDCloudDeploy.Flows | Where-Object { $_.Name -eq $selectedTaskSequence } | Select-Object -First 1 if ($workflowTaskObject -and $workflowTaskObject.steps) { $steps = $workflowTaskObject.steps foreach ($step in $steps) { if (-not (Get-Member -InputObject $step -Name 'skip' -ErrorAction SilentlyContinue)) { $step | Add-Member -MemberType NoteProperty -Name 'skip' -Value $false } if (-not (Get-Member -InputObject $step -Name 'debug' -ErrorAction SilentlyContinue)) { $step | Add-Member -MemberType NoteProperty -Name 'debug' -Value $false } if (-not (Get-Member -InputObject $step -Name 'pause' -ErrorAction SilentlyContinue)) { $step | Add-Member -MemberType NoteProperty -Name 'pause' -Value $false } if (-not (Get-Member -InputObject $step -Name 'verbose' -ErrorAction SilentlyContinue)) { $step | Add-Member -MemberType NoteProperty -Name 'verbose' -Value $false } } $TaskSequenceStepsGrid.Items.SortDescriptions.Clear() $TaskSequenceStepsGrid.ItemsSource = $steps $TaskSequenceStepsGrid.Items.SortDescriptions.Clear() } else { $TaskSequenceStepsGrid.ItemsSource = $null } } $TaskSequenceCombo.Add_SelectionChanged({ if ($SummaryTaskSequenceText) { $value = [string]$TaskSequenceCombo.SelectedItem $SummaryTaskSequenceText.Text = if (-not [string]::IsNullOrWhiteSpace($value)) { $value } else { 'Not selected' } } Save-TaskSequenceSteps -TaskSequenceName $script:CurrentTaskSequenceName -Steps $TaskSequenceStepsGrid.ItemsSource $script:CurrentTaskSequenceName = [string]$TaskSequenceCombo.SelectedItem Update-TaskSequenceSteps }) Update-TaskSequenceSteps #================================================ # Operating System Values if ($global:OSDCloudDeploy.OperatingSystemValues) { $OperatingSystemValues = $global:OSDCloudDeploy.OperatingSystemValues Write-Verbose "[$(Get-Date -format s)] [MainWindow.ps1] OperatingSystemValues = $OperatingSystemValues" } else { $OperatingSystemValues = $global:DeployOSDCloudOperatingSystems.OperatingSystem | Sort-Object -Unique | Sort-Object -Descending Write-Verbose "[$(Get-Date -format s)] [MainWindow.ps1] Catalog OperatingSystemValues = $OperatingSystemValues" } $OperatingSystemCombo = $window.FindName("OperatingSystemCombo") $OperatingSystemCombo.ItemsSource = $OperatingSystemValues #================================================ # OperatingSystem Default if ($global:OSDCloudDeploy.OperatingSystem) { $OperatingSystemDefault = $global:OSDCloudDeploy.OperatingSystem Write-Verbose "[$(Get-Date -format s)] [MainWindow.ps1] OperatingSystem = $OperatingSystemDefault" } if ($OperatingSystemDefault -and ($OperatingSystemValues -contains $OperatingSystemDefault)) { $OperatingSystemCombo.SelectedItem = $OperatingSystemDefault } elseif ($OperatingSystemValues) { $OperatingSystemCombo.SelectedIndex = 0 } else { $OperatingSystemCombo.SelectedIndex = -1 } #================================================ # OS Edition Values if ($global:OSDCloudDeploy.OSEditionValues.Edition) { $OSEditionValues = $global:OSDCloudDeploy.OSEditionValues.Edition Write-Verbose "[$(Get-Date -format s)] [MainWindow.ps1] OSEditionValues = $OSEditionValues" } else { $OSEditionValues = @() } $OSEditionCombo = $window.FindName("OSEditionCombo") $OSEditionCombo.ItemsSource = $OSEditionValues #================================================ # OS Edition Default if ($global:OSDCloudDeploy.OSEdition) { $OSEditionDefault = $global:OSDCloudDeploy.OSEdition Write-Verbose "[$(Get-Date -format s)] [MainWindow.ps1] OSEdition = $OSEditionDefault" } if ($OSEditionDefault) { $OSEditionCombo.SelectedItem = $OSEditionDefault } elseif ($OperatingSystemValues) { $OSEditionCombo.SelectedIndex = 0 } else { $OSEditionCombo.SelectedIndex = -1 } #================================================ # OS Activation Values if ($global:OSDCloudDeploy.OSActivationValues) { $OSActivationValues = $global:OSDCloudDeploy.OSActivationValues Write-Verbose "[$(Get-Date -format s)] [MainWindow.ps1] OSActivationValues = $OSActivationValues" } else { $OSActivationValues = @() } $OSActivationCombo = $window.FindName("OSActivationCombo") $OSActivationCombo.ItemsSource = $OSActivationValues #================================================ # OS Activation Default if ($global:OSDCloudDeploy.OSActivation) { $OSActivationDefault = $global:OSDCloudDeploy.OSActivation Write-Verbose "[$(Get-Date -format s)] [MainWindow.ps1] OSActivation = $OSActivationDefault" } if ($OSActivationDefault -and ($OSActivationValues -contains $OSActivationDefault)) { $OSActivationCombo.SelectedItem = $OSActivationDefault } elseif ($OSActivationValues) { $OSActivationCombo.SelectedIndex = 0 } else { $OSActivationCombo.SelectedIndex = -1 } #================================================ # OS Language Code Values if ($global:OSDCloudDeploy.OSLanguageCodeValues) { $OSLanguageCodeValues = $global:OSDCloudDeploy.OSLanguageCodeValues Write-Verbose "[$(Get-Date -format s)] [MainWindow.ps1] OSLanguageCodeValues = $OSLanguageCodeValues" } else { $OSLanguageCodeValues = $global:DeployOSDCloudOperatingSystems.OSLanguageCode | Sort-Object -Unique | Sort-Object -Descending Write-Verbose "[$(Get-Date -format s)] [MainWindow.ps1] Catalog OSLanguageCodeValues = $OSLanguageCodeValues" } $OSLanguageCodeCombo = $window.FindName("OSLanguageCodeCombo") $OSLanguageCodeCombo.ItemsSource = $OSLanguageCodeValues #================================================ # OS Language Code Default if ($global:OSDCloudDeploy.OSLanguageCode) { $OSLanguageCodeDefault = $global:OSDCloudDeploy.OSLanguageCode Write-Verbose "[$(Get-Date -format s)] [MainWindow.ps1] OSLanguage = $OSLanguageCodeDefault" } if ($OSLanguageCodeDefault -and ($OSLanguageCodeValues -contains $OSLanguageCodeDefault)) { $OSLanguageCodeCombo.SelectedItem = $OSLanguageCodeDefault } elseif ($OSLanguageCodeValues) { $OSLanguageCodeCombo.SelectedIndex = 0 } else { $OSLanguageCodeCombo.SelectedIndex = -1 } #================================================ # Driver Pack Combo $DriverPackCatalog = @('None', 'Microsoft Update Catalog') if ($global:OSDCloudDeploy.DriverPackValues) { $DriverPackCatalog += $global:OSDCloudDeploy.DriverPackValues | ForEach-Object { $_.Name } } $DriverPackCombo = $window.FindName("DriverPackCombo") $DriverPackCombo.ItemsSource = $DriverPackCatalog if ($global:OSDCloudDeploy.DriverPackName) { $DriverPackCombo.SelectedValue = $global:OSDCloudDeploy.DriverPackName } else { $DriverPackCombo.SelectedIndex = 0 } #================================================ # Device Info Text Blocks $deviceBiosReleaseDateText = $window.FindName("deviceBiosReleaseDateText") $deviceBiosReleaseDateText.Text = $deviceBiosReleaseDate $deviceBiosVersionText = $window.FindName("deviceBiosVersionText") $deviceBiosVersionText.Text = $deviceBiosVersion $deviceOSDManufacturerText = $window.FindName("deviceOSDManufacturerText") $deviceOSDManufacturerText.Text = $deviceOSDManufacturer $deviceOSDModelText = $window.FindName("deviceOSDModelText") $deviceOSDModelText.Text = $deviceOSDModel $deviceOSDProductText = $window.FindName("deviceOSDProductText") $deviceOSDProductText.Text = $deviceOSDProduct $deviceComputerSystemSKUText = $window.FindName("deviceComputerSystemSKUText") $deviceComputerSystemSKUText.Text = $deviceComputerSystemSKU function Set-ClipboardText { param([string]$Text) $maxRetries = 5 for ($i = 0; $i -lt $maxRetries; $i++) { try { [System.Windows.Clipboard]::SetText($Text) return } catch { if ($i -lt ($maxRetries - 1)) { Start-Sleep -Milliseconds 100 } else { Write-Warning "Failed to copy to clipboard: $_" } } } } $deviceSerialNumberText = $window.FindName("deviceSerialNumberText") $deviceSerialNumberText.Text = $deviceSerialNumber $deviceSerialNumberText.Add_MouseLeftButtonUp({ $serialNumberValue = [string]$deviceSerialNumberText.Text if ([string]::IsNullOrWhiteSpace($serialNumberValue)) { return } Set-ClipboardText -Text $serialNumberValue }) $deviceIsAutopilotSpecText = $window.FindName("deviceIsAutopilotSpecText") $deviceIsAutopilotSpecText.Text = $deviceIsAutopilotSpec $deviceIsTpmSpecText = $window.FindName("deviceIsTpmSpecText") $deviceIsTpmSpecText.Text = $deviceIsTpmSpec $deviceUUIDText = $window.FindName("deviceUUIDText") $deviceUUIDText.Text = $deviceUUID $deviceUUIDText.Add_MouseLeftButtonUp({ $uuidValue = [string]$deviceUUIDText.Text if ([string]::IsNullOrWhiteSpace($uuidValue)) { return } Set-ClipboardText -Text $uuidValue }) $deviceHardwareHashLabelText = $window.FindName("deviceHardwareHashLabelText") $deviceHardwareHashText = $window.FindName("deviceHardwareHashText") if (-not [string]::IsNullOrWhiteSpace([string]$deviceHardwareHash)) { $deviceHardwareHashLabelText.Visibility = [System.Windows.Visibility]::Visible $deviceHardwareHashText.Text = 'Copy to Clipboard' $deviceHardwareHashText.Visibility = [System.Windows.Visibility]::Visible $deviceHardwareHashText.Add_MouseLeftButtonUp({ Set-ClipboardText -Text ([string]$deviceHardwareHash) }) } #================================================ # Summary / Selected detail text blocks $SelectedOSLanguageText = $window.FindName("SelectedOSLanguageText") $SelectedIdText = $window.FindName("SelectedIdText") $SelectedFileNameText = $window.FindName("SelectedFileNameText") $DriverPackUrlText = $window.FindName("DriverPackUrlText") $DriverPackUrlText.Text = [string]$global:OSDCloudDeploy.DriverPackObject.Url #================================================ # Start Button $StartButton = $window.FindName("StartButton") $StartButton.IsEnabled = $false function Get-ComboValue { param( [Parameter(Mandatory)] [System.Windows.Controls.ComboBox]$ComboBox ) $value = $ComboBox.SelectedItem if ($null -eq $value) { return $null } $text = [string]$value if ([string]::IsNullOrWhiteSpace($text)) { return $null } return $text } function Set-StartButtonState { $StartButton.IsEnabled = ($null -ne $global:OSDCloudDeploy.OperatingSystemObject) } function Update-SelectedDetails { param( [Parameter()] $Item ) if (-not $Item) { $SelectedIdText.Text = 'No matching catalog entry.' $SelectedOSLanguageText.Text = '-' $SelectedFileNameText.Text = '-' return } $SelectedIdText.Text = [string]$Item.Id $SelectedOSLanguageText.Text = if ($Item.OSLanguage) { [string]$Item.OSLanguage } elseif ($Item.OSLanguageCode) { [string]$Item.OSLanguageCode } else { '-' } $SelectedFileNameText.Text = [string]$Item.FileName } function Update-OsResults { $updateOperatingSystem = Get-ComboValue -ComboBox $OperatingSystemCombo $updateOSEdition = Get-ComboValue -ComboBox $OSEditionCombo $updateOSActivation = Get-ComboValue -ComboBox $OSActivationCombo $updateOSLanguageCode = Get-ComboValue -ComboBox $OSLanguageCodeCombo Write-Verbose "[$(Get-Date -format s)] [MainWindow.ps1] updateOperatingSystem = $updateOperatingSystem" Write-Verbose "[$(Get-Date -format s)] [MainWindow.ps1] updateOSEdition = $updateOSEdition" Write-Verbose "[$(Get-Date -format s)] [MainWindow.ps1] updateOSActivation = $updateOSActivation" Write-Verbose "[$(Get-Date -format s)] [MainWindow.ps1] updateOSLanguageCode = $updateOSLanguageCode" $global:OSDCloudDeploy.OperatingSystemObject = $global:DeployOSDCloudOperatingSystems | ` Where-Object { $_.OperatingSystem -match $updateOperatingSystem } | ` Where-Object { $_.OSActivation -eq $updateOSActivation } | ` Where-Object { $_.OSLanguageCode -eq $updateOSLanguageCode } | Select-Object -First 1 if (-not $global:OSDCloudDeploy.OperatingSystemObject) { throw "No Operating System found for OperatingSystem: $updateOperatingSystem, OSActivation: $updateOSActivation, OSLanguageCode: $updateOSLanguageCode. Please check your OSDCloud OperatingSystems." } $script:SelectedImage = $global:OSDCloudDeploy.OperatingSystemObject if ($updateOSEdition -match 'Home') { $OSActivationCombo.SelectedValue = 'Retail' $OSActivationCombo.IsEnabled = $false } if ($updateOSEdition -match 'Education') { $OSActivationCombo.IsEnabled = $true } if ($updateOSEdition -match 'Enterprise') { $OSActivationCombo.SelectedValue = 'Volume' $OSActivationCombo.IsEnabled = $false } if ($updateOSEdition -match 'Pro') { $OSActivationCombo.IsEnabled = $true } Update-SelectedDetails -Item $script:SelectedImage Set-StartButtonState } function Update-DriverPackResults { $selectedDriverPackName = Get-ComboValue -ComboBox $DriverPackCombo $global:OSDCloudDeploy.DriverPackName = $selectedDriverPackName $global:OSDCloudDeploy.DriverPackObject = $global:OSDCloudDeploy.DriverPackValues | Where-Object { $_.Name -eq $selectedDriverPackName } $DriverPackUrlText.Text = [string]$global:OSDCloudDeploy.DriverPackObject.Url } $DriverPackCombo.Add_SelectionChanged({ Update-DriverPackResults }) $OperatingSystemCombo.Add_SelectionChanged({ Update-OsResults }) $OSActivationCombo.Add_SelectionChanged({ Update-OsResults }) $OSEditionCombo.Add_SelectionChanged({ Update-OsResults }) $OSLanguageCodeCombo.Add_SelectionChanged({ Update-OsResults }) $script:SelectionConfirmed = $false $StartButton.Add_Click({ $TaskSequenceStepsGrid.CommitEdit([System.Windows.Controls.DataGridEditingUnit]::Cell, $true) | Out-Null $TaskSequenceStepsGrid.CommitEdit([System.Windows.Controls.DataGridEditingUnit]::Row, $true) | Out-Null Save-TaskSequenceSteps -TaskSequenceName $script:CurrentTaskSequenceName -Steps $TaskSequenceStepsGrid.ItemsSource $script:SelectionConfirmed = $true $window.DialogResult = $true $window.Close() }) Update-OsResults # Initialize task sequence summary if present if ($SummaryTaskSequenceText) { $value = [string]$TaskSequenceCombo.SelectedItem $SummaryTaskSequenceText.Text = if (-not [string]::IsNullOrWhiteSpace($value)) { $value } else { 'Not selected' } } $null = $window.ShowDialog() if ($script:SelectionConfirmed) { #================================================ # Local Variables $OSDCloudWorkflowTaskName = $TaskSequenceCombo.SelectedValue $OSDCloudWorkflowTaskObject = $global:OSDCloudDeploy.Flows | Where-Object { $_.Name -eq $OSDCloudWorkflowTaskName } | Select-Object -First 1 $OperatingSystemObject = $global:OSDCloudDeploy.OperatingSystemObject $OSEditionId = $global:OSDCloudDeploy.OSEditionValues | Where-Object { $_.Edition -eq $OSEditionCombo.SelectedValue } | Select-Object -ExpandProperty EditionId #================================================ # Global Variables $global:OSDCloudDeploy.WorkflowTaskName = $OSDCloudWorkflowTaskName $global:OSDCloudDeploy.WorkflowTaskObject = $OSDCloudWorkflowTaskObject $global:OSDCloudDeploy.ImageFileName = $OperatingSystemObject.FileName $global:OSDCloudDeploy.ImageFileUrl = $OperatingSystemObject.FilePath $global:OSDCloudDeploy.OperatingSystemObject = $OperatingSystemObject $global:OSDCloudDeploy.OperatingSystem = $OperatingSystemObject.OSName $global:OSDCloudDeploy.OSActivation = $OperatingSystemObject.OSActivation $global:OSDCloudDeploy.OSBuild = $OperatingSystemObject.OSBuild $global:OSDCloudDeploy.OSEdition = Get-ComboValue -ComboBox $OSEditionCombo $global:OSDCloudDeploy.OSEditionId = $OSEditionId $global:OSDCloudDeploy.OSLanguageCode = $OperatingSystemObject.OSLanguageCode $global:OSDCloudDeploy.OperatingSystem = $OperatingSystemObject.OperatingSystem $global:OSDCloudDeploy.OSVersion = $OperatingSystemObject.OSVersion $global:OSDCloudDeploy.TimeStart = (Get-Date) $global:OSDCloudDeploy.LocalImageFileInfo = $LocalImageFileInfo $global:OSDCloudDeploy.LocalImageFilePath = $LocalImageFilePath $global:OSDCloudDeploy.LocalImageName = $LocalImageName $LogsPath = "$env:TEMP\osdcloud-logs" if (-not (Test-Path -Path $LogsPath)) { New-Item -Path $LogsPath -ItemType Directory -Force | Out-Null } $global:OSDCloudDeploy | ConvertTo-Json | Out-File -FilePath "$LogsPath\OSDCloudDeploy.json" -Encoding utf8 -Width 2000 -Force -ErrorAction SilentlyContinue -WarningAction SilentlyContinue } |