Files
benoit 2212e25d31 Ajout de la langue anglaise
Ajout d'un README.md avec le descriptif et les instructions
L'ancien README.md s'appelle désormais CHANGELOG.md
Activation du pavé numérique par défaut pour les installations sans assistance
Nouveau design pour la fenêtre de déploiement.
Ajout de paramètre pour pouvoir procéder à une installation totalement automatisée
Ajout de paramètre pour copier au choix sources, drivers ou les deux sur C:\DeployVenter avant leur usage par DISM.
2026-10-18 04:14:17 +02:00

128 lines
6.5 KiB
PowerShell

# DeployCenter - Load and validate partitioning profiles
# PSD1 profiles are data files; they contain no executable code.
function Get-DeployCenterPartitionProfileNames {
[CmdletBinding()]
param([Parameter(Mandatory=$true)][string]$ProfilesRoot)
if (-not (Test-Path -LiteralPath $ProfilesRoot -PathType Container)) { return @() }
$names = @()
foreach ($file in (Get-ChildItem -LiteralPath $ProfilesRoot -Filter '*.psd1' -File -ErrorAction SilentlyContinue)) {
if ($file.BaseName -match '^[A-Za-z0-9_-]+$') { $names += $file.BaseName }
}
return @($names | Sort-Object -Unique)
}
function Import-DeployCenterPartitionProfile {
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)][string]$ProfilesRoot,
[Parameter(Mandatory=$true)][string]$ProfileName
)
if ($ProfileName -notmatch '^[A-Za-z0-9_-]+$') { throw "Invalid profile name: $ProfileName" }
$path = Join-Path $ProfilesRoot ($ProfileName + '.psd1')
if (-not (Test-Path -LiteralPath $path -PathType Leaf)) { throw "Profile not found: $ProfileName" }
$profile = Import-PowerShellDataFile -LiteralPath $path
foreach ($key in @('Id','Name','Description','Firmware','PartitionStyle','Partitions')) {
if (-not $profile.ContainsKey($key)) { throw "The profile '$ProfileName' does not contain key '$key'." }
}
if ([string]$profile.Id -ne $ProfileName) { throw "Profile ID '$ProfileName' does not match the file name." }
if (@($profile.Partitions).Count -lt 2) { throw 'The profile must define at least two partitions.' }
if (@($profile.Partitions | Where-Object { [string]$_.Role -eq 'Windows' }).Count -ne 1) {
throw 'The profile must define exactly one Windows partition.'
}
$userInputPartitions = @($profile.Partitions | Where-Object { [string]$_.Size.Policy -eq 'UserInputGB' })
$remainderPartitions = @($profile.Partitions | Where-Object { [string]$_.Size.Policy -eq 'RemainderAfterInputs' })
$remainingPartitions = @($profile.Partitions | Where-Object { [string]$_.Size.Policy -eq 'Remaining' })
if ($userInputPartitions.Count -gt 0) {
if ($remainderPartitions.Count -ne 1 -or $remainingPartitions.Count -gt 0) {
throw "Profile '$ProfileName' must associate user inputs with exactly one remaining-space partition."
}
} elseif ($remainingPartitions.Count -ne 1 -or [string]$profile.Partitions[-1].Size.Policy -ne 'Remaining') {
throw "Profile '$ProfileName' must place exactly one remaining-space partition last."
}
foreach ($partition in $profile.Partitions) {
foreach ($key in @('Name','Role','FileSystem','Size')) {
if (-not $partition.ContainsKey($key)) { throw "A profile partition '$ProfileName' does not contain key '$key'." }
}
if (-not $partition.Size.ContainsKey('Policy')) { throw "The size of a profile partition '$ProfileName' does not define Policy." }
switch ([string]$partition.Size.Policy) {
'FixedMB' {
if ([int]$partition.Size.Value -le 0) { throw "A fixed size in profile '$ProfileName' must be greater than zero." }
}
'ImageSizePlusFreeSpace' {
if ([int]$partition.Size.FreeSpaceMB -lt 250) { throw 'The WinRE free-space allowance must be at least 250 MB.' }
if ([int]$partition.Size.PreviewMB -le 0) { throw "Profile '$ProfileName' must define a PreviewMB reserve to estimate available capacity." }
}
'ConfiguredMB' {
if ([string]::IsNullOrWhiteSpace([string]$partition.Size.ConfigKey) -or
[int]$partition.Size.Value -le 0 -or [int]$partition.Size.PreviewMB -le 0) {
throw "The configured size of partition '$($partition.Name)' in profile '$ProfileName' must define ConfigKey and strictly positive sizes."
}
}
'UserInputGB' {
if ([int]$partition.Size.MinimumGB -le 0 -or [int]$partition.Size.DefaultPercent -le 0 -or [int]$partition.Size.DefaultPercent -ge 100) {
throw 'The user-size input must define MinimumGB and a DefaultPercent from 1 to 99.'
}
if ([string]::IsNullOrWhiteSpace([string]$partition.Size.Label)) { throw "The profile user-size input '$ProfileName' must define Label." }
}
'RemainderAfterInputs' {
if ([double]$partition.Size.MinimumGB -lt 0 -or [string]::IsNullOrWhiteSpace([string]$partition.Size.Label)) {
throw "The remaining-space partition in profile '$ProfileName' must define a non-negative MinimumGB and a Label."
}
}
'Remaining' { }
default { throw "Unknown size policy in profile '$ProfileName': $($partition.Size.Policy)" }
}
}
return $profile
}
function Get-DeployCenterPartitionSizingCapacity {
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)][System.Collections.IDictionary]$Profile,
[Parameter(Mandatory=$true)][long]$DiskSizeBytes
)
$reservedMB = 0.0
foreach ($partition in $Profile.Partitions) {
switch ([string]$partition.Size.Policy) {
{ $_ -in @('FixedMB','ConfiguredMB') } { $reservedMB += [double]$partition.Size.Value }
default {
if ($partition.Size.ContainsKey('PreviewMB')) { $reservedMB += [double]$partition.Size.PreviewMB }
}
}
}
$capacityBytes = $DiskSizeBytes - [long][math]::Ceiling($reservedMB * 1MB)
if ($capacityBytes -le 0) { throw "The disk is too small for the profile reserves '$($Profile.Name)'." }
return [pscustomobject]@{
UsableBytes = [long]$capacityBytes
UsableGB = [math]::Round(($capacityBytes / 1GB), 1)
ReservedMB = [math]::Ceiling($reservedMB)
}
}
function New-DeployCenterPartitionSizingState {
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)][System.Collections.IDictionary]$Profile,
[Parameter(Mandatory=$true)]$DiskInfo,
[Parameter(Mandatory=$true)][System.Collections.IDictionary]$Selection
)
return [pscustomobject]@{
ProfileId = [string]$Profile.Id
DiskIndex = [int]$DiskInfo.Index
Inputs = $Selection.Inputs
RemainderRole = [string]$Selection.RemainderRole
RemainderGB = [double]$Selection.RemainderGB
AvailableGB = [double]$Selection.AvailableGB
}
}
Export-ModuleMember -Function Get-DeployCenterPartitionProfileNames, Import-DeployCenterPartitionProfile, Get-DeployCenterPartitionSizingCapacity, New-DeployCenterPartitionSizingState