Refactor configuration data export and template loading functions

- Updated Export-ConfigurationData to use resolved configuration data directly and added error handling for missing data.
- Enhanced Load-Templates to streamline category loading and improve error handling for missing template directories.
- Removed Merge-ConfigurationData function as it is no longer needed.
- Refactored Merge-Templates to improve merging logic and handle default files more effectively.
- Introduced Get-TemplatePreviewData function to handle template preview data retrieval and merging.
- Added Import-OrderedPowerShellDataFile function to support ordered hashtable imports.
- Updated Update-ParametersPanel to handle parameter and variable tab updates more efficiently.
- Improved Update-TreeView to handle cases where resources are not found.
- Added new parameters to Environment.Default.psd1 for Active Directory configuration.
- Created new template BGW-LAN.psd1 for domain configuration.
This commit is contained in:
Torsten Brendgen
2026-06-29 22:16:05 +02:00
parent 6986570510
commit 1a4ba96dc8
13 changed files with 689 additions and 4456 deletions

View File

@@ -2924,99 +2924,6 @@
return $ordered
}
# Concat mit einer dynamischen Anzahl von Argumenten
static [string] Concat([string[]]$input) {
return $input -join ''
}
# ToLower-Methode
static [string] ToLower([string[]]$input) {
return $input[0].ToLower()
}
# ToUpper-Methode
static [string] ToUpper([string[]]$input) {
return $input[0].ToUpper()
}
# FirstIndexOf-Methode
static [string] FirstIndexOf([string[]] $input){
return $input[0]
}
# LastIndexOf-Methode
static [string] LastIndexOf([string[]] $input){
return $input[-1]
}
# IndexOf-Methode
static [string] IndexOf([string[]] $input){
return $input[$input[-1]]
}
# Substring-Methode
static [String] Substring([string[]] $input){
if($input.Count -eq 2){
$array = $input.Split(',')
return $array[0].Substring($array[1])
}elseif($input.Count -eq 3){
$array = $input.Split(',')
return $array[0].Substring($array[1],$array[2])
}else{
Write-Warning "Zuviele Parameter"
return $false
}
}
# Replace-Methode
static [String] Replace([string[]] $input){
$array = $input.Split(',')
return $array[0].Replace($array[1],$array[2])
}
hidden [System.Collections.Specialized.OrderedDictionary] ResolveDeploymentParameterDefaultValues(){
$TemplateClone = $this.Template
if($TemplateClone.Contains("Parameters")){
foreach($Parameter in $this.Template.Parameters.GetEnumerator()){
if(!$Parameter.Value.Contains("Value")){
$TemplateClone.Parameters[$Parameter.Name].Value = $this.Template.Parameters[$Parameter.Name].DefaultValue
}
}
}
return $TemplateClone
}
[System.Collections.Specialized.OrderedDictionary] ResolveDeploymentDataVariables(){
$TemplateClone = $this.ResolveDeploymentParameterDefaultValues()
# Erst Variables auflösen (können Parameter-Referenzen enthalten)
if ($TemplateClone.Variables) {
$resolvedVariables = New-Object System.Collections.Specialized.OrderedDictionary
# WICHTIG: Keys-Array erstellen, um Collection-Modification zu vermeiden
$varKeys = @($TemplateClone.Variables.Keys)
foreach ($varKey in $varKeys) {
$resolvedVariables[$varKey] = $this.ResolveValue($TemplateClone.Variables[$varKey],$TemplateClone.Parameters,$TemplateClone.Variables)
}
$TemplateClone.Variables = $resolvedVariables
}
# Dann den Rest des Templates auflösen
# WICHTIG: Keys-Array erstellen, um Collection-Modification zu vermeiden
$templateKeys = @($TemplateClone.Keys)
foreach ($key in $templateKeys) {
if ($key -ne 'Variables' -and $key -ne 'Parameters') {
$TemplateClone[$key] = $this.ResolveValue($TemplateClone[$key],$TemplateClone.Parameters,$TemplateClone.Variables)
}
}
return $TemplateClone
}
hidden [System.Collections.Specialized.OrderedDictionary] ConvertFromPowerShellDataString($TemplatePath){
$errors = $null
$tokens = $null
@@ -3096,127 +3003,6 @@
return $ordered
}
hidden [System.Object] ResolveValue($Value, $Parameters, $Variables){
if ($Value -is [string]) {
# Resolve Parameter-Referenzen: [Parameter('name')]
while ($Value -match "\[Parameter\('([^']*)'\)\]") {
$paramName = $matches[1]
if ($Parameters.Contains($paramName)) {
# Prüfe erst auf Value, dann auf DefaultValue
$paramValue = $Parameters[$paramName].Value
if ($null -ne $paramValue) {
$Value = $Value -replace "\[Parameter\('$([regex]::Escape($paramName))'\)\]", $paramValue
}
else {
break
}
}
else {
Write-Warning "Parameter '$paramName' nicht gefunden"
break
}
}
# Resolve Variable-Referenzen: [Variable('name')]
while ($Value -match "\[Variable\('([^']*)'\)\]") {
$varName = $matches[1]
if ($Variables.Contains($varName)) {
$varValue = $this.ResolveValue($Variables[$varName],$Parameters,$Variables)
$Value = $Value -replace "\[Variable\('$([regex]::Escape($varName))'\)\]", $varValue
}
else {
Write-Warning "Variable '$varName' nicht gefunden"
break
}
}
while ($Value -match "Parameter\('([^']*)'\)") {
$paramName = $matches[1]
if ($Parameters.Contains($paramName)) {
# Prüfe erst auf Value, dann auf DefaultValue
$paramValue = if ($Parameters[$paramName].Value) {
$Parameters[$paramName].Value
}
elseif ($Parameters[$paramName].DefaultValue) {
$Parameters[$paramName].DefaultValue
}
else {
Write-Warning "Parameter '$paramName' hat weder Value noch DefaultValue"
$null
}
if ($null -ne $paramValue) {
$Value = $Value -replace "Parameter\('$([regex]::Escape($paramName))'\)", $("'"+$paramValue+"'")
}
else {
break
}
}
else {
Write-Warning "Parameter '$paramName' nicht gefunden"
break
}
}
#Resolve Variable-Referenzen: Variable('name')
while ($Value -match "Variable\('([^']*)'\)"){
$varName = $matches[1]
if ($Variables.Contains($varName)) {
$varValue = $this.ResolveValue($Variables[$varName],$Parameters,$Variables)
$Value = $Value -replace "Variable\('$([regex]::Escape($varName))'\)", $("'"+$varValue+"'")
}
else {
Write-Warning "Variable '$varName' nicht gefunden"
break
}
}
# Resolve SSPUtility-Funktionen
foreach($Function in $([TemplateBuilder].GetMethods('Static, Public')).Name | Get-Unique) {
$pattern = "\["+$Function+"\((.*?)\)\]"
while ($Value -match $pattern) {
try {
$fullMatch = $matches[0]
$argsString = $matches[1]
# Parse die Argumente korrekt - sie sind bereits als PowerShell-Array formatiert
# Wir müssen sie nur evaluieren
$scriptBlock = [scriptblock]::Create("@($argsString)")
$argsArray = & $scriptBlock
# Rufe die Methode direkt auf statt Invoke-Expression
$result = [TemplateBuilder]::$Function($argsArray)
$Value = $Value.Replace($fullMatch, $result)
}
catch {
Write-Warning "Fehler beim Ausführen von $matches[0] : $_"
break
}
}
}
return $Value
}
elseif ($Value -is [System.Collections.IDictionary]) {
$resolved = New-Object System.Collections.Specialized.OrderedDictionary
foreach ($key in $Value.Keys) {
$resolved[$key] = $this.ResolveValue($Value[$key],$Parameters,$Variables)
}
return $resolved
}
elseif ($Value -is [array]) {
$resolved = @()
foreach ($item in $Value) {
$resolved += $this.ResolveValue($item,$Parameters,$Variables)
}
return $resolved
}
else {
return $Value
}
}
}
class TabControlBuilder : BaseComponent{
@@ -3335,6 +3121,23 @@
[BaseComponent]::InitializeShared($settingsManager, $logManager)
$script:MergedConfigurationData = $null
$script:ResolvedConfigurationData = $null
$powerShellRoot = Split-Path -Path $PSScriptRoot -Parent
$mergeModulePath = Join-Path -Path $powerShellRoot -ChildPath "Merge-DSCConfigurationData\Merge-DSCConfigurationData.psd1"
$resolveModulePath = Join-Path -Path $powerShellRoot -ChildPath "Resolve-DSCConfigurationData\Resolve-DSCConfigurationData.psd1"
foreach($modulePath in @($mergeModulePath, $resolveModulePath)){
try{
Import-Module $modulePath -Force -ErrorAction Stop
$logManager.Info("Modul geladen: $modulePath")
}catch{
$logManager.Error("Fehler beim Laden des Moduls '$modulePath': $_")
throw
}
}
foreach($function in $(Get-ChildItem -Path $settingsManager.Get("FunctionsPath") -Recurse -Filter "*.ps1" -File)){
$logManager.Info("Lade Funktion: $($function.FullName)")
try{