Initial commit
This commit is contained in:
182
Functions/ConvertFrom-TreeView.ps1
Normal file
182
Functions/ConvertFrom-TreeView.ps1
Normal file
@@ -0,0 +1,182 @@
|
||||
function ConvertFrom-TreeView {
|
||||
[CmdletBinding()]
|
||||
Param(
|
||||
[Parameter(Mandatory = $true, ValueFromPipeline = $true)]
|
||||
[System.Windows.Forms.TreeView]
|
||||
$TreeView,
|
||||
|
||||
[Parameter(Mandatory = $false)]
|
||||
[switch]
|
||||
$SkipRootNode,
|
||||
|
||||
[Parameter(Mandatory = $false)]
|
||||
[switch]
|
||||
$PreserveTypes,
|
||||
|
||||
[Parameter(Mandatory = $false)]
|
||||
[switch]
|
||||
$IncludeMetadata
|
||||
)
|
||||
|
||||
function ConvertTreeNodeToHashtable {
|
||||
param(
|
||||
[System.Windows.Forms.TreeNode]$node,
|
||||
[string]$path = ""
|
||||
)
|
||||
|
||||
$currentPath = if ($path -eq "") { $node.Name } else { "$path.$($node.Name)" }
|
||||
|
||||
# Verwende Tag-Informationen wenn verfügbar
|
||||
if ($null -ne $node.Tag -and $node.Tag -is [hashtable]) {
|
||||
$nodeType = $node.Tag.Type
|
||||
|
||||
switch ($nodeType) {
|
||||
"Hashtable" {
|
||||
$result = @{}
|
||||
|
||||
if ($IncludeMetadata) {
|
||||
$result["__metadata"] = @{
|
||||
Type = "Hashtable"
|
||||
Path = $currentPath
|
||||
NodeCount = $node.Nodes.Count
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($childNode in $node.Nodes) {
|
||||
$key = if ([string]::IsNullOrEmpty($childNode.Name)) {
|
||||
$childNode.Text
|
||||
}
|
||||
else {
|
||||
$childNode.Name
|
||||
}
|
||||
$result[$key] = ConvertTreeNodeToHashtable $childNode $currentPath
|
||||
}
|
||||
return , $result
|
||||
}
|
||||
"Array" {
|
||||
$result = @()
|
||||
if ($node.Nodes.Count -gt 0) {
|
||||
foreach ($childNode in $node.Nodes) {
|
||||
$result += ConvertTreeNodeToHashtable $childNode $currentPath
|
||||
}
|
||||
}
|
||||
return , $result
|
||||
}
|
||||
"Value" {
|
||||
$value = $node.Tag.Value
|
||||
|
||||
if ($PreserveTypes) {
|
||||
return $value
|
||||
}
|
||||
else {
|
||||
# Konvertiere zu String wenn kein Type-Preservation
|
||||
return $value.ToString()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Fallback: Rekonstruktion ohne Tag-Informationen
|
||||
if ($node.Nodes.Count -gt 0) {
|
||||
# Array-Erkennung
|
||||
$isArray = $true
|
||||
$expectedIndex = 0
|
||||
foreach ($childNode in $node.Nodes) {
|
||||
if ($childNode.Name -ne "[$expectedIndex]") {
|
||||
$isArray = $false
|
||||
break
|
||||
}
|
||||
$expectedIndex++
|
||||
}
|
||||
|
||||
if ($isArray) {
|
||||
$result = @()
|
||||
foreach ($childNode in $node.Nodes) {
|
||||
$result += ConvertTreeNodeToHashtable $childNode $currentPath
|
||||
}
|
||||
return $result
|
||||
}
|
||||
else {
|
||||
$result = @{}
|
||||
foreach ($childNode in $node.Nodes) {
|
||||
$key = $childNode.Name
|
||||
if ([string]::IsNullOrEmpty($key)) {
|
||||
if ($childNode.Text -match '^(.+?)\s*=\s*(.*)$') {
|
||||
$key = $matches[1].Trim()
|
||||
}
|
||||
else {
|
||||
$key = $childNode.Text
|
||||
}
|
||||
}
|
||||
$result[$key] = ConvertTreeNodeToHashtable $childNode $currentPath
|
||||
}
|
||||
return $result
|
||||
}
|
||||
}
|
||||
else {
|
||||
# Leaf-Node
|
||||
if ($node.Text -match '^.+?\s*=\s*(.*)$') {
|
||||
$value = $matches[1].Trim()
|
||||
|
||||
if ($PreserveTypes) {
|
||||
# Typ-Konvertierung
|
||||
if ($value -eq '$true' -or $value -eq 'True') {
|
||||
return $true
|
||||
}
|
||||
elseif ($value -eq '$false' -or $value -eq 'False') {
|
||||
return $false
|
||||
}
|
||||
elseif ($value -match '^\d+$') {
|
||||
return [int]$value
|
||||
}
|
||||
elseif ($value -match '^\d+\.\d+$') {
|
||||
return [double]$value
|
||||
}
|
||||
elseif ($value -eq '$null' -or $value -eq 'null') {
|
||||
return $null
|
||||
}
|
||||
else {
|
||||
return $value
|
||||
}
|
||||
}
|
||||
else {
|
||||
return $value
|
||||
}
|
||||
}
|
||||
else {
|
||||
return $node.Text
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($TreeView.Nodes.Count -eq 0) {
|
||||
Write-Warning "TreeView enthält keine Nodes"
|
||||
return $null
|
||||
}
|
||||
|
||||
if ($SkipRootNode) {
|
||||
$rootNode = $TreeView.Nodes[0]
|
||||
if ($rootNode.Nodes.Count -eq 0) {
|
||||
Write-Warning "Root-Node hat keine Child-Nodes"
|
||||
return @{}
|
||||
}
|
||||
|
||||
$result = @{}
|
||||
foreach ($childNode in $rootNode.Nodes) {
|
||||
$key = $childNode.Name
|
||||
if ([string]::IsNullOrEmpty($key)) {
|
||||
if ($childNode.Text -match '^(.+?)\s*=\s*(.*)$') {
|
||||
$key = $matches[1].Trim()
|
||||
}
|
||||
else {
|
||||
$key = $childNode.Text
|
||||
}
|
||||
}
|
||||
$result[$key] = ConvertTreeNodeToHashtable $childNode
|
||||
}
|
||||
return $result
|
||||
}
|
||||
else {
|
||||
return ConvertTreeNodeToHashtable $TreeView.Nodes[0]
|
||||
}
|
||||
}
|
||||
24
Functions/Export-ConfigurationData.ps1
Normal file
24
Functions/Export-ConfigurationData.ps1
Normal file
@@ -0,0 +1,24 @@
|
||||
function Export-ConfigurationData {
|
||||
$result = (
|
||||
[DialogBuilder]::SaveFile().
|
||||
SetTitle("Konfiguration speichern").
|
||||
SetCommonFilter("PSD1").
|
||||
SetInitialDirectory($settingsManager.Get("DeploymentPath")).
|
||||
SetFileName("merged_config.psd1").
|
||||
SetOverwritePrompt($true).
|
||||
Show()
|
||||
)
|
||||
if ($result.Result) {
|
||||
try {
|
||||
$ConfigurationData = @{
|
||||
"Resources" = $(ConvertFrom-TreeView -TreeView $treeView -SkipRootNode)
|
||||
}
|
||||
|
||||
Export-Hashtable -Hashtable $ConfigurationData -Path $result.FileName
|
||||
[System.Windows.Forms.MessageBox]::Show("Export war erfolgreich", "Info", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Information)
|
||||
}
|
||||
catch {
|
||||
[System.Windows.Forms.MessageBox]::Show("Export war nicht erfolgreich", "Info", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Error)
|
||||
}
|
||||
}
|
||||
}
|
||||
152
Functions/Export-Hashtable.ps1
Normal file
152
Functions/Export-Hashtable.ps1
Normal file
@@ -0,0 +1,152 @@
|
||||
function Export-Hashtable {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Exportiert einen PowerShell Hashtable als valide PSD1-Datei.
|
||||
|
||||
.DESCRIPTION
|
||||
Diese Funktion konvertiert einen PowerShell Hashtable in eine gültige PSD1-Datei
|
||||
mit korrekter Formatierung und Einrückung.
|
||||
|
||||
.PARAMETER Hashtable
|
||||
Der zu exportierende Hashtable
|
||||
|
||||
.PARAMETER Path
|
||||
Der Pfad zur Ziel-PSD1-Datei
|
||||
|
||||
.PARAMETER Indent
|
||||
Die Anzahl der Leerzeichen für die Einrückung (Standard: 4)
|
||||
|
||||
.EXAMPLE
|
||||
$data = @{
|
||||
ModuleName = "MeinModul"
|
||||
Version = "1.0.0"
|
||||
Author = "Max Mustermann"
|
||||
Settings = @{
|
||||
Debug = $true
|
||||
MaxRetries = 3
|
||||
}
|
||||
}
|
||||
Export-Hashtable -Hashtable $data -Path "C:\config.psd1"
|
||||
#>
|
||||
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[System.Collections.Hashtable]$Hashtable,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[System.String]$Path,
|
||||
|
||||
[Parameter(Mandatory = $false)]
|
||||
[Int]$Indent = 4
|
||||
)
|
||||
|
||||
function ConvertTo-Psd1String {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
$Object,
|
||||
|
||||
[Parameter(Mandatory = $false)]
|
||||
[int]$Level = 0
|
||||
)
|
||||
|
||||
$indentStr = " " * ($Indent * $Level)
|
||||
$nextIndentStr = " " * ($Indent * ($Level + 1))
|
||||
|
||||
if ($null -eq $Object) {
|
||||
return "`$null"
|
||||
}
|
||||
|
||||
switch ($Object.GetType().Name) {
|
||||
"Hashtable" {
|
||||
if ($Object.Count -eq 0) {
|
||||
return "@{}"
|
||||
}
|
||||
|
||||
$lines = @("@{")
|
||||
foreach ($key in ($Object.Keys)) {
|
||||
$value = ConvertTo-Psd1String -Object $Object[$key] -Level ($Level + 1)
|
||||
$lines += "$nextIndentStr$key = $value"
|
||||
}
|
||||
$lines += "$indentStr}"
|
||||
return ($lines -join "`r`n")
|
||||
}
|
||||
|
||||
"Object[]" {
|
||||
if ($Object.Count -eq 0) {
|
||||
return "@()"
|
||||
}
|
||||
|
||||
$lines = @("@(")
|
||||
foreach ($item in $Object) {
|
||||
$value = ConvertTo-Psd1String -Object $item -Level ($Level + 1)
|
||||
$lines += "$nextIndentStr$value"
|
||||
}
|
||||
$lines += "$indentStr)"
|
||||
return ($lines -join "`r`n")
|
||||
}
|
||||
|
||||
"ArrayList" {
|
||||
return ConvertTo-Psd1String -Object $Object.ToArray() -Level $Level
|
||||
}
|
||||
|
||||
"String" {
|
||||
# Escape für einfache Anführungszeichen
|
||||
$escaped = $Object -replace "'", "''"
|
||||
return "'$escaped'"
|
||||
}
|
||||
|
||||
"Boolean" {
|
||||
return "`$$Object"
|
||||
}
|
||||
|
||||
"Int32" {
|
||||
return $Object.ToString()
|
||||
}
|
||||
|
||||
"Int64" {
|
||||
return $Object.ToString()
|
||||
}
|
||||
|
||||
"Double" {
|
||||
return $Object.ToString()
|
||||
}
|
||||
|
||||
default {
|
||||
if ($Object -is [Array]) {
|
||||
return ConvertTo-Psd1String -Object @($Object) -Level $Level
|
||||
}
|
||||
# Fallback für andere Typen
|
||||
return "'$Object'"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$psd1Content = ConvertTo-Psd1String -Object $Hashtable
|
||||
|
||||
# Stelle sicher, dass das Verzeichnis existiert
|
||||
$directory = Split-Path -Path $Path -Parent
|
||||
if ($directory -and -not (Test-Path -Path $directory)) {
|
||||
New-Item -Path $directory -ItemType Directory -Force | Out-Null
|
||||
}
|
||||
|
||||
# Schreibe die Datei mit UTF8-BOM Encoding (Standard für PSD1)
|
||||
$psd1Content | Out-File -FilePath $Path -Encoding utf8 -Force
|
||||
|
||||
Write-Verbose "Hashtable erfolgreich nach '$Path' exportiert"
|
||||
|
||||
# Validiere die erstellte PSD1-Datei
|
||||
try {
|
||||
$null = Import-PowerShellDataFile -Path $Path
|
||||
Write-Verbose "PSD1-Datei erfolgreich validiert"
|
||||
}
|
||||
catch {
|
||||
Write-Warning "Die erstellte PSD1-Datei konnte nicht validiert werden: $_"
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Error "Fehler beim Exportieren des Hashtables: $_"
|
||||
throw
|
||||
}
|
||||
}
|
||||
21
Functions/Import-ConfigurationData.ps1
Normal file
21
Functions/Import-ConfigurationData.ps1
Normal file
@@ -0,0 +1,21 @@
|
||||
function Import-ConfigurationData {
|
||||
$result = (
|
||||
[DialogBuilder]::OpenFile().
|
||||
SetTitle("Templates auswählen").
|
||||
SetCommonFilter("PSD1").
|
||||
SetMultiselect($true).
|
||||
SetInitialDirectory($settingsManager.Get("DeploymentPath")).
|
||||
Show()
|
||||
)
|
||||
if ($result.Result) {
|
||||
foreach ($file in $result.FileNames) {
|
||||
$newItem = New-Object PSObject -Property @{ BaseName = [System.IO.Path]::GetFileNameWithoutExtension($file); FullName = $file }
|
||||
$selectionList.Items.Add($newItem)
|
||||
$stateManager.SetState("hasSelection", $true)
|
||||
$stateManager.SetState("isMerged", $false)
|
||||
$stateManager.UpdateAllButtons()
|
||||
$statusBar.SetText("Status", "Zur Auswahl hinzugefügt: $($file.fullPath)")
|
||||
}
|
||||
Merge-Templates
|
||||
}
|
||||
}
|
||||
89
Functions/Import-OrderedPowerShellDataFile.ps1
Normal file
89
Functions/Import-OrderedPowerShellDataFile.ps1
Normal file
@@ -0,0 +1,89 @@
|
||||
function Import-OrderedPowerShellDataFile {
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
[string]$Path
|
||||
)
|
||||
|
||||
function ConvertTo-OrderedHashtable {
|
||||
param(
|
||||
$HashtableAst
|
||||
)
|
||||
|
||||
# Verwende OrderedDictionary statt [ordered]@{}
|
||||
$ordered = New-Object System.Collections.Specialized.OrderedDictionary
|
||||
|
||||
# Sortiere KeyValuePairs nach ihrer Position im Quelltext
|
||||
$sortedKvps = $HashtableAst.KeyValuePairs | Sort-Object { $_.Item1.Extent.StartOffset }
|
||||
|
||||
foreach ($kvp in $sortedKvps) {
|
||||
# Schlüssel extrahieren
|
||||
$key = $kvp.Item1.Extent.Text -replace '[''"]', ''
|
||||
|
||||
# Wert verarbeiten
|
||||
$valueAst = $kvp.Item2
|
||||
|
||||
# Suche nach HashtableAst in PipelineAst
|
||||
$hashtable = $null
|
||||
if ($valueAst -is [System.Management.Automation.Language.HashtableAst]) {
|
||||
$hashtable = $valueAst
|
||||
}
|
||||
elseif ($valueAst -is [System.Management.Automation.Language.PipelineAst]) {
|
||||
# Suche HashtableAst innerhalb der Pipeline
|
||||
$hashtable = $valueAst.Find({
|
||||
$args[0] -is [System.Management.Automation.Language.HashtableAst]
|
||||
}, $false)
|
||||
}
|
||||
|
||||
if ($hashtable) {
|
||||
$value = ConvertTo-OrderedHashtable -HashtableAst $hashtable
|
||||
}
|
||||
elseif ($valueAst -is [System.Management.Automation.Language.ArrayLiteralAst]) {
|
||||
$value = @()
|
||||
foreach ($element in $valueAst.Elements) {
|
||||
if ($element -is [System.Management.Automation.Language.HashtableAst]) {
|
||||
$value += ConvertTo-OrderedHashtable -HashtableAst $element
|
||||
}
|
||||
else {
|
||||
$value += Invoke-Expression $element.Extent.Text
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
try {
|
||||
$value = Invoke-Expression $valueAst.Extent.Text
|
||||
}
|
||||
catch {
|
||||
$value = $valueAst.Extent.Text
|
||||
}
|
||||
}
|
||||
|
||||
$ordered.Add($key, $value)
|
||||
}
|
||||
|
||||
return $ordered
|
||||
}
|
||||
|
||||
# Datei parsen
|
||||
$errors = $null
|
||||
$tokens = $null
|
||||
$ast = [System.Management.Automation.Language.Parser]::ParseFile(
|
||||
$Path,
|
||||
[ref]$tokens,
|
||||
[ref]$errors
|
||||
)
|
||||
|
||||
if ($errors) {
|
||||
throw "Fehler beim Parsen der Datei: $($errors[0].Message)"
|
||||
}
|
||||
|
||||
# Finde die oberste Hashtable
|
||||
$hashtableAst = $ast.Find({
|
||||
$args[0] -is [System.Management.Automation.Language.HashtableAst]
|
||||
}, $true)
|
||||
|
||||
if (-not $hashtableAst) {
|
||||
throw "Keine Hashtable in der Datei gefunden"
|
||||
}
|
||||
|
||||
return ConvertTo-OrderedHashtable -HashtableAst $hashtableAst
|
||||
}
|
||||
126
Functions/Load-Templates.ps1
Normal file
126
Functions/Load-Templates.ps1
Normal file
@@ -0,0 +1,126 @@
|
||||
function Load-Templates {
|
||||
|
||||
$flow.SuspendLayout()
|
||||
$flow.Controls.Clear()
|
||||
|
||||
# Lokales Tracking-Objekt
|
||||
$selectionTracker = @{
|
||||
LastSelectedListBox = $null
|
||||
}
|
||||
|
||||
if (-not (Test-Path -Path $($settingsManager.Get("TemplatePath")))) {
|
||||
$statusBar.SetText("Status", "Root-Ordner nicht gefunden: $rootPath")
|
||||
}
|
||||
else {
|
||||
try {
|
||||
$Categories = Get-ChildItem -Path $($settingsManager.Get("TemplatePath")) -Directory -ErrorAction Stop
|
||||
}
|
||||
catch {
|
||||
$statusBar.SetText("Status", "Fehler beim Laden: $($_.Exception.Message)")
|
||||
[System.Windows.Forms.MessageBox]::Show(
|
||||
"Konnte Kategorien nicht laden: $($_.Exception.Message)",
|
||||
"Fehler",
|
||||
[System.Windows.Forms.MessageBoxButtons]::OK,
|
||||
[System.Windows.Forms.MessageBoxIcon]::Error
|
||||
)
|
||||
return
|
||||
}
|
||||
if ($Categories.Count -eq 0) {
|
||||
$labelNoCategories = (
|
||||
[LabelBuilder]::new("Keine Unterordner gefunden.", 24).
|
||||
SetDock('Top').
|
||||
SetTextAlign([System.Drawing.ContentAlignment]::MiddleLeft).
|
||||
SetPadding(5, 0, 0, 0).
|
||||
Build()
|
||||
)
|
||||
$flow.Controls.Add($labelNoCategories)
|
||||
return
|
||||
}
|
||||
else {
|
||||
foreach ($Categorie in $Categories) {
|
||||
|
||||
$GroupBox = (
|
||||
[GroupBoxBuilder]::new($Categorie.Name).
|
||||
#SetAutoSize($true).
|
||||
SetWidth(0).
|
||||
SetHeight(90).
|
||||
SetMargin(4).
|
||||
SetPadding(10).
|
||||
AddTo($flow)
|
||||
)
|
||||
|
||||
$GroupBox.Tag = $Categorie.Name
|
||||
|
||||
$Files = Get-ChildItem -Path $Categorie.FullName -Filter "*.psd1" -File -ErrorAction SilentlyContinue | Sort-Object Name
|
||||
if ($Files.Count -eq 0) {
|
||||
$ListBox = (
|
||||
[ListBoxBuilder]::new().
|
||||
SetDock('Fill'). # Füllt die GroupBox aus
|
||||
AddItem("Keine Templates").
|
||||
AddTo($GroupBox)
|
||||
)
|
||||
}
|
||||
else {
|
||||
|
||||
$ListBox = (
|
||||
[ListBoxBuilder]::new().
|
||||
SetDock('Fill').
|
||||
AddSelectedIndexChangedHandler({
|
||||
param($s, $e)
|
||||
|
||||
if ($null -ne $selectionTracker.LastSelectedListBox -and
|
||||
$selectionTracker.LastSelectedListBox -ne $s) {
|
||||
|
||||
# Deselektiere die vorherige ListBox
|
||||
$selectionTracker.LastSelectedListBox.ClearSelected()
|
||||
}
|
||||
|
||||
# Speichere die aktuelle ListBox
|
||||
$selectionTracker.LastSelectedListBox = $s
|
||||
|
||||
$selectedItem = $s.SelectedItem
|
||||
if ($null -ne $selectedItem -and ($selectedItem -isnot [string])) {
|
||||
$currentGroupBox = $s.Parent
|
||||
$statusBar.SetText("Status", "Ausgewählt: $($selectedItem.FullName) [Kategorie: $($currentGroupBox.Tag)]")
|
||||
Show-Template -Template $([TemplateBuilder]::new($selectedItem.FullName).ResolveDeploymentDataVariables())
|
||||
}
|
||||
}.GetNewClosure()).
|
||||
AddMouseDoubleClickHandler({
|
||||
param($s, $e)
|
||||
$selectedItem = $s.SelectedItem
|
||||
if ($null -ne $selectedItem -and ($selectedItem -isnot [string])) {
|
||||
$fullPath = $selectedItem.FullName
|
||||
if (-not (Test-Path $fullPath)) {
|
||||
[System.Windows.Forms.MessageBox]::Show("Datei nicht gefunden: $fullPath", "Fehler", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Error)
|
||||
return
|
||||
}
|
||||
$newItem = New-Object PSObject -Property @{ BaseName = [System.IO.Path]::GetFileNameWithoutExtension($fullPath); FullName = $fullPath }
|
||||
if (-not ($selectionList.Items | Where-Object { $_.FullName -eq $newItem.FullName })) {
|
||||
$selectionList.Items.Add($newItem) | Out-Null
|
||||
$stateManager.SetState("hasSelection", $true)
|
||||
$stateManager.SetState("isMerged", $false)
|
||||
$stateManager.UpdateAllButtons()
|
||||
$statusBar.SetText("Status", "Zur Auswahl hinzugefügt: $fullPath")
|
||||
}
|
||||
else {
|
||||
$statusBar.SetText("Status", "Datei bereits in der Auswahl")
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
foreach ($file in $files) {
|
||||
$item = New-Object PSObject -Property @{ BaseName = $file.BaseName; FullName = $file.FullName }
|
||||
$ListBox.AddItem($item)
|
||||
$ListBox.AddTo($GroupBox)
|
||||
}
|
||||
}
|
||||
}
|
||||
$flow.ResumeLayout()
|
||||
}
|
||||
}
|
||||
|
||||
$form.Form.Invoke([Action] {
|
||||
$splitPanel.AutoSizeSplitterToPanel1Content()
|
||||
})
|
||||
}
|
||||
83
Functions/Merge-ConfigurationData.ps1
Normal file
83
Functions/Merge-ConfigurationData.ps1
Normal file
@@ -0,0 +1,83 @@
|
||||
function Merge-ConfigurationData {
|
||||
[CmdletBinding()]
|
||||
Param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[System.Collections.Hashtable]
|
||||
$Template,
|
||||
[Parameter(Mandatory = $true)]
|
||||
[System.Collections.Hashtable]
|
||||
$Deployment,
|
||||
[Parameter(Mandatory = $false)]
|
||||
[System.Collections.Hashtable]
|
||||
$Output
|
||||
)
|
||||
|
||||
# Prüfe auf zirkuläre Referenzen
|
||||
if ($Template -eq $Deployment) {
|
||||
throw "Zirkuläre Referenz erkannt"
|
||||
}
|
||||
|
||||
if ($Output -eq $null) {
|
||||
$Output = $Deployment
|
||||
}
|
||||
|
||||
foreach ($Property in $Template.GetEnumerator()) {
|
||||
if ($Property.Value -is [System.Collections.Hashtable]) {
|
||||
Write-Verbose "Key [$($Property.Name)] is a Hashtable"
|
||||
if ($null -ne $Deployment.$($Property.Name)) {
|
||||
Write-Verbose "Key [$($Property.Name)] is present in Deployment Data"
|
||||
$Output.($Property.Name) = Merge-ConfigurationData -Template $Template.$($Property.Name) -Deployment $Deployment.$($Property.Name) -Output $Output.$($Property.Name)
|
||||
}
|
||||
else {
|
||||
Write-Verbose "Key [$($Property.Name)] is not present in Deployment Data"
|
||||
$Output.Add($($Property.Name), $Template.$($Property.Name))
|
||||
}
|
||||
}
|
||||
elseif ($Property.Value -is [System.Collections.Specialized.OrderedDictionary]) {
|
||||
Write-Verbose "Key [$($Property.Name)] is a Ordered Dictionary"
|
||||
if ($null -ne $Deployment.$($Property.Name)) {
|
||||
Write-Verbose "Key [$($Property.Name)] is present in Deployment Data"
|
||||
$Output.($Property.Name) = Merge-ConfigurationData -Template $Template.$($Property.Name) -Deployment $Deployment.$($Property.Name) -Output $Output.$($Property.Name)
|
||||
}
|
||||
else {
|
||||
Write-Verbose "Key [$($Property.Name)] is not present in Deployment Data"
|
||||
$Output.Add($($Property.Name), $Template.$($Property.Name))
|
||||
}
|
||||
}
|
||||
elseif ($Property.Value -is [System.Array]) {
|
||||
Write-Verbose "$($Property.Name) is ein Array"
|
||||
Write-Verbose "Total Items in Template Array [$($Property.Value.Count)]"
|
||||
Write-Verbose "Total Items in Deployment Array [$($Deployment.$($Property.Name).Count)]"
|
||||
if ($null -ne $Deployment.$($Property.Name)) {
|
||||
Write-Verbose "Array is defined in Deployment"
|
||||
for ($i = 0; $i -lt $Property.Value.Count; $i++) {
|
||||
|
||||
$SearchItem = $($Property.Value[$i].GetEnumerator() | Where-Object { ($_.Value -is [String]) -and ($_.Name -like "*Name") })[0]
|
||||
if ($($Deployment.$($Property.Name) | ? { $_.($SearchItem.Name) -eq $SearchItem.Value })) {
|
||||
Merge-ConfigurationData -Template $Property.Value[$i] -Deployment $($Deployment.$($Property.Name) | ? { $_.($SearchItem.Name) -eq $SearchItem.Value }) -Output $($Output.$($Property.Name) | ? { $_.($SearchItem.Name) -eq $SearchItem.Value }) | Out-Null
|
||||
}
|
||||
else {
|
||||
Write-Verbose "Pair $($Key.Name) - $($Key.Value) not present"
|
||||
$Output.$($Property.Name) += $Property.Value[$i]
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
Write-Verbose "Array is not defined in Deployment"
|
||||
$Output.$($Property.Name) = $Template.$($Property.Name)
|
||||
}
|
||||
}
|
||||
else {
|
||||
Write-Verbose "$($Property.Name) is a String or Integer Value"
|
||||
if ($null -eq $Deployment.$($Property.Name)) {
|
||||
|
||||
$Output.Add($Property.Name, $Template.($Property.Name))
|
||||
|
||||
}
|
||||
elseif ($Deployment.$($Property.Name) -ne $Property.Value) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return $Output
|
||||
}
|
||||
43
Functions/Merge-Templates.ps1
Normal file
43
Functions/Merge-Templates.ps1
Normal file
@@ -0,0 +1,43 @@
|
||||
function Merge-Templates {
|
||||
$Errors = @()
|
||||
[System.Collections.Hashtable] $ConfigurationData = @{}
|
||||
#[System.Collections.Specialized.OrderedDictionary] $ConfigurationData = @{}
|
||||
|
||||
for ($i = 0; $i -lt $selectionList.Items.Count; $i++) {
|
||||
$item = $selectionList.Items[$i]
|
||||
$file = $item.FullName
|
||||
if (-not (Test-Path $file)) { $Errors += "Datei nicht gefunden: $file"; continue }
|
||||
|
||||
try {
|
||||
try {
|
||||
$TemplateData = Import-OrderedPowerShellDataFile -Path $file -ErrorAction Stop
|
||||
}
|
||||
catch {
|
||||
$Errors += "Datei konnte nicht importiert werden"
|
||||
}
|
||||
|
||||
$ConfigurationData = Merge-ConfigurationData -Template $ConfigurationData -Deployment $TemplateData
|
||||
}
|
||||
catch {
|
||||
$Errors += "Fehler beim Verarbeiten $($file): $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
|
||||
if ($null -ne $ConfigurationData) {
|
||||
Update-TreeView -ConfigurationData $([TemplateBuilder]::new($ConfigurationData).ResolveDeploymentDataVariables())
|
||||
$statusBar.SetText("Status", "Merge erfolgreich: $($selectionList.Items.Count) Dateien")
|
||||
}
|
||||
else {
|
||||
|
||||
Update-TreeView -ConfigurationData $ConfigurationData
|
||||
$statusLabel.Text = "Merge ergab kein Ergebnis"
|
||||
}
|
||||
|
||||
if ($Errors.Count -gt 0) {
|
||||
[System.Windows.Forms.MessageBox]::Show(($Errors -join "`r`n"), "Merge Warnungen", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Warning)
|
||||
return
|
||||
}
|
||||
else {
|
||||
return $ConfigurationData
|
||||
}
|
||||
}
|
||||
10
Functions/Show-Template.ps1
Normal file
10
Functions/Show-Template.ps1
Normal file
@@ -0,0 +1,10 @@
|
||||
function Show-Template {
|
||||
Param(
|
||||
[System.Collections.Hashtable] $Template
|
||||
)
|
||||
$treeView.Nodes.Clear()
|
||||
|
||||
$tempBuilder = [TreeViewBuilder]::new()
|
||||
$tempBuilder.control = $treeView
|
||||
$tempBuilder.LoadTemplate($Template, "Template")
|
||||
}
|
||||
55
Functions/Update-ParametersPanel.ps1
Normal file
55
Functions/Update-ParametersPanel.ps1
Normal file
@@ -0,0 +1,55 @@
|
||||
function Update-ParametersPanel {
|
||||
Param(
|
||||
[System.Collections.Hashtable] $ConfigurationData
|
||||
)
|
||||
|
||||
if ($ConfigurationData.Contains("Parameters") -or $ConfigurationData.Contains("Variables")) {
|
||||
if ($ConfigurationData.Contains("Parameters")) {
|
||||
if (!($tabControl.Controls | ? { $_.Text -eq "Parameters" })) {
|
||||
$ParametersTabPage = (
|
||||
[TabPageBuilder]::new("Parameters").
|
||||
Build()
|
||||
)
|
||||
}
|
||||
|
||||
$GridView = (
|
||||
[DataGridViewBuilder]::new().
|
||||
SetHeaderColumns(@("Name", "Value")).
|
||||
SetHeaderColumnReadOnly("Name").
|
||||
Build()
|
||||
)
|
||||
|
||||
foreach ($Parameter in $ConfigurationData.Parameters.GetEnumerator()) {
|
||||
$GridView.Rows.Add($Parameter.Name, $($Parameter.Value.Value)) | Out-Null
|
||||
|
||||
}
|
||||
$ParametersTabPage.Controls.Add($GridView)
|
||||
$tabControl.Controls.Add($ParametersTabPage)
|
||||
|
||||
}
|
||||
|
||||
if ($ConfigurationData.Contains("Variables")) {
|
||||
if (!($tabControl.Controls | ? { $_.Text -eq "Variables" })) {
|
||||
$VariablesTabPage = (
|
||||
[TabPageBuilder]::new("Variables").
|
||||
Build()
|
||||
)
|
||||
}
|
||||
|
||||
$GridView = (
|
||||
[DataGridViewBuilder]::new().
|
||||
SetHeaderColumns(@("Name", "Value")).
|
||||
SetHeaderColumnReadOnly("Name").
|
||||
Build()
|
||||
)
|
||||
|
||||
foreach ($Variable in $ConfigurationData.Variables.GetEnumerator()) {
|
||||
$GridView.Rows.Add($Variable.Name, $($Variable.Value)) | Out-Null
|
||||
|
||||
}
|
||||
$VariablesTabPage.Controls.Add($GridView)
|
||||
$tabControl.Controls.Add($VariablesTabPage)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
25
Functions/Update-Treeview.ps1
Normal file
25
Functions/Update-Treeview.ps1
Normal file
@@ -0,0 +1,25 @@
|
||||
function Update-TreeView {
|
||||
Param(
|
||||
[System.Collections.Hashtable] $ConfigurationData
|
||||
)
|
||||
if ($null -ne $ConfigurationData) {
|
||||
$tempBuilder = [TreeViewBuilder]::new()
|
||||
$tempBuilder.control = $treeView
|
||||
$tempBuilder.LoadTemplate($ConfigurationData['Resources'], "Deployment")
|
||||
$statusBar.SetText("Status", "Merged: Anzeige aktualisiert")
|
||||
$stateManager.SetState("isMerged", $true)
|
||||
$stateManager.UpdateAllButtons()
|
||||
|
||||
# Parameter und Variablen Panel aktualisieren
|
||||
Update-ParametersPanel -ConfigurationData $ConfigurationData
|
||||
|
||||
}
|
||||
else {
|
||||
$treeView.Nodes.Clear()
|
||||
$treeView.Nodes.Add('No merged data') | Out-Null
|
||||
$statusBar.SetText("Status", "Kein Merge vorhanden")
|
||||
|
||||
# Panel ausblenden
|
||||
$parametersPanel.Visible = $false
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user