Renommage du profil unattend pour mieux correspondre à ce qu'il fait. Ajout d'un warning si WinRE n'est pas assez grands au regard des préconisations Microsoft et du redémarrage automatique si l'installation réussi.
897 lines
41 KiB
PowerShell
897 lines
41 KiB
PowerShell
# DeployCenter - Interface WinPE
|
||
# Compatible Windows PowerShell 5.1
|
||
|
||
param(
|
||
# Affiche DeployCenter dans une fenetre redimensionnable pour le debug.
|
||
[switch]$Windowed,
|
||
[switch]$Vnc
|
||
)
|
||
|
||
$script:Windowed = [bool]$Windowed
|
||
$ErrorActionPreference = "Stop"
|
||
|
||
Add-Type -AssemblyName System.Windows.Forms
|
||
Add-Type -AssemblyName System.Drawing
|
||
[System.Windows.Forms.Application]::EnableVisualStyles()
|
||
|
||
Import-Module (Join-Path $PSScriptRoot "Modules\ThemeManager.psm1") -Force
|
||
$uiModulePath = Join-Path $PSScriptRoot 'Modules\UI.psm1'
|
||
if (-not (Test-Path -LiteralPath $uiModulePath -PathType Leaf)) { throw "Module UI introuvable : $uiModulePath" }
|
||
# Les workflows UI utilisent l'état de la session principale ; ce fichier est donc chargé dans ce scope.
|
||
. ([scriptblock]::Create([System.IO.File]::ReadAllText($uiModulePath)))
|
||
Import-Module (Join-Path $PSScriptRoot "Modules\Configuration.psm1") -Force
|
||
Import-Module (Join-Path $PSScriptRoot "Modules\HardwareInventory.psm1") -Force
|
||
|
||
# GroupBox dessine par DeployCenter pour que le fond et le cadre suivent les themes.
|
||
if (-not ([System.Management.Automation.PSTypeName]'DeployCenter.ThemedGroupBox').Type) {
|
||
Add-Type -TypeDefinition @'
|
||
using System;
|
||
using System.Drawing;
|
||
using System.Windows.Forms;
|
||
|
||
namespace DeployCenter {
|
||
public class ThemedGroupBox : GroupBox {
|
||
public Color PanelColor { get; set; }
|
||
public Color BorderColor { get; set; }
|
||
public Color TextColor { get; set; }
|
||
|
||
public ThemedGroupBox() {
|
||
SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint |
|
||
ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw, true);
|
||
PanelColor = SystemColors.Control;
|
||
BorderColor = SystemColors.ControlDark;
|
||
TextColor = SystemColors.ControlText;
|
||
}
|
||
|
||
protected override void OnPaint(PaintEventArgs e) {
|
||
Graphics g = e.Graphics;
|
||
g.Clear(PanelColor);
|
||
Size textSize = TextRenderer.MeasureText(Text, Font);
|
||
int textLeft = 10;
|
||
int lineY = Math.Max(8, (int)Math.Ceiling(textSize.Height / 2.0));
|
||
using (Pen pen = new Pen(BorderColor)) {
|
||
g.DrawLine(pen, 0, lineY, textLeft - 2, lineY);
|
||
int afterText = textLeft + textSize.Width + 4;
|
||
if (afterText < Width - 2) g.DrawLine(pen, afterText, lineY, Width - 2, lineY);
|
||
g.DrawLine(pen, 0, lineY, 0, Height - 2);
|
||
g.DrawLine(pen, 0, Height - 2, Width - 2, Height - 2);
|
||
g.DrawLine(pen, Width - 2, lineY, Width - 2, Height - 2);
|
||
}
|
||
TextRenderer.DrawText(g, Text, Font, new Point(textLeft, 0), TextColor,
|
||
PanelColor, TextFormatFlags.NoPadding | TextFormatFlags.SingleLine);
|
||
}
|
||
}
|
||
}
|
||
'@ -ReferencedAssemblies System.Windows.Forms,System.Drawing
|
||
}
|
||
|
||
# ============================================================
|
||
# CHEMINS
|
||
# ============================================================
|
||
|
||
$script:DeployRoot = $PSScriptRoot
|
||
# Racine du lecteur qui heberge DeployCenter (ex. Y:\), sans lecteur code en dur.
|
||
$script:DeployVolumeRoot = $null
|
||
try {
|
||
$deployQualifier = Split-Path -Path $script:DeployRoot -Qualifier -ErrorAction Stop
|
||
if (-not [string]::IsNullOrWhiteSpace($deployQualifier)) {
|
||
$script:DeployVolumeRoot = $deployQualifier.TrimEnd('\') + '\'
|
||
}
|
||
} catch {
|
||
$script:DeployVolumeRoot = $null
|
||
}
|
||
$script:AssetsRoot = Join-Path $script:DeployRoot "Assets"
|
||
$script:LogoPath = Join-Path $script:AssetsRoot "logo.png"
|
||
$script:LogoDarkPath = Join-Path $script:AssetsRoot "logo-dark.png"
|
||
$script:LogRoot = Join-Path $script:DeployRoot "Logs"
|
||
|
||
# Détection réseau centralisée dans Modules\\Network.psm1.
|
||
$networkModulePath = Join-Path $PSScriptRoot "Modules\\Network.psm1"
|
||
if (-not (Test-Path -LiteralPath $networkModulePath -PathType Leaf)) {
|
||
throw "Module réseau introuvable : $networkModulePath"
|
||
}
|
||
. ([scriptblock]::Create([System.IO.File]::ReadAllText($networkModulePath)))
|
||
$script:DeployIPv4 = Get-DeployNetworkIPv4
|
||
|
||
# La gestion des journaux est centralisee dans Modules\\Logging.psm1.
|
||
$loggingModulePath = Join-Path $PSScriptRoot "Modules\\Logging.psm1"
|
||
if (-not (Test-Path -LiteralPath $loggingModulePath -PathType Leaf)) {
|
||
throw "Module de journalisation introuvable : $loggingModulePath"
|
||
}
|
||
. ([scriptblock]::Create([System.IO.File]::ReadAllText($loggingModulePath)))
|
||
Initialize-DeployCenterLogging -LogRoot $script:LogRoot -IPv4 $script:DeployIPv4
|
||
# Garder le scope du script principal pour que Write-Log reste résolu dans les callbacks WinForms.
|
||
$script:SourceLogAction = {
|
||
param($Message, $Level)
|
||
if ([string]::IsNullOrWhiteSpace([string]$Level)) { $Level = 'INFO' }
|
||
Write-Log -Message $Message -Level $Level
|
||
}
|
||
# Analyse des sources et des images Windows.
|
||
$windowsSourcesModulePath = Join-Path $script:DeployRoot 'Modules\WindowsSources.psm1'
|
||
if (-not (Test-Path -LiteralPath $windowsSourcesModulePath -PathType Leaf)) {
|
||
throw "Module de sources Windows introuvable : $windowsSourcesModulePath"
|
||
}
|
||
Import-Module $windowsSourcesModulePath -Force
|
||
|
||
# Les profils de partitionnement sont des fichiers de données PSD1, validés par leur module.
|
||
$partitioningModulePath = Join-Path $script:DeployRoot 'Modules\Partitioning.psm1'
|
||
if (-not (Test-Path -LiteralPath $partitioningModulePath -PathType Leaf)) {
|
||
throw "Module de partitionnement introuvable : $partitioningModulePath"
|
||
}
|
||
Import-Module $partitioningModulePath -Force
|
||
$deploymentModulePath = Join-Path $script:DeployRoot 'Modules\Deployment.psm1'
|
||
if (-not (Test-Path -LiteralPath $deploymentModulePath -PathType Leaf)) {
|
||
throw "Module de déploiement introuvable : $deploymentModulePath"
|
||
}
|
||
Import-Module $deploymentModulePath -Force
|
||
$unattendModulePath = Join-Path $script:DeployRoot 'Modules\Unattend.psm1'
|
||
if (-not (Test-Path -LiteralPath $unattendModulePath -PathType Leaf)) {
|
||
throw "Module Unattend introuvable : $unattendModulePath"
|
||
}
|
||
Import-Module $unattendModulePath -Force
|
||
$script:PartitionProfilesRoot = Join-Path $script:DeployRoot 'Partitioning\Profiles'
|
||
$script:PartitionProfiles = @()
|
||
foreach ($profileName in (Get-DeployCenterPartitionProfileNames -ProfilesRoot $script:PartitionProfilesRoot)) {
|
||
try {
|
||
$script:PartitionProfiles += Import-DeployCenterPartitionProfile -ProfilesRoot $script:PartitionProfilesRoot -ProfileName $profileName
|
||
} catch {
|
||
& $script:SourceLogAction "Profil de partitionnement '$profileName' ignoré : $($_.Exception.Message)" 'WARNING'
|
||
}
|
||
}
|
||
if ($script:PartitionProfiles.Count -eq 0) {
|
||
throw "Aucun profil de partitionnement valide trouvé dans $script:PartitionProfilesRoot"
|
||
}
|
||
$script:SelectedPartitionProfileIndex = 0
|
||
for ($profileIndex = 0; $profileIndex -lt $script:PartitionProfiles.Count; $profileIndex++) {
|
||
if ($script:PartitionProfiles[$profileIndex].Default -eq $true) {
|
||
$script:SelectedPartitionProfileIndex = $profileIndex
|
||
break
|
||
}
|
||
}
|
||
$script:SelectedPartitionProfile = $script:PartitionProfiles[$script:SelectedPartitionProfileIndex]
|
||
$script:SelectedPartitionSizing = $null
|
||
$script:SelectedDiskIndex = $null
|
||
$script:SelectedWindowsEdition = $null
|
||
$script:RestartAfterDeployment = $false
|
||
$script:RefreshingDiskList = $false
|
||
$script:ChangingPartitionProfileSelection = $false
|
||
|
||
# Inventaire de session et UltraVNC portable : tout reste dans le dossier temporaire.
|
||
$script:InventoryDir = Join-Path $env:TEMP 'DeployCenter'
|
||
$script:InventoryFile = Join-Path $script:InventoryDir 'DeployCenter_Inventory.json'
|
||
$script:VncPassword = $null
|
||
$script:VncDirectory = Join-Path $script:InventoryDir ("uvnc_{0}" -f $PID)
|
||
$script:VncProcess = $null
|
||
$script:VncStarted = $false
|
||
$script:HardwareInventory = $null
|
||
|
||
# ============================================================
|
||
# THEMES EXTERNES (Themes\*.psd1)
|
||
# Les thèmes sont des fichiers de données ; aucun code PowerShell n'est exécuté.
|
||
# ============================================================
|
||
|
||
$script:ThemesRoot = Join-Path $script:DeployRoot "Themes"
|
||
if (-not (Test-Path -LiteralPath $script:ThemesRoot -PathType Container)) {
|
||
New-Item -Path $script:ThemesRoot -ItemType Directory -Force | Out-Null
|
||
}
|
||
|
||
# ============================================================
|
||
# PREFERENCES (DeployCenter.ini en lecture seule : aucune ecriture automatique)
|
||
# ============================================================
|
||
|
||
$script:ConfigPath = Join-Path $script:DeployRoot "DeployCenter.ini"
|
||
|
||
# Themes par defaut : crees uniquement si absents, afin de faciliter les personnalisations.
|
||
$defaultThemeFiles = @{
|
||
Dark = @"
|
||
@{
|
||
Background = "#171A21"
|
||
Panel = "#222731"
|
||
PanelAlt = "#1C2029"
|
||
Text = "#F1F5F9"
|
||
Secondary = "#9CA9BC"
|
||
Accent = "#3B82F6"
|
||
Success = "#4ADE80"
|
||
Border = "#414A59"
|
||
Danger = "#EF4444"
|
||
Button = @{
|
||
Background = "#303744"; Foreground = "#F1F5F9"; Border = "#414A59"
|
||
HoverBackground = "#3B4555"; PressedBackground = "#485365"
|
||
DisabledBackground = "#292E38"; DisabledForeground = "#7F8999"
|
||
}
|
||
PrimaryButton = @{
|
||
Background = "#3B82F6"; Foreground = "#FFFFFF"; Border = "#3B82F6"
|
||
HoverBackground = "#2563EB"; PressedBackground = "#1D4ED8"
|
||
DisabledBackground = "#344A6A"; DisabledForeground = "#9AAAC1"
|
||
}
|
||
DangerButton = @{
|
||
Background = "#EF4444"; Foreground = "#FFFFFF"; Border = "#EF4444"
|
||
HoverBackground = "#DC2626"; PressedBackground = "#B91C1C"
|
||
DisabledBackground = "#59383B"; DisabledForeground = "#BBA0A2"
|
||
}
|
||
}
|
||
"@
|
||
Light = @"
|
||
@{
|
||
Background = "#F5F7FA"
|
||
Panel = "#FFFFFF"
|
||
PanelAlt = "#F8FAFC"
|
||
Text = "#1E293B"
|
||
Secondary = "#475569"
|
||
Accent = "#2563EB"
|
||
Success = "#16A34A"
|
||
Border = "#CBD5E1"
|
||
Danger = "#DC2626"
|
||
Button = @{
|
||
Background = "#E8EDF3"; Foreground = "#1E293B"; Border = "#CBD5E1"
|
||
HoverBackground = "#DCE4EE"; PressedBackground = "#CBD5E1"
|
||
DisabledBackground = "#F1F3F6"; DisabledForeground = "#94A3B8"
|
||
}
|
||
PrimaryButton = @{
|
||
Background = "#2563EB"; Foreground = "#FFFFFF"; Border = "#2563EB"
|
||
HoverBackground = "#1D4ED8"; PressedBackground = "#1E40AF"
|
||
DisabledBackground = "#C7D8F8"; DisabledForeground = "#F8FAFC"
|
||
}
|
||
DangerButton = @{
|
||
Background = "#DC2626"; Foreground = "#FFFFFF"; Border = "#DC2626"
|
||
HoverBackground = "#B91C1C"; PressedBackground = "#991B1B"
|
||
DisabledBackground = "#F2C5C5"; DisabledForeground = "#FFF7F7"
|
||
}
|
||
}
|
||
"@
|
||
}
|
||
foreach ($themeFileName in $defaultThemeFiles.Keys) {
|
||
$themeFilePath = Join-Path $script:ThemesRoot ($themeFileName + '.psd1')
|
||
if (-not (Test-Path -LiteralPath $themeFilePath -PathType Leaf)) {
|
||
Set-Content -LiteralPath $themeFilePath -Value $defaultThemeFiles[$themeFileName] -Encoding UTF8
|
||
}
|
||
}
|
||
|
||
$script:Config = Read-DeployCenterConfig -ConfigPath $script:ConfigPath
|
||
$script:UnattendProfilesRoot = Join-Path $script:DeployRoot 'Unattend\Profiles'
|
||
$script:UnattendProfiles = @()
|
||
foreach ($unattendProfileName in (Get-DeployCenterUnattendProfileNames -ProfilesRoot $script:UnattendProfilesRoot)) {
|
||
try {
|
||
$script:UnattendProfiles += Import-DeployCenterUnattendProfile `
|
||
-ProfilesRoot $script:UnattendProfilesRoot -ProfileName $unattendProfileName
|
||
} catch {
|
||
& $script:SourceLogAction "Profil Unattend '$unattendProfileName' ignoré : $($_.Exception.Message)" 'WARNING'
|
||
}
|
||
}
|
||
$duplicateUnattendNames = @($script:UnattendProfiles | Group-Object -Property Name | Where-Object Count -gt 1)
|
||
foreach ($duplicateName in $duplicateUnattendNames) {
|
||
& $script:SourceLogAction "Profils Unattend ignorés car leur nom affiché est en double : $($duplicateName.Name)." 'WARNING'
|
||
$script:UnattendProfiles = @($script:UnattendProfiles | Where-Object { [string]$_.Name -ne [string]$duplicateName.Name })
|
||
}
|
||
$script:UnattendOobeChoice = 'Avec OOBE'
|
||
foreach ($partitionProfile in $script:PartitionProfiles) {
|
||
foreach ($partition in $partitionProfile.Partitions) {
|
||
if ([string]$partition.Size.Policy -ne 'ConfiguredMB') { continue }
|
||
$configKey = [string]$partition.Size.ConfigKey
|
||
if (-not $script:Config.ContainsKey($configKey)) {
|
||
throw "Le paramètre DeployCenter.ini '$configKey' requis par le profil '$($partitionProfile.Name)' est absent de la configuration."
|
||
}
|
||
$configuredSizeMB = [int]$script:Config[$configKey]
|
||
if ($configuredSizeMB -le 0) {
|
||
throw "Le paramètre DeployCenter.ini '$configKey' doit être strictement positif."
|
||
}
|
||
$partition.Size.Value = $configuredSizeMB
|
||
$partition.Size.PreviewMB = $configuredSizeMB
|
||
}
|
||
}
|
||
$availableThemes = @(Get-DeployCenterThemeNames -ThemesRoot $script:ThemesRoot)
|
||
if ($availableThemes.Count -eq 0) { throw "Aucun thème valide trouvé dans $script:ThemesRoot" }
|
||
if ($availableThemes -notcontains $script:Config.Theme) { $script:Config.Theme = "Light" }
|
||
$script:CurrentTheme = $script:Config.Theme
|
||
try {
|
||
$script:Theme = Import-DeployCenterTheme -ThemesRoot $script:ThemesRoot -ThemeName $script:CurrentTheme
|
||
} catch {
|
||
$script:CurrentTheme = "Light"
|
||
$script:Config.Theme = "Light"
|
||
$script:Theme = Import-DeployCenterTheme -ThemesRoot $script:ThemesRoot -ThemeName "Light"
|
||
}
|
||
# ============================================================
|
||
# POLICES
|
||
# ============================================================
|
||
|
||
$script:FontRegular = [System.Drawing.Font]::new("Segoe UI", [single]10, [System.Drawing.FontStyle]::Regular)
|
||
$script:FontSmall = [System.Drawing.Font]::new("Segoe UI", [single]9, [System.Drawing.FontStyle]::Regular)
|
||
$script:FontTitle = [System.Drawing.Font]::new("Segoe UI", [single]23, [System.Drawing.FontStyle]::Bold)
|
||
$script:FontSubtitle = [System.Drawing.Font]::new("Segoe UI", [single]10, [System.Drawing.FontStyle]::Regular)
|
||
$script:FontGroup = [System.Drawing.Font]::new("Segoe UI", [single]11, [System.Drawing.FontStyle]::Bold)
|
||
|
||
# ============================================================
|
||
# RESEAU, ULTRAVNC ET INVENTAIRE DE SESSION
|
||
# ============================================================
|
||
|
||
|
||
|
||
|
||
# L'adresse IPv4 a été détectée par Modules\\Network.psm1 avant l'initialisation du journal.
|
||
|
||
# VNC est désactivé par défaut ; il démarre uniquement avec le paramètre -vnc.
|
||
$script:EnableVnc = [bool]$Vnc
|
||
if ($script:EnableVnc) {
|
||
try {
|
||
# Le code VNC est exécuté dans le scope principal uniquement avec -vnc.
|
||
$vncModulePath = Join-Path $PSScriptRoot "Modules\VNC.psm1"
|
||
if (-not (Test-Path -LiteralPath $vncModulePath -PathType Leaf)) {
|
||
throw "Module VNC introuvable : $vncModulePath"
|
||
}
|
||
$vncCode = [System.IO.File]::ReadAllText($vncModulePath)
|
||
. ([scriptblock]::Create($vncCode))
|
||
Start-DeployCenterVnc
|
||
} catch {
|
||
& $script:SourceLogAction "Impossible de démarrer VNC : $($_.Exception.Message)" 'ERROR'
|
||
}
|
||
} else {
|
||
& $script:SourceLogAction "UltraVNC non démarré : paramètre -vnc absent."
|
||
}
|
||
|
||
# ============================================================
|
||
# CREATION DES CONTROLES
|
||
# ============================================================
|
||
|
||
# ============================================================
|
||
# FENETRE PRINCIPALE
|
||
# ============================================================
|
||
|
||
$script:form = New-Object System.Windows.Forms.Form
|
||
$script:form.Text = "DeployCenter"
|
||
$script:form.BackColor = $script:Theme.Background
|
||
if ($script:Windowed) {
|
||
# Mode debug : fenetre classique, deplacable et reductible.
|
||
$script:form.StartPosition = [System.Windows.Forms.FormStartPosition]::CenterScreen
|
||
$script:form.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::Sizable
|
||
$script:form.WindowState = [System.Windows.Forms.FormWindowState]::Normal
|
||
$script:form.TopMost = $false
|
||
$screen = [System.Windows.Forms.Screen]::PrimaryScreen.WorkingArea
|
||
$debugWidth = [Math]::Min(1200, [Math]::Max(800, $screen.Width - 80))
|
||
$debugHeight = [Math]::Min(850, [Math]::Max(600, $screen.Height - 80))
|
||
$script:form.Size = New-Object System.Drawing.Size($debugWidth, $debugHeight)
|
||
} else {
|
||
# Mode normal : plein ecran, sans bordure et au premier plan.
|
||
$script:form.StartPosition = "Manual"
|
||
$script:form.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::None
|
||
$script:form.WindowState = [System.Windows.Forms.FormWindowState]::Maximized
|
||
$script:form.TopMost = $true
|
||
$script:form.Bounds = [System.Windows.Forms.Screen]::PrimaryScreen.Bounds
|
||
}
|
||
$script:form.ForeColor = $script:Theme.Text
|
||
$script:form.Font = $script:FontRegular
|
||
$script:form.KeyPreview = $true
|
||
$script:form.MinimumSize = New-Object System.Drawing.Size(800, 600)
|
||
|
||
$screenWidth = $script:form.ClientSize.Width
|
||
$screenHeight = $script:form.ClientSize.Height
|
||
$margin = 30
|
||
$usableWidth = $screenWidth - (2 * $margin)
|
||
|
||
# ============================================================
|
||
# EN-TETE ET LOGO FACULTATIF
|
||
# ============================================================
|
||
|
||
$script:pictureLogo = $null
|
||
$titleX = 30
|
||
|
||
# Deux fichiers seulement : logo.png (clair et solution de repli) et logo-dark.png.
|
||
# En mode sombre, logo-dark.png est prioritaire ; s'il manque, logo.png est utilise.
|
||
# En mode clair, logo.png est utilise.
|
||
$initialLogoPath = Get-DeployCenterLogoPathForTheme -ThemeName $script:CurrentTheme `
|
||
-LogoPath $script:LogoPath -LogoDarkPath $script:LogoDarkPath
|
||
if ($null -ne $initialLogoPath) {
|
||
try {
|
||
$script:pictureLogo = New-Object System.Windows.Forms.PictureBox
|
||
$script:pictureLogo.Location = New-Object System.Drawing.Point(30, 20)
|
||
$script:pictureLogo.Size = New-Object System.Drawing.Size(64, 64)
|
||
$script:pictureLogo.SizeMode = [System.Windows.Forms.PictureBoxSizeMode]::Zoom
|
||
$script:pictureLogo.BackColor = [System.Drawing.Color]::Transparent
|
||
$script:pictureLogo.Image = [System.Drawing.Image]::FromFile($initialLogoPath)
|
||
$script:form.Controls.Add($script:pictureLogo)
|
||
$titleX = 110
|
||
}
|
||
catch {
|
||
$script:pictureLogo = $null
|
||
$titleX = 30
|
||
}
|
||
}
|
||
|
||
$script:lblTitle = New-Label -Text "DeployCenter" `
|
||
-X $titleX -Y 17 -Width 600 -Height 42 -Theme $script:Theme -Font $script:FontTitle `
|
||
-Color $script:Theme.Text
|
||
|
||
$script:lblSubtitle = New-Label `
|
||
-Text "Environnement de déploiement Windows" `
|
||
-X ($titleX + 4) -Y 61 -Width 650 -Height 24 -Theme $script:Theme -Font $script:FontSubtitle `
|
||
-Color $script:Theme.Secondary
|
||
|
||
$script:form.Controls.Add($script:lblTitle)
|
||
$script:form.Controls.Add($script:lblSubtitle)
|
||
|
||
# Menu de selection du theme ; les noms correspondent aux fichiers Themes\<Nom>.psd1
|
||
$script:cmbTheme = New-Object System.Windows.Forms.ComboBox
|
||
$script:cmbTheme.DropDownStyle = [System.Windows.Forms.ComboBoxStyle]::DropDownList
|
||
# OwnerDraw permet de colorer aussi la liste deroulante, que WinForms laisse sinon au theme systeme.
|
||
$script:cmbTheme.DrawMode = [System.Windows.Forms.DrawMode]::OwnerDrawFixed
|
||
$script:cmbTheme.ItemHeight = 24
|
||
$script:cmbTheme.Font = $script:FontRegular
|
||
$script:cmbTheme.Width = 190
|
||
$script:cmbTheme.Height = 32
|
||
$script:cmbTheme.Location = New-Object System.Drawing.Point(0, 29)
|
||
$script:cmbTheme.Anchor = [System.Windows.Forms.AnchorStyles]::Top -bor [System.Windows.Forms.AnchorStyles]::Right
|
||
foreach ($themeName in (Get-DeployCenterThemeNames -ThemesRoot $script:ThemesRoot)) { [void]$script:cmbTheme.Items.Add($themeName) }
|
||
$script:cmbTheme.SelectedItem = $script:CurrentTheme
|
||
$script:cmbTheme.BackColor = $script:Theme.Panel
|
||
$script:cmbTheme.ForeColor = $script:Theme.Text
|
||
$script:cmbTheme.Add_DrawItem({
|
||
param($sender, $e)
|
||
if ($e.Index -lt 0) {
|
||
$itemText = [string]$sender.Text
|
||
} else {
|
||
$itemText = [string]$sender.Items[$e.Index]
|
||
}
|
||
$isSelected = (($e.State -band [System.Windows.Forms.DrawItemState]::Selected) -ne 0)
|
||
if ($isSelected) {
|
||
$backgroundColor = $script:Theme.Accent
|
||
$foregroundColor = [System.Drawing.Color]::White
|
||
} else {
|
||
$backgroundColor = $script:Theme.Panel
|
||
$foregroundColor = $script:Theme.Text
|
||
}
|
||
$backgroundBrush = New-Object System.Drawing.SolidBrush($backgroundColor)
|
||
try { $e.Graphics.FillRectangle($backgroundBrush, $e.Bounds) }
|
||
finally { $backgroundBrush.Dispose() }
|
||
if (-not [string]::IsNullOrEmpty($itemText)) {
|
||
$textBounds = $e.Bounds
|
||
$textBounds.X += 4
|
||
[System.Windows.Forms.TextRenderer]::DrawText(
|
||
$e.Graphics, $itemText, $sender.Font, $textBounds, $foregroundColor,
|
||
([System.Windows.Forms.TextFormatFlags]::Left -bor [System.Windows.Forms.TextFormatFlags]::VerticalCenter -bor [System.Windows.Forms.TextFormatFlags]::EndEllipsis)
|
||
)
|
||
}
|
||
$e.DrawFocusRectangle()
|
||
})
|
||
$script:form.Controls.Add($script:cmbTheme)
|
||
$script:cmbTheme.BringToFront()
|
||
|
||
# ============================================================
|
||
# INFORMATIONS DU PC
|
||
# ============================================================
|
||
|
||
$script:groupPC = New-GroupBox -Text "Informations du PC" `
|
||
-X $margin -Y 100 -Width $usableWidth -Height 90 -Theme $script:Theme -Font $script:FontGroup
|
||
|
||
$script:lblManufacturer = New-Label -Text "Fabricant : -" `
|
||
-X 18 -Y 25 -Width 330 -Height 24 -Theme $script:Theme -Font $script:FontRegular
|
||
$script:lblModel = New-Label -Text "Modèle : -" `
|
||
-X 360 -Y 25 -Width 400 -Height 24 -Theme $script:Theme -Font $script:FontRegular
|
||
$script:lblSerial = New-Label -Text "Numéro de série : -" `
|
||
-X 18 -Y 52 -Width 330 -Height 24 -Theme $script:Theme -Font $script:FontRegular
|
||
$script:lblFirmware = New-Label -Text "Firmware : -" `
|
||
-X 360 -Y 52 -Width 220 -Height 24 -Theme $script:Theme -Font $script:FontRegular
|
||
$script:lblArchitecture = New-Label -Text "Architecture : -" `
|
||
-X 600 -Y 52 -Width 220 -Height 24 -Theme $script:Theme -Font $script:FontRegular
|
||
$script:groupPC.Controls.AddRange(@(
|
||
$script:lblManufacturer,
|
||
$script:lblModel,
|
||
$script:lblSerial,
|
||
$script:lblFirmware,
|
||
$script:lblArchitecture
|
||
))
|
||
$script:form.Controls.Add($script:groupPC)
|
||
|
||
# ============================================================
|
||
# PREPARATION DU DEPLOIEMENT
|
||
# ============================================================
|
||
|
||
$script:groupDisks = New-GroupBox -Text "Préparation du déploiement" `
|
||
-X $margin -Y 205 -Width $usableWidth -Height 270 -Theme $script:Theme -Font $script:FontGroup
|
||
|
||
$deploymentControls = New-DeployCenterDeploymentControls `
|
||
-Parent $script:groupDisks `
|
||
-ProfileNames @($script:PartitionProfiles | ForEach-Object { [string]$_.Name }) `
|
||
-Theme $script:Theme `
|
||
-Font $script:FontSmall
|
||
$script:cmbDisk = $deploymentControls.DiskComboBox
|
||
$script:btnChooseWindows = $deploymentControls.ChooseSystemButton
|
||
$script:lblSelectedWindows = $deploymentControls.SelectedSystemLabel
|
||
$script:lblPartitionProfile = $deploymentControls.PartitionProfileLabel
|
||
$script:cmbPartitionProfile = $deploymentControls.PartitionProfileComboBox
|
||
$script:cmbUnattendProfile = $deploymentControls.UnattendProfileComboBox
|
||
$script:DeploymentControls = $deploymentControls
|
||
$script:lblHostName = $deploymentControls.HostNameLabel
|
||
$script:txtHostName = $deploymentControls.HostNameTextBox
|
||
$script:cmbPartitionProfile.SelectedIndex = $script:SelectedPartitionProfileIndex
|
||
|
||
$script:form.Controls.Add($script:groupDisks)
|
||
|
||
|
||
|
||
# ============================================================
|
||
# JOURNAL DANS UNE FENETRE DEDIEE
|
||
# ============================================================
|
||
|
||
$logWindow = New-DeployCenterLogWindow -Theme $script:Theme -Font $script:FontRegular
|
||
$script:logForm = $logWindow.Form
|
||
$script:txtLog = $logWindow.TextBox
|
||
|
||
$buttonHeight = 38
|
||
# En plein ecran, rapprocher les boutons du bas sans empiéter sur le pied de page.
|
||
# En mode fenetre, conserver la position actuelle.
|
||
$buttonY = if ($script:Windowed) {
|
||
$screenHeight - 54 - $buttonHeight
|
||
} else {
|
||
$screenHeight - 42 - $buttonHeight
|
||
}
|
||
# BOUTONS JOURNAL, ACTUALISER ET FERMER
|
||
# ============================================================
|
||
|
||
$buttonWidth = 140
|
||
$buttonGap = 12
|
||
$closeX = $screenWidth - $margin - $buttonWidth
|
||
$deployX = $closeX - $buttonGap - $buttonWidth
|
||
$refreshX = $deployX - $buttonGap - $buttonWidth
|
||
$script:btnLog = New-Button -Text "Journal" `
|
||
-X $margin -Y $buttonY -Width $buttonWidth -Height $buttonHeight `
|
||
-Theme $script:Theme -Font $script:FontRegular `
|
||
-Role "Button"
|
||
|
||
$script:btnRefresh = New-Button -Text "Actualiser" `
|
||
-X $refreshX -Y $buttonY -Width $buttonWidth -Height $buttonHeight `
|
||
-Theme $script:Theme -Font $script:FontRegular `
|
||
-Role "PrimaryButton"
|
||
|
||
$script:btnDeploy = New-Button -Text "Installer" `
|
||
-X $deployX -Y $buttonY -Width $buttonWidth -Height $buttonHeight `
|
||
-Theme $script:Theme -Font $script:FontRegular `
|
||
-Role "PrimaryButton"
|
||
|
||
$script:btnClose = New-Button -Text "Fermer" `
|
||
-X $closeX -Y $buttonY -Width $buttonWidth -Height $buttonHeight `
|
||
-Theme $script:Theme -Font $script:FontRegular `
|
||
-Role "DangerButton"
|
||
|
||
$script:form.Controls.Add($script:btnLog)
|
||
$script:form.Controls.Add($script:btnRefresh)
|
||
$script:form.Controls.Add($script:btnDeploy)
|
||
$script:form.Controls.Add($script:btnClose)
|
||
Add-SessionFooter -TargetForm $script:form -Theme $script:Theme -Font $script:FontSmall `
|
||
-IPv4 $script:DeployIPv4 -VncPassword $script:VncPassword -ShowPassword $true
|
||
|
||
# ============================================================
|
||
# APPLICATION DU THEME A TOUS LES CONTROLES
|
||
# ============================================================
|
||
|
||
|
||
|
||
|
||
|
||
# ============================================================
|
||
# DETECTION DES SOURCES WINDOWS SUR PARTAGE SMB
|
||
# ============================================================
|
||
|
||
|
||
|
||
# ============================================================
|
||
# INVENTAIRE MATERIEL
|
||
# ============================================================
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
# ============================================================
|
||
# MISE EN PAGE ADAPTATIVE
|
||
# Les grandes zones suivent la fenetre ; les marges et hauteurs de controles restent fixes.
|
||
# ============================================================
|
||
|
||
|
||
|
||
# ============================================================
|
||
# EVENEMENTS
|
||
# ============================================================
|
||
|
||
$script:btnChooseWindows.Add_Click({
|
||
Show-WindowsSourcesDialog
|
||
if ($script:SelectedWindowsEdition) {
|
||
$edition = $script:SelectedWindowsEdition
|
||
$sourceDescription = if ($edition.ImagePath) { [string]$edition.ImagePath } else { [string]$edition.SourcePath }
|
||
$script:lblSelectedWindows.Text = "{0} (index {1}) — {2}" -f $edition.Name, $edition.Index, $sourceDescription
|
||
$script:lblSelectedWindows.ForeColor = $script:Theme.Success
|
||
$script:lblSelectedWindows.Name = 'lblSelectedWindows'
|
||
$script:cmbPartitionProfile.Enabled = $true
|
||
Set-DeployCenterUnattendProfileChoices -ComboBox $script:cmbUnattendProfile `
|
||
-Profiles $script:UnattendProfiles -EditionName ([string]$edition.Name) `
|
||
-OobeChoice $script:UnattendOobeChoice
|
||
}
|
||
})
|
||
|
||
$script:cmbUnattendProfile.Add_SelectedIndexChanged({
|
||
$showHostName = $script:cmbUnattendProfile.SelectedItem -and
|
||
[string]$script:cmbUnattendProfile.SelectedItem -ne $script:UnattendOobeChoice
|
||
Set-DeployCenterUnattendHostNameVisibility -Controls $script:DeploymentControls -ShowHostName ([bool]$showHostName)
|
||
})
|
||
|
||
$script:btnLog.Add_Click({
|
||
if ($script:logForm.IsDisposed) { return }
|
||
if (-not $script:logForm.Visible) { $script:logForm.Show($script:form) }
|
||
$script:logForm.BringToFront()
|
||
})
|
||
|
||
$script:btnRefresh.Add_Click({
|
||
Update-HardwareView
|
||
})
|
||
|
||
$script:btnDeploy.Add_Click({
|
||
$diskIndex = $null
|
||
if ($null -ne $script:cmbDisk.SelectedItem) { $diskIndex = [int]$script:cmbDisk.SelectedItem.Tag }
|
||
$diskInfo = if ($null -ne $diskIndex) { Get-SelectedDeployDiskInfo -HardwareInfo $script:HardwareInventory -DiskIndex $diskIndex } else { $null }
|
||
$unattendChoice = [string]$script:cmbUnattendProfile.SelectedItem
|
||
$unattendProfile = $null
|
||
$hostName = $null
|
||
if ($unattendChoice -and $unattendChoice -ne $script:UnattendOobeChoice) {
|
||
$matchingProfiles = @($script:UnattendProfiles | Where-Object { [string]$_.Name -eq $unattendChoice })
|
||
if ($matchingProfiles.Count -ne 1) {
|
||
Show-DeployCenterMessage -Message "Le profil Unattend '$unattendChoice' est introuvable ou ambigu." -Title 'Profil Unattend' -Icon Error -Owner $script:form -Theme $script:Theme -Font $script:FontRegular
|
||
return
|
||
}
|
||
$unattendProfile = $matchingProfiles[0]
|
||
$hostName = [string]$script:txtHostName.Text.Trim()
|
||
}
|
||
|
||
if ($null -eq $diskInfo) {
|
||
Show-DeployCenterMessage -Message 'Sélectionne le disque de destination.' -Title 'Déploiement Windows' -Icon Warning -Owner $script:form -Theme $script:Theme -Font $script:FontRegular
|
||
return
|
||
}
|
||
if ($null -eq $script:SelectedWindowsEdition) {
|
||
Show-DeployCenterMessage -Message 'Sélectionne une édition Windows à installer.' -Title 'Déploiement Windows' -Icon Warning -Owner $script:form -Theme $script:Theme -Font $script:FontRegular
|
||
return
|
||
}
|
||
if ($null -ne $unattendProfile -and $unattendProfile.ComputerName -and $hostName -notmatch '^(?=.*[A-Za-z])[A-Za-z0-9](?:[A-Za-z0-9-]{0,13}[A-Za-z0-9])?$') {
|
||
Show-DeployCenterMessage -Message "Le nom d’hôte doit contenir de 1 à 15 caractères, commencer et finir par une lettre ou un chiffre, et ne contenir que des lettres, chiffres ou tirets." -Title "Nom d’hôte invalide" -Icon Warning -Owner $script:form -Theme $script:Theme -Font $script:FontRegular
|
||
return
|
||
}
|
||
if ($null -ne $unattendProfile) {
|
||
try {
|
||
Test-DeployCenterUnattendConfiguration -Profile $unattendProfile `
|
||
-Configuration $script:Config -HostName $hostName
|
||
} catch {
|
||
Show-DeployCenterMessage -Message $_.Exception.Message -Title 'Configuration Unattend invalide' -Icon Warning -Owner $script:form -Theme $script:Theme -Font $script:FontRegular
|
||
return
|
||
}
|
||
}
|
||
if ($script:SelectedPartitionSizing -and [int]$script:SelectedPartitionSizing.DiskIndex -ne [int]$diskInfo.Index) {
|
||
Show-DeployCenterMessage -Message 'La taille des partitions correspond à un autre disque. Sélectionne de nouveau le profil de partitionnement.' -Title 'Partitionnement' -Icon Warning -Owner $script:form -Theme $script:Theme -Font $script:FontRegular
|
||
return
|
||
}
|
||
|
||
$sizeDescription = 'Tailles définies par le profil'
|
||
if ($script:SelectedPartitionSizing -and $script:SelectedPartitionSizing.Inputs.Count -gt 0) {
|
||
$sizeParts = @()
|
||
foreach ($role in $script:SelectedPartitionSizing.Inputs.Keys) {
|
||
$sizeParts += ("{0} : {1} Go" -f $role, $script:SelectedPartitionSizing.Inputs[$role])
|
||
}
|
||
$sizeParts += ("espace restant : {0:N1} Go" -f $script:SelectedPartitionSizing.RemainderGB)
|
||
$sizeDescription = $sizeParts -join ', '
|
||
}
|
||
$unattendDescription = if ($null -ne $unattendProfile) { "Profil Unattend : $($unattendProfile.Name)`r`nNom d’hôte : $hostName" } else { 'Configuration initiale : Avec OOBE' }
|
||
$confirmation = Show-DeployCenterConfirmation `
|
||
-Title "Confirmer l’effacement du disque" `
|
||
-Message ("Disque {0} — {1} ({2:N1} Go)`r`nProfil de partitionnement : {3}`r`nÉdition : {4}`r`nTailles : {5}`r`n{6}`r`nTout le contenu du disque sera effacé. Cette opération est irréversible." -f $diskInfo.Index, $diskInfo.Model, $diskInfo.SizeGB, $script:SelectedPartitionProfile.Name, $script:SelectedWindowsEdition.Name, $sizeDescription, $unattendDescription) `
|
||
-Owner $script:form -Theme $script:Theme -Font $script:FontRegular
|
||
if (-not $confirmation) { return }
|
||
|
||
$progress = New-DeployCenterDeploymentProgress -Theme $script:Theme -Font $script:FontRegular
|
||
$script:form.Enabled = $false
|
||
try {
|
||
$progress.Form.Show($script:form)
|
||
[System.Windows.Forms.Application]::DoEvents()
|
||
$deploymentLogAction = $script:SourceLogAction
|
||
$deploymentProgressMessage = 'Préparation du déploiement…'
|
||
$deploymentProgressAction = {
|
||
param($Message, $Percent)
|
||
if ($null -ne $Message) {
|
||
$deploymentProgressMessage = [string]$Message
|
||
if ($null -eq $Percent) {
|
||
$progress.ProgressBar.Style = [System.Windows.Forms.ProgressBarStyle]::Marquee
|
||
}
|
||
if ($deploymentLogAction -is [scriptblock]) {
|
||
& $deploymentLogAction ([string]$Message) 'INFO'
|
||
}
|
||
}
|
||
if ($null -ne $Percent) {
|
||
if ($progress.ProgressBar.Style -ne [System.Windows.Forms.ProgressBarStyle]::Continuous) {
|
||
$progress.ProgressBar.Style = [System.Windows.Forms.ProgressBarStyle]::Continuous
|
||
}
|
||
$progress.ProgressBar.Value = [int][Math]::Max(0, [Math]::Min(100, $Percent))
|
||
$progress.StatusLabel.Text = '{0} ({1} %)' -f $deploymentProgressMessage, $progress.ProgressBar.Value
|
||
} elseif ($null -ne $Message) {
|
||
$progress.StatusLabel.Text = $deploymentProgressMessage
|
||
}
|
||
[System.Windows.Forms.Application]::DoEvents()
|
||
}.GetNewClosure()
|
||
|
||
$deploymentResult = Invoke-DeployCenterWindowsDeployment `
|
||
-DiskInfo $diskInfo `
|
||
-Profile $script:SelectedPartitionProfile `
|
||
-SizingState $script:SelectedPartitionSizing `
|
||
-Edition $script:SelectedWindowsEdition `
|
||
-HostName $hostName `
|
||
-UnattendProfile $unattendProfile `
|
||
-UnattendConfiguration $script:Config `
|
||
-Firmware $script:HardwareInventory.Firmware `
|
||
-TemporaryRoot $script:InventoryDir `
|
||
-LogAction $script:SourceLogAction `
|
||
-ProgressAction $deploymentProgressAction
|
||
|
||
$progress.Form.Close()
|
||
$script:form.Enabled = $true
|
||
$completionMessage = 'Windows a été appliqué avec succès. Le déploiement est prêt.'
|
||
$restartByDefault = $true
|
||
if ($deploymentResult -and @($deploymentResult.WinRERecommendationWarnings).Count -gt 0) {
|
||
$winreWarnings = @($deploymentResult.WinRERecommendationWarnings) -join '; '
|
||
$completionMessage += "`r`n`r`nRappel WinRE : les recommandations Microsoft ne sont pas toutes respectées : $winreWarnings."
|
||
$restartByDefault = $false
|
||
}
|
||
$restartAfterDeployment = Show-DeployCenterDeploymentComplete `
|
||
-Message $completionMessage `
|
||
-RestartByDefault $restartByDefault `
|
||
-Owner $script:form -Theme $script:Theme -Font $script:FontRegular
|
||
if ($restartAfterDeployment) {
|
||
$script:RestartAfterDeployment = $true
|
||
$script:form.Close()
|
||
}
|
||
} catch {
|
||
if (-not $progress.Form.IsDisposed) { $progress.Form.Close() }
|
||
$script:form.Enabled = $true
|
||
& $script:SourceLogAction "Échec du déploiement : $($_.Exception.Message)" 'ERROR'
|
||
Show-DeployCenterMessage -Message $_.Exception.Message -Title 'Échec du déploiement' -Icon Error -Owner $script:form -Theme $script:Theme -Font $script:FontRegular
|
||
} finally {
|
||
if (-not $progress.Form.IsDisposed) { $progress.Form.Dispose() }
|
||
$script:form.Enabled = $true
|
||
if (-not $script:form.IsDisposed -and $script:form.Visible) { $script:form.Activate() }
|
||
}
|
||
})
|
||
|
||
$script:btnClose.Add_Click({
|
||
$script:form.Close()
|
||
})
|
||
|
||
$script:cmbTheme.Add_SelectedIndexChanged({
|
||
if ($script:cmbTheme.SelectedItem) {
|
||
Set-DeployCenterTheme -ThemeName ([string]$script:cmbTheme.SelectedItem)
|
||
}
|
||
})
|
||
|
||
$script:cmbDisk.Add_SizeChanged({
|
||
Set-DiskSelectorWidth
|
||
})
|
||
|
||
$script:cmbPartitionProfile.Add_SelectedIndexChanged({
|
||
if ($script:ChangingPartitionProfileSelection) { return }
|
||
$selectedIndex = $script:cmbPartitionProfile.SelectedIndex
|
||
if ($selectedIndex -ge 0 -and $selectedIndex -lt $script:PartitionProfiles.Count) {
|
||
$candidateProfile = $script:PartitionProfiles[$selectedIndex]
|
||
$sizeInputs = @($candidateProfile.Partitions | Where-Object { $_.Size.Policy -eq 'UserInputGB' })
|
||
if ($sizeInputs.Count -gt 0) {
|
||
$selectedDiskTag = if ($null -ne $script:cmbDisk.SelectedItem) { [int]$script:cmbDisk.SelectedItem.Tag } else { $null }
|
||
$diskInfo = if ($null -ne $selectedDiskTag) { Get-SelectedDeployDiskInfo -HardwareInfo $script:HardwareInventory -DiskIndex $selectedDiskTag } else { $null }
|
||
$initialValues = @{}
|
||
if ($script:SelectedPartitionSizing -and $script:SelectedPartitionSizing.ProfileId -eq $candidateProfile.Id) {
|
||
$initialValues = $script:SelectedPartitionSizing.Inputs
|
||
}
|
||
if ($null -eq $diskInfo) {
|
||
Show-DeployCenterMessage -Message "Sélectionne d’abord un disque physique." -Title 'Partitionnement' -Icon Information -Owner $script:form -Theme $script:Theme -Font $script:FontRegular
|
||
}
|
||
if ($null -eq $diskInfo -or -not (Set-PartitionProfileSizingSelection -Profile $candidateProfile -DiskInfo $diskInfo -InitialValues $initialValues)) {
|
||
$script:ChangingPartitionProfileSelection = $true
|
||
try { $script:cmbPartitionProfile.SelectedIndex = $script:SelectedPartitionProfileIndex }
|
||
finally { $script:ChangingPartitionProfileSelection = $false }
|
||
return
|
||
}
|
||
} else {
|
||
$script:SelectedPartitionSizing = $null
|
||
}
|
||
|
||
$script:SelectedPartitionProfileIndex = $selectedIndex
|
||
$script:SelectedPartitionProfile = $candidateProfile
|
||
& $script:SourceLogAction "Profil de partitionnement sélectionné : $($candidateProfile.Name)" 'INFO'
|
||
if ($script:SelectedPartitionSizing) {
|
||
foreach ($role in $script:SelectedPartitionSizing.Inputs.Keys) {
|
||
& $script:SourceLogAction "Taille saisie pour $role : $($script:SelectedPartitionSizing.Inputs[$role]) Go ; espace restant : $($script:SelectedPartitionSizing.RemainderGB) Go" 'INFO'
|
||
}
|
||
}
|
||
}
|
||
})
|
||
|
||
$script:cmbDisk.Add_SelectedIndexChanged({
|
||
if ($script:RefreshingDiskList -or $script:ChangingPartitionProfileSelection) { return }
|
||
$selectedDiskTag = if ($null -ne $script:cmbDisk.SelectedItem) { [int]$script:cmbDisk.SelectedItem.Tag } else { $null }
|
||
$diskInfo = if ($null -ne $selectedDiskTag) { Get-SelectedDeployDiskInfo -HardwareInfo $script:HardwareInventory -DiskIndex $selectedDiskTag } else { $null }
|
||
if ($null -eq $diskInfo) { $script:SelectedDiskIndex = $null; return }
|
||
|
||
$profileSizeInputs = @($script:SelectedPartitionProfile.Partitions | Where-Object { $_.Size.Policy -eq 'UserInputGB' })
|
||
if ($profileSizeInputs.Count -gt 0) {
|
||
$initialValues = if ($script:SelectedPartitionSizing -and $script:SelectedPartitionSizing.ProfileId -eq $script:SelectedPartitionProfile.Id) {
|
||
$script:SelectedPartitionSizing.Inputs
|
||
} else { @{} }
|
||
if (-not (Set-PartitionProfileSizingSelection -Profile $script:SelectedPartitionProfile -DiskInfo $diskInfo -InitialValues $initialValues)) {
|
||
$script:RefreshingDiskList = $true
|
||
try {
|
||
for ($i = 0; $i -lt $script:cmbDisk.Items.Count; $i++) {
|
||
if ([string]$script:cmbDisk.Items[$i].Tag -eq [string]$script:SelectedDiskIndex) { $script:cmbDisk.SelectedIndex = $i; break }
|
||
}
|
||
} finally { $script:RefreshingDiskList = $false }
|
||
return
|
||
}
|
||
}
|
||
$script:SelectedDiskIndex = [string]$diskInfo.Index
|
||
})
|
||
|
||
$script:form.Add_SizeChanged({
|
||
Update-DeployCenterLayout
|
||
})
|
||
|
||
$script:form.Add_KeyDown({
|
||
param($sender, $eventArgs)
|
||
|
||
if ($eventArgs.KeyCode -eq [System.Windows.Forms.Keys]::Escape) {
|
||
$script:form.Close()
|
||
}
|
||
elseif ($eventArgs.KeyCode -eq [System.Windows.Forms.Keys]::F5) {
|
||
Update-HardwareView
|
||
}
|
||
})
|
||
|
||
$script:form.Add_Shown({
|
||
# Use the real maximized client width to position the theme button.
|
||
Update-DeployCenterLayout
|
||
$script:cmbTheme.BringToFront()
|
||
& $script:SourceLogAction "DeployCenter demarre."
|
||
& $script:SourceLogAction "Dossier : $script:DeployRoot"
|
||
& $script:SourceLogAction "Journal : $script:LogFile"
|
||
Update-HardwareView
|
||
})
|
||
|
||
$script:form.Add_FormClosed({
|
||
if ($null -ne $script:pictureLogo -and $null -ne $script:pictureLogo.Image) {
|
||
$script:pictureLogo.Image.Dispose()
|
||
}
|
||
|
||
$script:FontRegular.Dispose()
|
||
$script:FontSmall.Dispose()
|
||
$script:FontTitle.Dispose()
|
||
$script:FontSubtitle.Dispose()
|
||
$script:FontGroup.Dispose()
|
||
})
|
||
|
||
# ============================================================
|
||
# LANCEMENT
|
||
# ============================================================
|
||
|
||
try {
|
||
[void]$script:form.ShowDialog()
|
||
}
|
||
finally {
|
||
if ($script:SelectedWindowsEdition -and $script:SelectedWindowsEdition.MountedImage) {
|
||
try { [void](Dismount-DeployCenterInstallImage -Image $script:SelectedWindowsEdition) } catch {
|
||
& $script:SourceLogAction "Impossible de démonter l'ISO à la fermeture : $($_.Exception.Message)" 'WARNING'
|
||
}
|
||
}
|
||
if ($script:EnableVnc -and (Get-Command Stop-DeployCenterVnc -ErrorAction SilentlyContinue)) {
|
||
Stop-DeployCenterVnc
|
||
}
|
||
$script:form.Dispose()
|
||
if ($script:RestartAfterDeployment) {
|
||
try {
|
||
Restart-DeployCenterWinPE -LogAction $script:SourceLogAction
|
||
} catch {
|
||
& $script:SourceLogAction "Échec de la demande de redémarrage : $($_.Exception.Message)" 'ERROR'
|
||
}
|
||
}
|
||
}
|