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] } }