Ajout du support de unattend
Ajout du script cmd à utiliser pour lancer DeployCenter
This commit is contained in:
1 parent
2019c565f5
commit
e067721763
12 files changed
+663
-166
No files matched your search
@@ -0,0 +1,120 @@
|
||||
# DeployCenter - Découverte et génération des profils de réponses Windows.
|
||||
# Les profils PSD1 restent des fichiers de données ; les réponses sont construites comme XML.
|
||||
|
||||
function Get-DeployCenterUnattendProfileNames {
|
||||
[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-DeployCenterUnattendProfile {
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][string]$ProfilesRoot,
|
||||
[Parameter(Mandatory=$true)][string]$ProfileName
|
||||
)
|
||||
|
||||
if ($ProfileName -notmatch '^[A-Za-z0-9_-]+$') { throw "Nom de profil Unattend invalide : $ProfileName" }
|
||||
$path = Join-Path $ProfilesRoot ($ProfileName + '.psd1')
|
||||
if (-not (Test-Path -LiteralPath $path -PathType Leaf)) { throw "Profil Unattend introuvable : $ProfileName" }
|
||||
$profile = Import-PowerShellDataFile -LiteralPath $path
|
||||
foreach ($key in @('Id','Name','Description','Target','Template','ComputerName','LocalAccount')) {
|
||||
if (-not $profile.ContainsKey($key)) { throw ('Le profil Unattend {0} ne contient pas la cle {1}.' -f $ProfileName, $key) }
|
||||
}
|
||||
if ([string]$profile.Id -ne $ProfileName) { throw ('L identifiant du profil Unattend {0} ne correspond pas au nom du fichier.' -f $ProfileName) }
|
||||
if ([string]$profile.Target -notin @('Workstation', 'Server')) { throw ('La propriete Target du profil Unattend {0} doit etre Workstation ou Server.' -f $ProfileName) }
|
||||
if ([string]$profile.Template -notmatch '^[A-Za-z0-9_-]+\.xml$') { throw ('Nom de template XML invalide dans le profil {0}.' -f $ProfileName) }
|
||||
$templatesRoot = Join-Path (Split-Path -Parent $ProfilesRoot) 'Templates'
|
||||
$templatePath = Join-Path $templatesRoot ([string]$profile.Template)
|
||||
if (-not (Test-Path -LiteralPath $templatePath -PathType Leaf)) { throw "Template XML introuvable pour le profil '$ProfileName' : $templatePath" }
|
||||
if (-not [string]$profile.Name -or [string]::IsNullOrWhiteSpace([string]$profile.Name)) { throw ('Le profil Unattend {0} doit definir un nom affichable.' -f $ProfileName) }
|
||||
$profile.TemplatePath = $templatePath
|
||||
return $profile
|
||||
}
|
||||
|
||||
function Test-DeployCenterUnattendConfiguration {
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][System.Collections.IDictionary]$Profile,
|
||||
[Parameter(Mandatory=$true)][System.Collections.IDictionary]$Configuration,
|
||||
[Parameter(Mandatory=$true)][string]$HostName
|
||||
)
|
||||
|
||||
if ($Profile.ComputerName -and $HostName -notmatch '^(?=.*[A-Za-z])[A-Za-z0-9](?:[A-Za-z0-9-]{0,13}[A-Za-z0-9])?$') {
|
||||
throw 'Le nom de machine doit respecter les règles NetBIOS et ne pas dépasser 15 caractères.'
|
||||
}
|
||||
if ($Profile.LocalAccount) {
|
||||
$accountName = [string]$Configuration.UnattendAdminName
|
||||
$displayName = [string]$Configuration.UnattendAdminDisplayName
|
||||
$groupName = [string]$Configuration.UnattendAdminGroup
|
||||
$passwordBase64 = [string]$Configuration.UnattendAdminPasswordBase64
|
||||
if ($accountName -notmatch '^[^"/\[\]:;|=,+*?<>\\]{1,20}$') { throw 'Le paramètre [Unattend] AdminName doit contenir de 1 à 20 caractères et éviter les caractères interdits par Windows.' }
|
||||
if ([string]::IsNullOrWhiteSpace($displayName)) { throw 'Le paramètre [Unattend] AdminDisplayName ne peut pas être vide.' }
|
||||
if ([string]::IsNullOrWhiteSpace($groupName)) { throw 'Le paramètre [Unattend] AdminGroup ne peut pas être vide.' }
|
||||
if ([string]::IsNullOrWhiteSpace($passwordBase64)) { throw 'Le paramètre [Unattend] AdminPasswordBase64 est requis pour ce profil.' }
|
||||
try {
|
||||
$passwordBytes = [Convert]::FromBase64String($passwordBase64)
|
||||
if ($passwordBytes.Length -eq 0 -or ($passwordBytes.Length % 2) -ne 0 -or
|
||||
[string]::IsNullOrEmpty([Text.Encoding]::Unicode.GetString($passwordBytes))) {
|
||||
throw 'Format UTF-16LE Base64 invalide.'
|
||||
}
|
||||
} catch {
|
||||
throw 'Le paramètre [Unattend] AdminPasswordBase64 doit être un mot de passe UTF-16LE encodé en Base64.'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function New-DeployCenterUnattendXml {
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][System.Collections.IDictionary]$Profile,
|
||||
[Parameter(Mandatory=$true)][System.Collections.IDictionary]$Configuration,
|
||||
[Parameter(Mandatory=$true)][string]$HostName,
|
||||
[Parameter(Mandatory=$true)][string]$Architecture
|
||||
)
|
||||
|
||||
Test-DeployCenterUnattendConfiguration -Profile $Profile -Configuration $Configuration -HostName $HostName
|
||||
$document = New-Object System.Xml.XmlDocument
|
||||
$document.PreserveWhitespace = $true
|
||||
$document.Load([string]$Profile.TemplatePath)
|
||||
$namespaces = New-Object System.Xml.XmlNamespaceManager($document.NameTable)
|
||||
$namespaces.AddNamespace('u', 'urn:schemas-microsoft-com:unattend')
|
||||
$namespaces.AddNamespace('wcm', 'http://schemas.microsoft.com/WMIConfig/2002/State')
|
||||
|
||||
$processorArchitecture = switch -Regex ($Architecture.ToLowerInvariant()) {
|
||||
'arm64' { 'arm64'; break }
|
||||
'x86|32' { 'x86'; break }
|
||||
default { 'amd64' }
|
||||
}
|
||||
foreach ($component in $document.SelectNodes('//u:component', $namespaces)) {
|
||||
$component.SetAttribute('processorArchitecture', $processorArchitecture)
|
||||
}
|
||||
if ($Profile.ComputerName) {
|
||||
$node = $document.SelectSingleNode('/u:unattend/u:settings[@pass="specialize"]/u:component[@name="Microsoft-Windows-Shell-Setup"]/u:ComputerName', $namespaces)
|
||||
if ($null -eq $node) { throw ('Le template du profil {0} ne definit pas le noeud ComputerName dans specialize.' -f $Profile.Id) }
|
||||
$node.InnerText = $HostName
|
||||
}
|
||||
if ($Profile.LocalAccount) {
|
||||
$values = @{
|
||||
Name = [string]$Configuration.UnattendAdminName
|
||||
DisplayName = [string]$Configuration.UnattendAdminDisplayName
|
||||
Group = [string]$Configuration.UnattendAdminGroup
|
||||
Password = [string]$Configuration.UnattendAdminPasswordBase64
|
||||
}
|
||||
foreach ($name in $values.Keys) {
|
||||
$field = if ($name -eq 'Password') { 'Password/u:Value' } else { $name }
|
||||
$node = $document.SelectSingleNode("/u:unattend/u:settings[@pass='oobeSystem']/u:component[@name='Microsoft-Windows-Shell-Setup']/u:UserAccounts/u:LocalAccounts/u:LocalAccount/u:$field", $namespaces)
|
||||
if ($null -eq $node) { throw ('Le template du profil {0} ne definit pas le champ de compte {1}.' -f $Profile.Id, $name) }
|
||||
$node.InnerText = $values[$name]
|
||||
}
|
||||
}
|
||||
return $document.OuterXml
|
||||
}
|
||||
|
||||
Export-ModuleMember -Function Get-DeployCenterUnattendProfileNames, Import-DeployCenterUnattendProfile, Test-DeployCenterUnattendConfiguration, New-DeployCenterUnattendXml
|
||||
Reference in new issue
Block a user