Compare commits

..

3 Commits

Author SHA1 Message Date
Torsten Brendgen
1a4ba96dc8 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.
2026-06-29 22:16:05 +02:00
Torsten Brendgen
6986570510 Merge branch 'main' of https://git.local.unique-studios.de/PowerShell-Projekte/DSC-Configuration-Compiler 2026-06-27 23:19:38 +02:00
Torsten Brendgen
846dccf468 clean dev commit 2026-06-27 23:18:34 +02:00
17 changed files with 4663 additions and 4499 deletions

3616
Compiler.Core.ps1 Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,93 +0,0 @@
@{
Resources = @{
NonNodeData = @{
Services = @{
SharePoint = @{
Farm = @{
Passphrase = 'Use-SecureString-Or-KeyVault'
ConfigDatabaseName = 'SharePoint_Farm_Config'
ServiceApplications = @{
AppManagementService = @{
DatabaseName = 'SharePoint_Services_AppManagement'
Provision = 'True'
}
StateService = @{
DatabaseName = 'SharePoint_Services_StateService'
Provision = 'True'
}
SubscriptionSettingsService = @{
DatabaseName = 'SharePoint_Services_SubscriptionSettings'
Provision = 'True'
}
ManagedMetadataService = @{
DatabaseName = 'SharePoint_Services_ManagedMetadata'
Name = 'Managed Metadata Service'
ApplicationPool = 'SharePoint Service Applications'
Provision = 'True'
}
SearchService = @{
DatabaseName = 'SharePoint_Services_Search'
Name = 'Search Service Application'
ApplicationPool = 'SharePoint Service Applications'
Provision = 'True'
}
UsageAndHealthService = @{
DatabaseName = 'SharePoint_Services_UsageAndHealth'
Provision = 'True'
}
SecureStoreService = @{
DatabaseName = 'SharePoint_Services_SecureStore'
Name = 'Secure Store Service'
ApplicationPool = 'SharePoint Service Applications'
Provision = 'True'
}
UserProfileService = @{
SyncDBName = 'SharePoint_Services_UserProfile_SyncDB'
ApplicationPool = 'SharePoint User Profile Services'
Provision = 'True'
Name = 'User Profile Service'
SocialDBName = 'SharePoint_Services_UserProfile_SocialDB'
ProfileDBName = 'SharePoint_Services_UserProfile_ProfileDB'
}
}
CentralAdminAuth = 'NTLM'
CentralAdminPort = '2016'
AdminContentDatabase = 'SharePoint_Farm_AdminContent'
ServiceApplicationPools = @{
Default = @{
Account = 'CONTOSO\sp_services'
Name = 'SharePoint Service Applications'
}
UserProfile = @{
Account = 'CONTOSO\sp_ups'
Name = 'SharePoint User Profile Services'
}
}
}
Database = @{
SQLAlias = @{
SQLServer = @{
InstanceName = ''
ServerName = ''
TcpPort = '0'
}
}
}
General = @{
ProductKey = '0000-0000-0000-0000-0000'
}
Windows = @{
Registry = @{
DisableLoopbackCheck = @{
Path = 'HKLM:\SYSTEM\CurrentControlSet\Control\Lsa'
Name = 'DisableLoopbackCheck'
Value = '1'
Type = 'DWord'
}
}
}
}
}
}
}
}

View File

@@ -10,8 +10,9 @@ function Export-ConfigurationData {
)
if ($result.Result) {
try {
$ConfigurationData = @{
"Resources" = $(ConvertFrom-TreeView -TreeView $treeView -SkipRootNode)
$ConfigurationData = $script:ResolvedConfigurationData
if($null -eq $ConfigurationData){
throw "Keine aufgelöste ConfigurationData zum Exportieren vorhanden."
}
Export-Hashtable -Hashtable $ConfigurationData -Path $result.FileName

View File

@@ -0,0 +1,170 @@
function Get-TemplatePreviewData {
[CmdletBinding()]
Param(
[Parameter(Mandatory = $true)]
[string]
$TemplatePath
)
if (-not (Test-Path -Path $TemplatePath -PathType Leaf)) {
throw "Template nicht gefunden: $TemplatePath"
}
$directory = Split-Path -Path $TemplatePath -Parent
$defaultFiles = @(Get-ChildItem -Path $directory -Filter "*.psd1" -File -ErrorAction SilentlyContinue |
Where-Object { $_.BaseName -eq "Default" -or $_.BaseName -like "*.Default" } |
Sort-Object Name)
$mergeFiles = @()
$mergeFiles += @($defaultFiles | ForEach-Object { $_.FullName })
$mergeFiles += $TemplatePath
$mergedConfigurationData = $null
foreach ($file in $mergeFiles) {
$templateData = Import-PowerShellDataFile -Path $file -ErrorAction Stop
if ($null -eq $mergedConfigurationData) {
$mergedConfigurationData = $templateData
}
else {
$mergedConfigurationData = Merge-DSCConfigurationData -Template $mergedConfigurationData -Deployment $templateData
}
}
$resolvedConfigurationData = $null
$resolveError = $null
try {
$resolvedConfigurationData = Resolve-DSCConfigurationData -ConfigurationData $mergedConfigurationData -ErrorAction Stop
}
catch {
$resolveError = $_
}
$displayOrder = $null
if (Get-Command -Name Import-OrderedPowerShellDataFile -ErrorAction SilentlyContinue) {
foreach ($file in $mergeFiles) {
$orderedTemplateData = Import-OrderedPowerShellDataFile -Path $file -ErrorAction Stop
if ($null -eq $displayOrder) {
$displayOrder = $orderedTemplateData
}
else {
$displayOrder = Merge-TemplatePreviewOrder -Base $displayOrder -Override $orderedTemplateData
}
}
}
$displaySource = if ($null -ne $resolvedConfigurationData) { $resolvedConfigurationData } else { $mergedConfigurationData }
$displayConfigurationData = ConvertTo-TemplatePreviewDisplayOrder -Value $displaySource -Order $displayOrder
[PSCustomObject]@{
Files = $mergeFiles
Merged = $mergedConfigurationData
Resolved = $resolvedConfigurationData
Display = $displayConfigurationData
ResolveError = $resolveError
}
}
function Test-TemplatePreviewDictionaryKey {
Param(
[Parameter(Mandatory = $true)]
[System.Collections.IDictionary]
$Dictionary,
[Parameter(Mandatory = $true)]
[string]
$Key
)
if ($Dictionary -is [System.Collections.Specialized.OrderedDictionary]) {
return $Dictionary.Contains($Key)
}
return $Dictionary.ContainsKey($Key)
}
function Merge-TemplatePreviewOrder {
Param(
[AllowNull()]
$Base,
[AllowNull()]
$Override
)
if ($Base -is [System.Collections.IDictionary] -and $Override -is [System.Collections.IDictionary]) {
$ordered = New-Object System.Collections.Specialized.OrderedDictionary
foreach ($key in $Base.Keys) {
if (Test-TemplatePreviewDictionaryKey -Dictionary $Override -Key $key) {
$ordered.Add($key, (Merge-TemplatePreviewOrder -Base $Base[$key] -Override $Override[$key]))
}
else {
$ordered.Add($key, $Base[$key])
}
}
foreach ($key in $Override.Keys) {
if (-not (Test-TemplatePreviewDictionaryKey -Dictionary $ordered -Key $key)) {
$ordered.Add($key, $Override[$key])
}
}
return $ordered
}
return $Override
}
function ConvertTo-TemplatePreviewDisplayOrder {
Param(
[AllowNull()]
$Value,
[AllowNull()]
$Order
)
if ($Value -is [System.Collections.IDictionary]) {
$ordered = New-Object System.Collections.Specialized.OrderedDictionary
$orderedKeys = @()
if ($Order -is [System.Collections.IDictionary]) {
foreach ($key in $Order.Keys) {
if (Test-TemplatePreviewDictionaryKey -Dictionary $Value -Key $key) {
$orderedKeys += $key
$ordered.Add($key, (ConvertTo-TemplatePreviewDisplayOrder -Value $Value[$key] -Order $Order[$key]))
}
}
}
foreach ($key in $Value.Keys) {
if ($orderedKeys -notcontains $key) {
$ordered.Add($key, (ConvertTo-TemplatePreviewDisplayOrder -Value $Value[$key] -Order $null))
}
}
return $ordered
}
if ($Value -is [System.Collections.IEnumerable] -and -not ($Value -is [string])) {
$items = @()
$index = 0
foreach ($item in $Value) {
$itemOrder = $null
if ($Order -is [System.Array] -and $Order.Count -gt $index) {
$itemOrder = $Order[$index]
}
$items += ,(ConvertTo-TemplatePreviewDisplayOrder -Value $item -Order $itemOrder)
$index++
}
return ,$items
}
return $Value
}

View File

@@ -0,0 +1,117 @@
function Import-OrderedPowerShellDataFile {
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true)]
[string]
$Path
)
function ConvertTo-OrderedHashtable {
Param(
[Parameter(Mandatory=$true)]
$HashtableAst
)
$Ordered = New-Object System.Collections.Specialized.OrderedDictionary
$SortedPairs = $HashtableAst.KeyValuePairs | Sort-Object { $_.Item1.Extent.StartOffset }
foreach($Pair in $SortedPairs){
$Key = $Pair.Item1.Extent.Text.Trim("'`"")
$Ordered.Add($Key, (ConvertFrom-DataAst -Ast $Pair.Item2))
}
return $Ordered
}
function ConvertFrom-DataAst {
Param(
[AllowNull()]
$Ast
)
if($null -eq $Ast){
return $null
}
if($Ast -is [System.Management.Automation.Language.HashtableAst]){
return ConvertTo-OrderedHashtable -HashtableAst $Ast
}
if($Ast -is [System.Management.Automation.Language.PipelineAst]){
return ConvertFrom-DataAst -Ast $Ast.PipelineElements[0]
}
if($Ast -is [System.Management.Automation.Language.CommandExpressionAst]){
return ConvertFrom-DataAst -Ast $Ast.Expression
}
if($Ast -is [System.Management.Automation.Language.ParenExpressionAst]){
return ConvertFrom-DataAst -Ast $Ast.Pipeline
}
if($Ast -is [System.Management.Automation.Language.StatementBlockAst]){
$Items = @()
foreach($Statement in $Ast.Statements){
$Items += ,(ConvertFrom-DataAst -Ast $Statement)
}
return ,$Items
}
if($Ast -is [System.Management.Automation.Language.ArrayExpressionAst]){
return @(ConvertFrom-DataAst -Ast $Ast.SubExpression)
}
if($Ast -is [System.Management.Automation.Language.ArrayLiteralAst]){
$Items = @()
foreach($Element in $Ast.Elements){
$Items += ,(ConvertFrom-DataAst -Ast $Element)
}
return ,$Items
}
if($Ast -is [System.Management.Automation.Language.StringConstantExpressionAst]){
return $Ast.Value
}
if($Ast -is [System.Management.Automation.Language.ExpandableStringExpressionAst]){
return $Ast.Value
}
if($Ast -is [System.Management.Automation.Language.ConstantExpressionAst]){
return $Ast.Value
}
if($Ast -is [System.Management.Automation.Language.VariableExpressionAst]){
switch($Ast.VariablePath.UserPath){
"true" { return $true }
"false" { return $false }
"null" { return $null }
}
}
if($Ast -is [System.Management.Automation.Language.UnaryExpressionAst]){
$ChildValue = ConvertFrom-DataAst -Ast $Ast.Child
if($Ast.TokenKind -eq [System.Management.Automation.Language.TokenKind]::Minus){
return -1 * $ChildValue
}
return $ChildValue
}
throw "Nicht unterstützter Ausdruck in PSD1: $($Ast.Extent.Text)"
}
$Tokens = $null
$Errors = $null
$Ast = [System.Management.Automation.Language.Parser]::ParseFile($Path, [ref]$Tokens, [ref]$Errors)
if($Errors.Count -gt 0){
throw "Fehler beim Parsen der Datei: $($Errors[0].Message)"
}
$HashtableAst = $Ast.Find({ $args[0] -is [System.Management.Automation.Language.HashtableAst] }, $true)
if($null -eq $HashtableAst){
throw "Keine Hashtable in der Datei gefunden."
}
return ConvertTo-OrderedHashtable -HashtableAst $HashtableAst
}

View File

@@ -1,126 +1,172 @@
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")
$templatePath = $settingsManager.Get("TemplatePath")
if (-not (Test-Path -Path $templatePath)) {
$statusBar.SetText("Status", "Template-Ordner nicht gefunden: $templatePath")
$flow.ResumeLayout()
return
}
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)
)
try {
$categories = @(Get-ChildItem -Path $templatePath -Directory -ErrorAction Stop | Where-Object {
@(Get-ChildItem -Path $_.FullName -Filter "*.psd1" -File -ErrorAction SilentlyContinue).Count -gt 0
})
}
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
)
$flow.ResumeLayout()
return
}
$GroupBox.Tag = $Categorie.Name
if ($categories.Count -eq 0) {
$labelNoCategories = (
[LabelBuilder]::new("Keine Templates gefunden.", 24).
SetDock('Top').
SetTextAlign([System.Drawing.ContentAlignment]::MiddleLeft).
SetPadding(5, 0, 0, 0).
Build()
)
$flow.Controls.Add($labelNoCategories)
$flow.ResumeLayout()
return
}
$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)
)
foreach ($category in $categories) {
$groupBoxWidth = [Math]::Max(($flow.ClientSize.Width - 20), 220)
$groupBox = (
[GroupBoxBuilder]::new($category.Name).
SetWidth($groupBoxWidth).
SetHeight(90).
SetMargin(4).
SetPadding(10).
AddTo($flow)
)
$groupBox.Tag = $category.Name
$files = @(Get-ChildItem -Path $category.FullName -Filter "*.psd1" -File -ErrorAction SilentlyContinue |
Where-Object { $_.BaseName -ne "Default" -and $_.BaseName -notlike "*.Default" } |
Sort-Object Name)
$listBox = (
[ListBoxBuilder]::new().
SetDock('Fill').
AddSelectedIndexChangedHandler({
param($s, $e)
if ($null -ne $selectionTracker.LastSelectedListBox -and $selectionTracker.LastSelectedListBox -ne $s) {
$selectionTracker.LastSelectedListBox.ClearSelected()
}
else {
$ListBox = (
[ListBoxBuilder]::new().
SetDock('Fill').
AddSelectedIndexChangedHandler({
param($s, $e)
$selectionTracker.LastSelectedListBox = $s
$selectedItem = $s.SelectedItem
if ($null -ne $selectionTracker.LastSelectedListBox -and
$selectionTracker.LastSelectedListBox -ne $s) {
if ($null -ne $selectedItem -and ($selectedItem -isnot [string])) {
$currentGroupBox = $s.Parent
$statusBar.SetText("Status", "Ausgewählt: $($selectedItem.FullName) [Kategorie: $($currentGroupBox.Tag)]")
# Deselektiere die vorherige ListBox
$selectionTracker.LastSelectedListBox.ClearSelected()
}
try {
if (-not (Get-Command -Name Get-TemplatePreviewData -ErrorAction SilentlyContinue)) {
$previewFunctionPath = Join-Path -Path $settingsManager.Get("FunctionsPath") -ChildPath "Get-TemplatePreviewData.ps1"
if (Test-Path -Path $previewFunctionPath -PathType Leaf) {
. $previewFunctionPath
}
}
# Speichere die aktuelle ListBox
$selectionTracker.LastSelectedListBox = $s
if (-not (Get-Command -Name Get-TemplatePreviewData -ErrorAction SilentlyContinue)) {
$templateData = Import-OrderedPowerShellDataFile -Path $selectedItem.FullName -ErrorAction Stop
Show-Template -Template $templateData
$statusBar.SetText("Status", "Vorschau ohne Default-Merge geladen: Get-TemplatePreviewData ist nicht verfügbar")
return
}
$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")
}
}
})
)
$preview = Get-TemplatePreviewData -TemplatePath $selectedItem.FullName -ErrorAction Stop
$previewData = if ($null -ne $preview.Display) { $preview.Display } elseif ($null -ne $preview.Resolved) { $preview.Resolved } else { $preview.Merged }
foreach ($file in $files) {
$item = New-Object PSObject -Property @{ BaseName = $file.BaseName; FullName = $file.FullName }
$ListBox.AddItem($item)
$ListBox.AddTo($GroupBox)
Show-Template -Template $previewData
Update-ParametersPanel -ConfigurationData $preview.Merged
if ($null -ne $preview.ResolveError) {
$statusBar.SetText("Status", "Vorschau gemerged, Resolve unvollständig: $($preview.ResolveError.Exception.Message)")
}
else {
$statusBar.SetText("Status", "Vorschau geladen: $($preview.Files.Count) Datei(en) inklusive Defaults")
}
}
catch {
[System.Windows.Forms.MessageBox]::Show(
"Datei konnte nicht geladen werden: $($_.Exception.Message)",
"Fehler",
[System.Windows.Forms.MessageBoxButtons]::OK,
[System.Windows.Forms.MessageBoxIcon]::Error
)
}
}
}.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")
}
}
}).
AddTo($groupBox)
)
if($files.Count -eq 0){
$listBox.Items.Add("Keine Templates vorhanden") | Out-Null
}else{
foreach ($file in $files) {
$item = New-Object PSObject -Property @{
BaseName = $file.BaseName
FullName = $file.FullName
}
$listBox.Items.Add($item) | Out-Null
}
$flow.ResumeLayout()
}
}
$flow.ResumeLayout()
foreach ($groupBox in $flow.Controls) {
$groupBox.Width = [Math]::Max(($flow.ClientSize.Width - 20), 220)
}
$form.Form.Invoke([Action] {
$splitPanel.AutoSizeSplitterToPanel1Content()
})
$splitPanel.AutoSizeSplitterToPanel1Content()
})
}

View File

@@ -1,83 +0,0 @@
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
}

View File

@@ -1,36 +1,74 @@
function Merge-Templates {
$Errors = @()
[System.Collections.Hashtable] $ConfigurationData = @{}
#[System.Collections.Specialized.OrderedDictionary] $ConfigurationData = @{}
$MergedConfigurationData = $null
$MergeFiles = @()
$AddedDefaultFiles = @{}
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 }
if (-not (Test-Path $file)) {
$Errors += "Datei nicht gefunden: $file"
continue
}
$directory = Split-Path -Path $file -Parent
$defaultFiles = @(Get-ChildItem -Path $directory -Filter "*.psd1" -File -ErrorAction SilentlyContinue |
Where-Object { $_.BaseName -eq "Default" -or $_.BaseName -like "*.Default" } |
Sort-Object Name)
foreach($defaultFile in $defaultFiles){
if(-not $AddedDefaultFiles.ContainsKey($defaultFile.FullName)){
$MergeFiles += $defaultFile.FullName
$AddedDefaultFiles[$defaultFile.FullName] = $true
}
}
$MergeFiles += $file
}
foreach($file in $MergeFiles){
try {
try {
$TemplateData = [TemplateBuilder]::new($file).Template
$TemplateData = Import-PowerShellDataFile -Path $file -ErrorAction Stop
}
catch {
$Errors += "Datei konnte nicht importiert werden"
$Errors += "Datei konnte nicht importiert werden: $file"
continue
}
$ConfigurationData = Merge-ConfigurationData -Template $ConfigurationData -Deployment $TemplateData
if($null -eq $MergedConfigurationData){
$MergedConfigurationData = $TemplateData
}else{
$MergedConfigurationData = Merge-DSCConfigurationData -Template $MergedConfigurationData -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")
if ($null -ne $MergedConfigurationData) {
try {
$script:MergedConfigurationData = $MergedConfigurationData
$script:ResolvedConfigurationData = Resolve-DSCConfigurationData -ConfigurationData $MergedConfigurationData
}
catch {
$Errors += "Fehler beim Auflösen der ConfigurationData: $($_.Exception.Message)"
$script:ResolvedConfigurationData = $null
}
if($null -ne $script:ResolvedConfigurationData){
Update-TreeView -ConfigurationData $script:ResolvedConfigurationData
}else{
Update-TreeView -ConfigurationData $MergedConfigurationData
}
$statusBar.SetText("Status", "Merge erfolgreich: $($selectionList.Items.Count) Queue-Dateien, $($MergeFiles.Count) inklusive Defaults")
}
else {
Update-TreeView -ConfigurationData $ConfigurationData
Update-TreeView -ConfigurationData $MergedConfigurationData
$statusLabel.Text = "Merge ergab kein Ergebnis"
}
@@ -38,7 +76,6 @@ function Merge-Templates {
[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
}
return $script:ResolvedConfigurationData
}

View File

@@ -1,10 +1,15 @@
function Show-Template {
Param(
[System.Collections.Hashtable] $Template
$Template
)
$treeView.Nodes.Clear()
$tempBuilder = [TreeViewBuilder]::new()
$tempBuilder.control = $treeView
$tempBuilder.LoadTemplate($Template, "Template")
if($null -ne $Template -and $Template.Contains("Resources")){
$tempBuilder.LoadTemplate($Template["Resources"], "Template")
}else{
$treeView.Nodes.Add("No resources found") | Out-Null
}
}

View File

@@ -3,53 +3,63 @@ function Update-ParametersPanel {
[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)
foreach ($tabName in @("Parameters", "Variables")) {
$existingTabs = @($tabControl.Controls | Where-Object { $_.Text -eq $tabName })
foreach ($tab in $existingTabs) {
$tabControl.Controls.Remove($tab)
$tab.Dispose()
}
}
if ($null -eq $ConfigurationData) {
return
}
if ($ConfigurationData.Contains("Parameters")) {
$parametersTabPage = (
[TabPageBuilder]::new("Parameters").
Build()
)
$gridView = (
[DataGridViewBuilder]::new().
SetHeaderColumns(@("Name", "Value", "Type", "Required")).
SetHeaderColumnReadOnly("Name").
Build()
)
foreach ($parameter in $ConfigurationData.Parameters.GetEnumerator()) {
$value = $parameter.Value
$gridView.Rows.Add(
$parameter.Name,
$value.Value,
$value.Type,
$value.Required
) | Out-Null
}
$parametersTabPage.Controls.Add($gridView)
$tabControl.Controls.Add($parametersTabPage)
}
if ($ConfigurationData.Contains("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)
}
}

View File

@@ -5,13 +5,23 @@ function Update-TreeView {
if ($null -ne $ConfigurationData) {
$tempBuilder = [TreeViewBuilder]::new()
$tempBuilder.control = $treeView
$tempBuilder.LoadTemplate($ConfigurationData['Resources'], "Deployment")
if($ConfigurationData.ContainsKey("Resources")){
$tempBuilder.LoadTemplate($ConfigurationData['Resources'], "Deployment")
}else{
$treeView.Nodes.Clear()
$treeView.Nodes.Add("No resources found") | Out-Null
}
$statusBar.SetText("Status", "Merged: Anzeige aktualisiert")
$stateManager.SetState("isMerged", $true)
$stateManager.SetState("isResolved", $null -ne $script:ResolvedConfigurationData)
$stateManager.UpdateAllButtons()
# Parameter und Variablen Panel aktualisieren
Update-ParametersPanel -ConfigurationData $ConfigurationData
if($null -ne $script:MergedConfigurationData){
Update-ParametersPanel -ConfigurationData $script:MergedConfigurationData
}else{
Update-ParametersPanel -ConfigurationData $ConfigurationData
}
}
else {

View File

@@ -0,0 +1,13 @@
@{
Parameters = @{
DomainLabel = @{
Value = 'LAN'
}
DomainFQDN = @{
Value = 'bgw-online.de'
}
DomainNetBIOS = @{
Value = 'BGW-Online'
}
}
}

View File

@@ -1,14 +0,0 @@
@{
Resources = @{
NonNodeData = @{
Services = @{
ActiveDirectory = @{
Domain = @{
FQDN = "contoso.local"
NetBIOS = "Contoso"
}
}
}
}
}
}

View File

@@ -0,0 +1,244 @@
@{
Parameters = @{
DomainLabel = @{
Type = 'string'
DefaultValue = ''
Required = $false
MinLength = 2
MaxLength = 32
Pattern = '^[A-Za-z][A-Za-z0-9_-]*$'
Metadata = @{
Description = @{
'de-DE' = 'Kurzer logischer Bezeichner der Umgebung oder Domaene.'
'en-US' = 'Short logical identifier for the environment or domain.'
}
}
}
DomainFQDN = @{
Type = 'string'
DefaultValue = ''
Required = $true
Pattern = '^[A-Za-z0-9.-]+$'
Metadata = @{
Description = @{
'de-DE' = 'Vollqualifizierter DNS-Name der Active-Directory-Domaene.'
'en-US' = 'Fully qualified DNS name of the Active Directory domain.'
}
}
}
DomainNetBIOS = @{
Type = 'string'
DefaultValue = ''
Required = $true
MinLength = 1
MaxLength = 15
Pattern = '^[A-Za-z0-9_-]+$'
Metadata = @{
Description = @{
'de-DE' = 'NetBIOS-Name der Active-Directory-Domaene.'
'en-US' = 'NetBIOS name of the Active Directory domain.'
}
}
}
ForestMode = @{
Type = 'string'
DefaultValue = 'WinThreshold'
AllowedValues = @(
'Win2012R2',
'WinThreshold'
)
Metadata = @{
Description = @{
'de-DE' = 'Funktionsebene des Active-Directory-Forests.'
'en-US' = 'Functional level of the Active Directory forest.'
}
}
}
DomainMode = @{
Type = 'string'
DefaultValue = 'WinThreshold'
AllowedValues = @(
'Win2012R2',
'WinThreshold'
)
Metadata = @{
Description = @{
'de-DE' = 'Funktionsebene der Active-Directory-Domaene.'
'en-US' = 'Functional level of the Active Directory domain.'
}
}
}
DefaultSiteName = @{
Type = 'string'
DefaultValue = 'Default-First-Site-Name'
Required = $true
MinLength = 1
MaxLength = 64
Metadata = @{
Description = @{
'de-DE' = 'Standard-AD-Sitename fuer Domaenencontroller und Subnetze.'
'en-US' = 'Default AD site name for domain controllers and subnets.'
}
}
}
DefaultSubnet = @{
Type = 'string'
DefaultValue = ''
Required = $false
Pattern = '^$|^\d{1,3}(\.\d{1,3}){3}/\d{1,2}$'
Metadata = @{
Description = @{
'de-DE' = 'Optionales Standard-Subnetz im CIDR-Format.'
'en-US' = 'Optional default subnet in CIDR notation.'
}
}
}
DomainAdministratorCredentialName = @{
Type = 'string'
DefaultValue = 'DomainAdministrator'
Required = $true
Sensitive = $true
Metadata = @{
Description = @{
'de-DE' = 'Name der Credential-Referenz fuer den Domaenenadministrator.'
'en-US' = 'Name of the credential reference for the domain administrator.'
}
}
}
SafeModeAdministratorPasswordSecretName = @{
Type = 'string'
DefaultValue = 'SafeModeAdministratorPassword'
Required = $true
Sensitive = $true
Metadata = @{
Description = @{
'de-DE' = 'Name der Secret-Referenz fuer das Safe-Mode-Administrator-Kennwort.'
'en-US' = 'Name of the secret reference for the safe mode administrator password.'
}
}
}
}
Resources = @{
NonNodeData = @{
RequiredModules = @(
@{
Name = 'ActiveDirectoryDsc'
Version = '6.7.1'
}
)
Services = @{
ActiveDirectory = @{
Domain = @{
Ensure = 'Present'
FQDN = "[parameters('DomainFQDN')]"
NetBIOS = "[parameters('DomainNetBIOS')]"
ForestMode = "[parameters('ForestMode')]"
DomainMode = "[parameters('DomainMode')]"
DnsDelegation = $false
Credentials = @{
DomainAdministrator = @{
CredentialName = "[parameters('DomainAdministratorCredentialName')]"
}
SafeModeAdministrator = @{
SecretName = "[parameters('SafeModeAdministratorPasswordSecretName')]"
}
}
}
DomainControllers = @(
@{
NodeName = '*'
Ensure = 'Present'
InstallDns = $true
IsGlobalCatalog = $true
SiteName = "[parameters('DefaultSiteName')]"
}
)
Sites = @(
@{
Name = "[parameters('DefaultSiteName')]"
Ensure = 'Present'
}
)
Subnets = @(
@{
Name = "[parameters('DefaultSubnet')]"
SiteName = "[parameters('DefaultSiteName')]"
Ensure = 'Present'
}
)
OrganizationalUnits = @(
@{
Name = 'Servers'
Path = "[concat('DC=', replace(parameters('DomainFQDN'), '.', ',DC='))]"
Ensure = 'Present'
ProtectedFromAccidentalDeletion = $true
}
@{
Name = 'Service Accounts'
Path = "[concat('DC=', replace(parameters('DomainFQDN'), '.', ',DC='))]"
Ensure = 'Present'
ProtectedFromAccidentalDeletion = $true
}
@{
Name = 'Groups'
Path = "[concat('DC=', replace(parameters('DomainFQDN'), '.', ',DC='))]"
Ensure = 'Present'
ProtectedFromAccidentalDeletion = $true
}
)
Groups = @(
@{
GroupName = 'GG-SharePoint-Admins'
Path = "[concat('OU=Groups,DC=', replace(parameters('DomainFQDN'), '.', ',DC='))]"
Scope = 'Global'
Category = 'Security'
Ensure = 'Present'
Members = @()
}
)
Users = @(
@{
UserName = 'SVC_SHP_Setup'
Path = "[concat('OU=Service Accounts,DC=', replace(parameters('DomainFQDN'), '.', ',DC='))]"
Ensure = 'Present'
Enabled = $true
Password = @{
SecretName = 'SVC_SHP_Setup'
}
}
)
Trusts = @()
Dns = @{
Forwarders = @()
ReverseLookupZones = @()
}
}
}
}
}
}

View File

@@ -0,0 +1,200 @@
@{
Parameters = @{
DatabasePrefix = @{
Type = 'string'
Value = 'SharePoint'
DefaultValue = 'SharePoint'
Metadata = @{
Description = @{
'de-DE' = 'Praefix fuer alle von der SharePoint-Farm angelegten Datenbanken.'
'en-US' = 'Prefix for all databases created by the SharePoint farm.'
}
}
}
ServiceDatabaseSegment = @{
Type = 'string'
DefaultValue = 'Services'
Metadata = @{
Description = @{
'de-DE' = 'Namenssegment fuer SharePoint-Service-Datenbanken innerhalb des Datenbanknamens.'
'en-US' = 'Name segment used for SharePoint service databases within the database name.'
}
}
}
ContentDatabaseSegment = @{
Type = 'string'
DefaultValue = 'Content'
Metadata = @{
Description = @{
'de-DE' = 'Namenssegment fuer SharePoint-Content-Datenbanken innerhalb des Datenbanknamens.'
'en-US' = 'Name segment used for SharePoint content databases within the database name.'
}
}
}
ServiceApplicationPoolDefault = @{
Type = 'string'
DefaultValue = 'SharePoint Service Applications'
Metadata = @{
Description = @{
'de-DE' = 'Anzeigename des Standard-Application-Pools fuer SharePoint-Serviceanwendungen.'
'en-US' = 'Display name of the default application pool for SharePoint service applications.'
}
}
}
ServiceApplicationPoolUserProfileService = @{
Type = 'string'
DefaultValue = 'SharePoint User Profile Services'
Metadata = @{
Description = @{
'de-DE' = 'Anzeigename des Application-Pools fuer den SharePoint User Profile Service.'
'en-US' = 'Display name of the application pool for the SharePoint User Profile Service.'
}
}
}
ServiceApplicationPoolDefaultAccount = @{
Type = 'string'
DefaultValue = 'SVC_SHP_SAP'
Metadata = @{
Description = @{
'de-DE' = 'Kontoname fuer den Standard-Application-Pool der SharePoint-Serviceanwendungen.'
'en-US' = 'Account name used by the default application pool for SharePoint service applications.'
}
}
}
WebApplicationPoolDefault = @{
Type = 'string'
DefaultValue = 'SharePoint Web Applications'
Metadata = @{
Description = @{
'de-DE' = 'Anzeigename des Standard-Application-Pools fuer SharePoint-Webanwendungen.'
'en-US' = 'Display name of the default application pool for SharePoint web applications.'
}
}
}
WebApplicationPoolDefaultAccount = @{
Type = 'string'
DefaultValue = 'SVC_SHP_WAP'
Metadata = @{
Description = @{
'de-DE' = 'Kontoname fuer den Standard-Application-Pool der SharePoint-Webanwendungen.'
'en-US' = 'Account name used by the default application pool for SharePoint web applications.'
}
}
}
DatabaseInstanceName = @{
Type = 'string'
DefaultValue = 'SQL_Server'
Metadata = @{
Description = @{
'de-DE' = 'Standard-SQL-Instanzname fuer SharePoint-Datenbankverbindungen und Aliase.'
'en-US' = 'Default SQL instance name used for SharePoint database connections and aliases.'
}
}
}
}
Variables = @{
ServiceDbPrefix = "[concat(parameters('DatabasePrefix'),'_',parameters('ServiceDatabaseSegment'),'_')]"
ContentDbPrefix = "[concat(parameters('DatabasePrefix'),'_',parameters('ContentDatabaseSegment'),'_')]"
ConfigDbName = "[concat(parameters('DatabasePrefix'),'_','Farm_Config')]"
AdminDbName = "[concat(parameters('DatabasePrefix'),'_','Farm_AdminContent')]"
}
Resources = @{
NonNodeData = @{
Services = @{
SharePoint = @{
General = @{
ProductKey = '0000-0000-0000-0000-0000'
}
Windows = @{
Registry = @{
DisableLoopbackCheck = @{
Path = 'HKLM:\SYSTEM\CurrentControlSet\Control\Lsa'
Name = 'DisableLoopbackCheck'
Type = 'DWord'
Value = 1
}
}
}
Database = @{
SQLAlias = @{
SQLServer = @{
ServerName = ''
InstanceName = "[parameters('DatabaseInstanceName')]"
TcpPort = 0
}
}
}
Farm = @{
Passphrase = 'Use-SecureString-Or-KeyVault'
ConfigDatabaseName = "[variables('ConfigDbName')]"
AdminContentDatabase = "[variables('AdminDbName')]"
CentralAdminPort = 2016
CentralAdminAuth = 'NTLM' # oder Kerberos
ServiceApplicationPools = @{
Default = @{
Name = "[parameters('ServiceApplicationPoolDefault')]"
Account = 'CONTOSO\sp_services'
}
UserProfile = @{
Name = "[parameters('ServiceApplicationPoolUserProfileService')]"
Account = 'CONTOSO\sp_ups'
}
}
ServiceApplications = @{
ManagedMetadataService = @{
Provision = $true
Name = 'Managed Metadata Service'
ApplicationPool = 'SharePoint Service Applications'
DatabaseName = "[concat(variables('ServiceDbPrefix'), 'ManagedMetadata')]"
}
UserProfileService = @{
Provision = $true
Name = 'User Profile Service'
ApplicationPool = 'SharePoint User Profile Services'
ProfileDBName = "[concat(variables('ServiceDbPrefix'), 'UserProfile_ProfileDB')]"
SocialDBName = "[concat(variables('ServiceDbPrefix'), 'UserProfile_SocialDB')]"
SyncDBName = "[concat(variables('ServiceDbPrefix'), 'UserProfile_SyncDB')]"
}
SearchService = @{
Provision = $true
Name = 'Search Service Application'
ApplicationPool = 'SharePoint Service Applications'
DatabaseName = "[concat(variables('ServiceDbPrefix'),'Search')]"
}
StateService = @{
Provision = $true
DatabaseName = "[concat(variables('ServiceDbPrefix'),'StateService')]"
}
UsageAndHealthService = @{
Provision = $true
DatabaseName = "[concat(variables('ServiceDbPrefix'),'UsageAndHealth')]"
}
AppManagementService = @{
Provision = $true
DatabaseName = "[concat(variables('ServiceDbPrefix'),'AppManagement')]"
}
SubscriptionSettingsService = @{
Provision = $true
DatabaseName = "[concat(variables('ServiceDbPrefix'),'SubscriptionSettings')]"
}
SecureStoreService = @{
Provision = $true
Name = 'Secure Store Service'
ApplicationPool = 'SharePoint Service Applications'
DatabaseName = "[concat(variables('ServiceDbPrefix'),'SecureStore')]"
}
}
}
}
}
}
}
}

View File

@@ -1,142 +0,0 @@
@{
Parameters = @{
DatabasePrefix = @{
Type = 'string'
Value = 'SharePoint'
DefaultValue = 'SP'
Metadata = @{
Description = 'Prefix für alle Datenbanknamen'
}
}
ServiceDatabasePrefix = @{
Type = 'string'
DefaultValue = 'Services'
}
ContentDatabasePrefix = @{
Type = 'string'
DefaultValue = 'Content'
}
ServiceApplicationPoolDefault = @{
Type = 'string'
DefaultValue = 'SharePoint Service Applications'
}
ServiceApplicationPoolUserProfileService = @{
Type = 'string'
DefaultValue = 'SharePoint User Profile Services'
}
DatbaseInstanceName = @{
Type = 'string'
DefaultValue = 'mssqlserver'
Metadata = @{
Description = 'Instanz Name für die Standart Instanz'
}
}
}
Variables = @{
ServiceDbPrefix = "[Concat(Parameter('DatabasePrefix'),'_',Parameter('ServiceDatabasePrefix'),'_')]"
ContentDbPrefix = "[Concat(Parameter('DatabasePrefix'),'_',Parameter('ServiceDatabasePrefix'),'_')]"
ConfigDbName = "[Concat(Parameter('DatabasePrefix'),'_','Farm_Config')]"
AdminDbName = "[Concat(Parameter('DatabasePrefix'),'_','Farm_AdminContent')]"
HZDTest = "[Substring(Parameter('DatbaseInstanceName'),0,5)]"
Test = "[ToUpper(Parameter('DatbaseInstanceName'),0,5)]"
}
Resources = @{
NonNodeData = @{
Services = @{
SharePoint = @{
General = @{
ProductKey = '0000-0000-0000-0000-0000'
}
Windows = @{
Registry = @{
DisableLoopbackCheck = @{
Path = 'HKLM:\SYSTEM\CurrentControlSet\Control\Lsa'
Name = 'DisableLoopbackCheck'
Type = 'DWord'
Value = 1
}
}
}
Database = @{
SQLAlias = @{
SQLServer = @{
ServerName = ''
InstanceName = ''
TcpPort = 0
}
}
}
Farm = @{
Passphrase = 'Use-SecureString-Or-KeyVault'
ConfigDatabaseName = "[Variable('ConfigDbName')]"
AdminContentDatabase = "[Variable('AdminDbName')]"
CentralAdminPort = 2016
CentralAdminAuth = 'NTLM' # oder Kerberos
ServiceApplicationPools = @{
Default = @{
Name = "[Parameter('ServiceApplicationPoolDefault')]"
Account = 'CONTOSO\sp_services'
}
UserProfile = @{
Name = "[Parameter('ServiceApplicationPoolUserProfileService')]"
Account = 'CONTOSO\sp_ups'
}
}
ServiceApplications = @{
ManagedMetadataService = @{
Provision = $true
Name = 'Managed Metadata Service'
ApplicationPool = 'SharePoint Service Applications'
DatabaseName = "[Concat(Variable('ServiceDbPrefix'), 'ManagedMetadata')]"
}
UserProfileService = @{
Provision = $true
Name = 'User Profile Service'
ApplicationPool = 'SharePoint User Profile Services'
ProfileDBName = "[Concat(Variable('ServiceDbPrefix'), 'UserProfile_ProfileDB')]"
SocialDBName = "[Concat(Variable('ServiceDbPrefix'), 'UserProfile_SocialDB')]"
SyncDBName = "[Concat(Variable('ServiceDbPrefix'), 'UserProfile_SyncDB')]"
}
SearchService = @{
Provision = $true
Name = 'Search Service Application'
ApplicationPool = 'SharePoint Service Applications'
DatabaseName = "[Concat(Variable('ServiceDbPrefix'),'Search')]"
}
StateService = @{
Provision = $true
DatabaseName = "[Concat(Variable('ServiceDbPrefix'),'StateService')]"
}
UsageAndHealthService = @{
Provision = $true
DatabaseName = "[Concat(Variable('ServiceDbPrefix'),'UsageAndHealth')]"
}
AppManagementService = @{
Provision = $true
DatabaseName = "[Concat(Variable('ServiceDbPrefix'),'AppManagement')]"
}
SubscriptionSettingsService = @{
Provision = $true
DatabaseName = "[Concat(Variable('ServiceDbPrefix'),'SubscriptionSettings')]"
}
SecureStoreService = @{
Provision = $true
Name = 'Secure Store Service'
ApplicationPool = 'SharePoint Service Applications'
DatabaseName = "[Concat(Variable('ServiceDbPrefix'),'SecureStore')]"
}
}
}
}
}
}
}
}