Compare commits
5 Commits
01a535eb39
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6986570510 | ||
|
|
846dccf468 | ||
| 7dd71be14c | |||
| f5dcc022cf | |||
| 5a57021e6a |
3813
Compiler.Core.ps1
Normal file
3813
Compiler.Core.ps1
Normal file
File diff suppressed because it is too large
Load Diff
553
Compiler.ps1
553
Compiler.ps1
@@ -1,3 +1,7 @@
|
|||||||
|
<<<<<<< HEAD
|
||||||
|
$formsType = 'System.Windows.Forms.Form' -as [type]
|
||||||
|
if ($null -eq $formsType) {
|
||||||
|
=======
|
||||||
using namespace System.Windows.Forms
|
using namespace System.Windows.Forms
|
||||||
using namespace System.Drawing
|
using namespace System.Drawing
|
||||||
|
|
||||||
@@ -2923,55 +2927,75 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Concat mit einer dynamischen Anzahl von Argumenten
|
# Concat mit einer dynamischen Anzahl von Argumenten
|
||||||
static [string] Concat([string[]]$input) {
|
static [string] Concat([object[]]$input) {
|
||||||
return $input -join ''
|
return (($input | ForEach-Object { [string]$_ }) -join '')
|
||||||
}
|
}
|
||||||
|
|
||||||
# ToLower-Methode
|
# ToLower-Methode
|
||||||
static [string] ToLower([string[]]$input) {
|
static [string] ToLower([object[]]$input) {
|
||||||
return $input[0].ToLower()
|
if ($input.Count -lt 1) {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return ([string]$input[0]).ToLowerInvariant()
|
||||||
}
|
}
|
||||||
|
|
||||||
# ToUpper-Methode
|
# ToUpper-Methode
|
||||||
static [string] ToUpper([string[]]$input) {
|
static [string] ToUpper([object[]]$input) {
|
||||||
return $input[0].ToUpper()
|
if ($input.Count -lt 1) {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return ([string]$input[0]).ToUpperInvariant()
|
||||||
}
|
}
|
||||||
|
|
||||||
# FirstIndexOf-Methode
|
# FirstIndexOf-Methode
|
||||||
static [string] FirstIndexOf([string[]] $input){
|
static [string] FirstIndexOf([object[]] $input){
|
||||||
return $input[0]
|
if ($input.Count -lt 1) {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return [string]$input[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
# LastIndexOf-Methode
|
# LastIndexOf-Methode
|
||||||
static [string] LastIndexOf([string[]] $input){
|
static [string] LastIndexOf([object[]] $input){
|
||||||
return $input[-1]
|
if ($input.Count -lt 1) {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return [string]$input[-1]
|
||||||
}
|
}
|
||||||
|
|
||||||
# IndexOf-Methode
|
# IndexOf-Methode
|
||||||
static [string] IndexOf([string[]] $input){
|
static [string] IndexOf([object[]] $input){
|
||||||
return $input[$input[-1]]
|
if ($input.Count -lt 2) {
|
||||||
|
throw "IndexOf benötigt mindestens zwei Argumente."
|
||||||
|
}
|
||||||
|
|
||||||
|
return [string]$input[[int]$input[-1]]
|
||||||
}
|
}
|
||||||
|
|
||||||
# Substring-Methode
|
# Substring-Methode
|
||||||
static [String] Substring([string[]] $input){
|
static [String] Substring([object[]] $input){
|
||||||
if($input.Count -eq 2){
|
if($input.Count -eq 2){
|
||||||
$array = $input.Split(',')
|
return ([string]$input[0]).Substring([int]$input[1])
|
||||||
return $array[0].Substring($array[1])
|
|
||||||
|
|
||||||
}elseif($input.Count -eq 3){
|
}elseif($input.Count -eq 3){
|
||||||
$array = $input.Split(',')
|
return ([string]$input[0]).Substring([int]$input[1],[int]$input[2])
|
||||||
return $array[0].Substring($array[1],$array[2])
|
|
||||||
|
|
||||||
}else{
|
}else{
|
||||||
Write-Warning "Zuviele Parameter"
|
throw "Substring erwartet zwei oder drei Argumente."
|
||||||
return $false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Replace-Methode
|
# Replace-Methode
|
||||||
static [String] Replace([string[]] $input){
|
static [String] Replace([object[]] $input){
|
||||||
$array = $input.Split(',')
|
if ($input.Count -lt 3) {
|
||||||
return $array[0].Replace($array[1],$array[2])
|
throw "Replace erwartet drei Argumente."
|
||||||
|
}
|
||||||
|
|
||||||
|
return ([string]$input[0]).Replace([string]$input[1],[string]$input[2])
|
||||||
}
|
}
|
||||||
|
|
||||||
hidden [System.Collections.Specialized.OrderedDictionary] ResolveDeploymentParameterDefaultValues(){
|
hidden [System.Collections.Specialized.OrderedDictionary] ResolveDeploymentParameterDefaultValues(){
|
||||||
@@ -3025,6 +3049,10 @@
|
|||||||
[ref]$errors
|
[ref]$errors
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if ($errors) {
|
||||||
|
throw "Fehler beim Parsen der Datei: $($errors[0].Message)"
|
||||||
|
}
|
||||||
|
|
||||||
$hashtableAst = $ast.Find({
|
$hashtableAst = $ast.Find({
|
||||||
$args[0] -is [System.Management.Automation.Language.HashtableAst]
|
$args[0] -is [System.Management.Automation.Language.HashtableAst]
|
||||||
}, $true)
|
}, $true)
|
||||||
@@ -3038,176 +3066,108 @@
|
|||||||
return $this.Template
|
return $this.Template
|
||||||
}
|
}
|
||||||
|
|
||||||
hidden [System.Collections.Specialized.OrderedDictionary] ConvertToOrderedHashtable($HashtableAst){
|
hidden [System.Collections.Specialized.OrderedDictionary] ConvertToOrderedHashtable([System.Management.Automation.Language.HashtableAst]$HashtableAst){
|
||||||
|
$ordered = New-Object System.Collections.Specialized.OrderedDictionary
|
||||||
|
|
||||||
# Verwende OrderedDictionary statt [ordered]@{}
|
$sortedKvps = $HashtableAst.KeyValuePairs | Sort-Object { $_.Item1.Extent.StartOffset }
|
||||||
$ordered = New-Object System.Collections.Specialized.OrderedDictionary
|
|
||||||
|
|
||||||
# Sortiere KeyValuePairs nach ihrer Position im Quelltext
|
foreach ($kvp in $sortedKvps) {
|
||||||
$sortedKvps = $HashtableAst.KeyValuePairs | Sort-Object { $_.Item1.Extent.StartOffset }
|
$key = [string]$this.ConvertAstValue($kvp.Item1)
|
||||||
|
$value = $this.ConvertAstValue($kvp.Item2)
|
||||||
|
$ordered.Add($key, $value)
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($kvp in $sortedKvps) {
|
return $ordered
|
||||||
# Schlüssel extrahieren
|
}
|
||||||
$key = $kvp.Item1.Extent.Text -replace '[''"]', ''
|
|
||||||
|
|
||||||
# Wert verarbeiten
|
hidden [System.Object] ConvertAstValue([System.Management.Automation.Language.Ast]$Ast) {
|
||||||
$valueAst = $kvp.Item2
|
if ($null -eq $Ast) {
|
||||||
|
return $null
|
||||||
|
}
|
||||||
|
|
||||||
# Suche nach HashtableAst in PipelineAst
|
if ($Ast -is [System.Management.Automation.Language.PipelineAst]) {
|
||||||
$hashtable = $null
|
if ($Ast.PipelineElements.Count -eq 1 -and $Ast.PipelineElements[0] -is [System.Management.Automation.Language.CommandExpressionAst]) {
|
||||||
if ($valueAst -is [System.Management.Automation.Language.HashtableAst]) {
|
return $this.ConvertAstValue($Ast.PipelineElements[0].Expression)
|
||||||
$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 = $this.ConvertToOrderedHashtable($hashtable)
|
|
||||||
}
|
|
||||||
elseif ($valueAst -is [System.Management.Automation.Language.ArrayLiteralAst]) {
|
|
||||||
$value = @()
|
|
||||||
foreach ($element in $valueAst.Elements) {
|
|
||||||
if ($element -is [System.Management.Automation.Language.HashtableAst]) {
|
|
||||||
$value += $this.ConvertToOrderedHashtable($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
|
return $Ast.SafeGetValue()
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($Ast -is [System.Management.Automation.Language.CommandExpressionAst]) {
|
||||||
|
return $this.ConvertAstValue($Ast.Expression)
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($Ast -is [System.Management.Automation.Language.ParenExpressionAst]) {
|
||||||
|
return $this.ConvertAstValue($Ast.Pipeline)
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($Ast -is [System.Management.Automation.Language.ArrayExpressionAst]) {
|
||||||
|
return $this.ConvertAstValue($Ast.SubExpression)
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($Ast -is [System.Management.Automation.Language.StatementBlockAst]) {
|
||||||
|
if ($Ast.Statements.Count -eq 1 -and $Ast.Statements[0] -is [System.Management.Automation.Language.PipelineAst]) {
|
||||||
|
return $this.ConvertAstValue($Ast.Statements[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
throw "Nicht unterstützter Ausdruck in PSD1-Datei: $($Ast.Extent.Text)"
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($Ast -is [System.Management.Automation.Language.ArrayLiteralAst]) {
|
||||||
|
$result = @()
|
||||||
|
foreach ($element in $Ast.Elements) {
|
||||||
|
$result += $this.ConvertAstValue($element)
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($Ast -is [System.Management.Automation.Language.HashtableAst]) {
|
||||||
|
return $this.ConvertToOrderedHashtable($Ast)
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($Ast -is [System.Management.Automation.Language.VariableExpressionAst]) {
|
||||||
|
switch ($Ast.VariablePath.UserPath) {
|
||||||
|
'true' { return $true }
|
||||||
|
'false' { return $false }
|
||||||
|
'null' { return $null }
|
||||||
|
default { return $Ast.Extent.Text }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return $Ast.SafeGetValue()
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
return $Ast.Extent.Text
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hidden [System.Object] ResolveValue($Value, $Parameters, $Variables){
|
hidden [System.Object] ResolveValue($Value, $Parameters, $Variables){
|
||||||
|
$resolutionStack = [System.Collections.Generic.List[string]]::new()
|
||||||
|
return $this.ResolveValueInternal($Value, $Parameters, $Variables, $resolutionStack)
|
||||||
|
}
|
||||||
|
|
||||||
|
hidden [System.Object] ResolveValueInternal($Value, $Parameters, $Variables, [System.Collections.Generic.List[string]]$ResolutionStack){
|
||||||
if ($Value -is [string]) {
|
if ($Value -is [string]) {
|
||||||
# Resolve Parameter-Referenzen: [Parameter('name')]
|
$trimmedValue = $Value.Trim()
|
||||||
while ($Value -match "\[Parameter\('([^']*)'\)\]") {
|
if ($this.IsTemplateExpression($trimmedValue)) {
|
||||||
$paramName = $matches[1]
|
return $this.EvaluateTemplateExpression($trimmedValue.Substring(1, $trimmedValue.Length - 2), $Parameters, $Variables, $ResolutionStack)
|
||||||
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')]
|
return $this.ResolveInlineTemplateExpressions($Value, $Parameters, $Variables, $ResolutionStack)
|
||||||
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]) {
|
elseif ($Value -is [System.Collections.IDictionary]) {
|
||||||
$resolved = New-Object System.Collections.Specialized.OrderedDictionary
|
$resolved = New-Object System.Collections.Specialized.OrderedDictionary
|
||||||
foreach ($key in $Value.Keys) {
|
foreach ($key in $Value.Keys) {
|
||||||
$resolved[$key] = $this.ResolveValue($Value[$key],$Parameters,$Variables)
|
$resolved[$key] = $this.ResolveValueInternal($Value[$key], $Parameters, $Variables, $ResolutionStack)
|
||||||
}
|
}
|
||||||
return $resolved
|
return $resolved
|
||||||
}
|
}
|
||||||
elseif ($Value -is [array]) {
|
elseif ($Value -is [array]) {
|
||||||
$resolved = @()
|
$resolved = @()
|
||||||
foreach ($item in $Value) {
|
foreach ($item in $Value) {
|
||||||
$resolved += $this.ResolveValue($item,$Parameters,$Variables)
|
$resolved += $this.ResolveValueInternal($item, $Parameters, $Variables, $ResolutionStack)
|
||||||
}
|
}
|
||||||
return $resolved
|
return $resolved
|
||||||
}
|
}
|
||||||
@@ -3215,6 +3175,229 @@
|
|||||||
return $Value
|
return $Value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hidden [bool] IsTemplateExpression([string]$Value) {
|
||||||
|
if ([string]::IsNullOrWhiteSpace($Value)) {
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-not ($Value.StartsWith('[') -and $Value.EndsWith(']'))) {
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this.IsFunctionInvocation($Value.Substring(1, $Value.Length - 2))
|
||||||
|
}
|
||||||
|
|
||||||
|
hidden [bool] IsFunctionInvocation([string]$Value) {
|
||||||
|
return $Value.Trim() -match '^[A-Za-z_][A-Za-z0-9_]*\s*\(.*\)$'
|
||||||
|
}
|
||||||
|
|
||||||
|
hidden [string] ResolveInlineTemplateExpressions([string]$Value, $Parameters, $Variables, [System.Collections.Generic.List[string]]$ResolutionStack) {
|
||||||
|
$resolved = $Value
|
||||||
|
$matches = [regex]::Matches($Value, '\[[^\[\]]+\]')
|
||||||
|
|
||||||
|
for ($i = $matches.Count - 1; $i -ge 0; $i--) {
|
||||||
|
$match = $matches[$i]
|
||||||
|
$expressionText = $match.Value.Substring(1, $match.Value.Length - 2)
|
||||||
|
if (-not $this.IsFunctionInvocation($expressionText)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
$replacement = $this.EvaluateTemplateExpression($expressionText, $Parameters, $Variables, $ResolutionStack)
|
||||||
|
$resolved = $resolved.Remove($match.Index, $match.Length).Insert($match.Index, [string]$replacement)
|
||||||
|
}
|
||||||
|
|
||||||
|
return $resolved
|
||||||
|
}
|
||||||
|
|
||||||
|
hidden [System.Object] EvaluateTemplateExpression([string]$ExpressionText, $Parameters, $Variables, [System.Collections.Generic.List[string]]$ResolutionStack) {
|
||||||
|
$trimmedExpression = $ExpressionText.Trim()
|
||||||
|
if ($trimmedExpression -notmatch '^([A-Za-z_][A-Za-z0-9_]*)\s*\((.*)\)$') {
|
||||||
|
return $ExpressionText
|
||||||
|
}
|
||||||
|
|
||||||
|
$functionName = $matches[1]
|
||||||
|
$argumentsText = $matches[2]
|
||||||
|
$resolvedArguments = @()
|
||||||
|
$result = $null
|
||||||
|
|
||||||
|
foreach ($argument in $this.SplitExpressionArguments($argumentsText)) {
|
||||||
|
$resolvedArguments += ,($this.ResolveExpressionToken($argument, $Parameters, $Variables, $ResolutionStack))
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ($functionName.ToLowerInvariant()) {
|
||||||
|
'parameter' { $result = $this.GetParameterValue([string]$resolvedArguments[0], $Parameters); break }
|
||||||
|
'parameters' { $result = $this.GetParameterValue([string]$resolvedArguments[0], $Parameters); break }
|
||||||
|
'variable' { $result = $this.GetVariableValue([string]$resolvedArguments[0], $Parameters, $Variables, $ResolutionStack); break }
|
||||||
|
'variables' { $result = $this.GetVariableValue([string]$resolvedArguments[0], $Parameters, $Variables, $ResolutionStack); break }
|
||||||
|
'concat' { $result = [TemplateBuilder]::Concat($resolvedArguments); break }
|
||||||
|
'tolower' { $result = [TemplateBuilder]::ToLower($resolvedArguments); break }
|
||||||
|
'toupper' { $result = [TemplateBuilder]::ToUpper($resolvedArguments); break }
|
||||||
|
'firstindexof' { $result = [TemplateBuilder]::FirstIndexOf($resolvedArguments); break }
|
||||||
|
'lastindexof' { $result = [TemplateBuilder]::LastIndexOf($resolvedArguments); break }
|
||||||
|
'indexof' { $result = [TemplateBuilder]::IndexOf($resolvedArguments); break }
|
||||||
|
'substring' { $result = [TemplateBuilder]::Substring($resolvedArguments); break }
|
||||||
|
'replace' { $result = [TemplateBuilder]::Replace($resolvedArguments); break }
|
||||||
|
default {
|
||||||
|
throw "Nicht unterstützte Template-Funktion '$functionName'"
|
||||||
|
return $null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result
|
||||||
|
}
|
||||||
|
|
||||||
|
hidden [string[]] SplitExpressionArguments([string]$ArgumentsText) {
|
||||||
|
$arguments = New-Object 'System.Collections.Generic.List[string]'
|
||||||
|
if ([string]::IsNullOrWhiteSpace($ArgumentsText)) {
|
||||||
|
return $arguments.ToArray()
|
||||||
|
}
|
||||||
|
|
||||||
|
$builder = New-Object System.Text.StringBuilder
|
||||||
|
$depth = 0
|
||||||
|
$inSingleQuote = $false
|
||||||
|
$inDoubleQuote = $false
|
||||||
|
|
||||||
|
for ($i = 0; $i -lt $ArgumentsText.Length; $i++) {
|
||||||
|
$char = $ArgumentsText[$i]
|
||||||
|
|
||||||
|
if ($char -eq "'" -and -not $inDoubleQuote) {
|
||||||
|
[void]$builder.Append($char)
|
||||||
|
if ($inSingleQuote -and $i + 1 -lt $ArgumentsText.Length -and $ArgumentsText[$i + 1] -eq "'") {
|
||||||
|
$i++
|
||||||
|
[void]$builder.Append($ArgumentsText[$i])
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
$inSingleQuote = -not $inSingleQuote
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($char -eq '"' -and -not $inSingleQuote) {
|
||||||
|
$inDoubleQuote = -not $inDoubleQuote
|
||||||
|
[void]$builder.Append($char)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-not $inSingleQuote -and -not $inDoubleQuote) {
|
||||||
|
if ($char -eq '(') {
|
||||||
|
$depth++
|
||||||
|
}
|
||||||
|
elseif ($char -eq ')') {
|
||||||
|
$depth--
|
||||||
|
}
|
||||||
|
elseif ($char -eq ',' -and $depth -eq 0) {
|
||||||
|
$arguments.Add($builder.ToString().Trim())
|
||||||
|
[void]$builder.Clear()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[void]$builder.Append($char)
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($builder.Length -gt 0 -or $ArgumentsText.Trim().Length -gt 0) {
|
||||||
|
$arguments.Add($builder.ToString().Trim())
|
||||||
|
}
|
||||||
|
|
||||||
|
return $arguments.ToArray()
|
||||||
|
}
|
||||||
|
|
||||||
|
hidden [System.Object] ResolveExpressionToken([string]$Token, $Parameters, $Variables, [System.Collections.Generic.List[string]]$ResolutionStack) {
|
||||||
|
$trimmedToken = $Token.Trim()
|
||||||
|
if ([string]::IsNullOrWhiteSpace($trimmedToken)) {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this.IsTemplateExpression($trimmedToken)) {
|
||||||
|
return $this.EvaluateTemplateExpression($trimmedToken.Substring(1, $trimmedToken.Length - 2), $Parameters, $Variables, $ResolutionStack)
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this.IsFunctionInvocation($trimmedToken)) {
|
||||||
|
return $this.EvaluateTemplateExpression($trimmedToken, $Parameters, $Variables, $ResolutionStack)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (($trimmedToken.StartsWith("'") -and $trimmedToken.EndsWith("'")) -or ($trimmedToken.StartsWith('"') -and $trimmedToken.EndsWith('"'))) {
|
||||||
|
return $this.UnquoteString($trimmedToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($trimmedToken -match '^\$?true$') {
|
||||||
|
return $true
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($trimmedToken -match '^\$?false$') {
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($trimmedToken -match '^\$?null$') {
|
||||||
|
return $null
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($trimmedToken -match '^-?\d+$') {
|
||||||
|
return [int]$trimmedToken
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($trimmedToken -match '^-?\d+\.\d+$') {
|
||||||
|
return [double]$trimmedToken
|
||||||
|
}
|
||||||
|
|
||||||
|
return $trimmedToken
|
||||||
|
}
|
||||||
|
|
||||||
|
hidden [string] UnquoteString([string]$Value) {
|
||||||
|
if ($Value.StartsWith("'") -and $Value.EndsWith("'")) {
|
||||||
|
return ($Value.Substring(1, $Value.Length - 2) -replace "''", "'")
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($Value.StartsWith('"') -and $Value.EndsWith('"')) {
|
||||||
|
return $Value.Substring(1, $Value.Length - 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
return $Value
|
||||||
|
}
|
||||||
|
|
||||||
|
hidden [System.Object] GetParameterValue([string]$ParameterName, $Parameters) {
|
||||||
|
if ($null -eq $Parameters -or -not $Parameters.Contains($ParameterName)) {
|
||||||
|
throw "Parameter '$ParameterName' nicht gefunden"
|
||||||
|
}
|
||||||
|
|
||||||
|
$parameter = $Parameters[$ParameterName]
|
||||||
|
if ($parameter -is [System.Collections.IDictionary]) {
|
||||||
|
if ($parameter.Contains('Value') -and $null -ne $parameter.Value) {
|
||||||
|
return $parameter.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($parameter.Contains('DefaultValue')) {
|
||||||
|
return $parameter.DefaultValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $parameter
|
||||||
|
}
|
||||||
|
|
||||||
|
hidden [System.Object] GetVariableValue([string]$VariableName, $Parameters, $Variables, [System.Collections.Generic.List[string]]$ResolutionStack) {
|
||||||
|
if ($null -eq $Variables -or -not $Variables.Contains($VariableName)) {
|
||||||
|
throw "Variable '$VariableName' nicht gefunden"
|
||||||
|
return $null
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($ResolutionStack.Contains($VariableName)) {
|
||||||
|
$cycle = @($ResolutionStack.ToArray()) + $VariableName
|
||||||
|
throw "Zirkuläre Variablenreferenz erkannt: $($cycle -join ' -> ')"
|
||||||
|
return $null
|
||||||
|
}
|
||||||
|
|
||||||
|
$ResolutionStack.Add($VariableName)
|
||||||
|
$resolvedValue = $null
|
||||||
|
try {
|
||||||
|
$resolvedValue = $this.ResolveValueInternal($Variables[$VariableName], $Parameters, $Variables, $ResolutionStack)
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
[void]$ResolutionStack.Remove($VariableName)
|
||||||
|
}
|
||||||
|
|
||||||
|
return $resolvedValue
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TabControlBuilder : BaseComponent{
|
class TabControlBuilder : BaseComponent{
|
||||||
@@ -3325,26 +3508,27 @@
|
|||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
>>>>>>> 7dd71be14c5216e6f7f99d006643ed1139a69376
|
||||||
Add-Type -AssemblyName System.Windows.Forms
|
Add-Type -AssemblyName System.Windows.Forms
|
||||||
|
}
|
||||||
|
|
||||||
|
$drawingType = 'System.Drawing.Color' -as [type]
|
||||||
|
if ($null -eq $drawingType) {
|
||||||
Add-Type -AssemblyName System.Drawing
|
Add-Type -AssemblyName System.Drawing
|
||||||
|
}
|
||||||
|
|
||||||
$settingsManager = [SettingsManager]::new("DSC Tool")
|
if ([System.Threading.Thread]::CurrentThread.GetApartmentState() -ne [System.Threading.ApartmentState]::STA) {
|
||||||
|
$powershell = (Get-Command powershell.exe -ErrorAction SilentlyContinue).Source
|
||||||
# Verwendung
|
if ($powershell) {
|
||||||
$logManager = [LogManager]::new("DSC Tool")
|
& $powershell -NoProfile -ExecutionPolicy Bypass -STA -File $PSCommandPath @args
|
||||||
$logManager.Info("Anwendung gestartet")
|
exit $LASTEXITCODE
|
||||||
|
|
||||||
[BaseComponent]::InitializeShared($settingsManager, $logManager)
|
|
||||||
|
|
||||||
foreach($function in $(Get-ChildItem -Path $settingsManager.Get("FunctionsPath") -Recurse -Filter "*.ps1" -File)){
|
|
||||||
$logManager.Info("Lade Funktion: $($function.FullName)")
|
|
||||||
try{
|
|
||||||
. $function.FullName
|
|
||||||
}catch{
|
|
||||||
$logManager.Error("Fehler beim Laden: $_")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
|
$coreScript = Join-Path -Path $PSScriptRoot -ChildPath 'Compiler.Core.ps1'
|
||||||
|
& $coreScript @args
|
||||||
|
=======
|
||||||
$stateManager = [StateManager]::new()
|
$stateManager = [StateManager]::new()
|
||||||
$stateManager.SetStates(@{
|
$stateManager.SetStates(@{
|
||||||
hasSelection = $false
|
hasSelection = $false
|
||||||
@@ -3812,3 +3996,4 @@
|
|||||||
$stateManager.UpdateAllButtons()
|
$stateManager.UpdateAllButtons()
|
||||||
|
|
||||||
$form.Show()
|
$form.Show()
|
||||||
|
>>>>>>> 7dd71be14c5216e6f7f99d006643ed1139a69376
|
||||||
|
|||||||
@@ -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'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
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
|
|
||||||
}
|
|
||||||
@@ -10,10 +10,11 @@ function Merge-Templates {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
try {
|
try {
|
||||||
$TemplateData = Import-OrderedPowerShellDataFile -Path $file -ErrorAction Stop
|
$TemplateData = [TemplateBuilder]::new($file).Template
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
$Errors += "Datei konnte nicht importiert werden"
|
$Errors += "Datei konnte nicht importiert werden"
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
$ConfigurationData = Merge-ConfigurationData -Template $ConfigurationData -Deployment $TemplateData
|
$ConfigurationData = Merge-ConfigurationData -Template $ConfigurationData -Deployment $TemplateData
|
||||||
|
|||||||
185
README.md
Normal file
185
README.md
Normal file
@@ -0,0 +1,185 @@
|
|||||||
|
# DSC Configuration Compiler
|
||||||
|
|
||||||
|
Ein WinForms-basiertes PowerShell-Tool zum Laden, Kombinieren, Anzeigen und Exportieren von DSC-nahen Konfigurationen auf Basis von `psd1`-Dateien.
|
||||||
|
|
||||||
|
Der Fokus des Projekts liegt auf einem einfachen Template-Workflow:
|
||||||
|
|
||||||
|
- Templates aus Ordnern laden
|
||||||
|
- mehrere Templates zu einer Zielkonfiguration zusammenfuehren
|
||||||
|
- Parameter und Variablen aufloesen
|
||||||
|
- die resultierende Struktur im TreeView pruefen
|
||||||
|
- die zusammengefuehrte Konfiguration wieder als `psd1` exportieren
|
||||||
|
|
||||||
|
## Voraussetzungen
|
||||||
|
|
||||||
|
- Windows
|
||||||
|
- PowerShell mit WinForms-Unterstuetzung
|
||||||
|
- Schreibzugriff auf `%APPDATA%`
|
||||||
|
|
||||||
|
Das Tool speichert Einstellungen und Logs unterhalb von `%APPDATA%\DSC Tool`.
|
||||||
|
|
||||||
|
## Start
|
||||||
|
|
||||||
|
Das Projekt kann direkt ueber `Compiler.ps1` gestartet werden:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
powershell -ExecutionPolicy Bypass -File .\Compiler.ps1
|
||||||
|
```
|
||||||
|
|
||||||
|
Alternativ:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
pwsh -File .\Compiler.ps1
|
||||||
|
```
|
||||||
|
|
||||||
|
## Projektstruktur
|
||||||
|
|
||||||
|
```text
|
||||||
|
.
|
||||||
|
|-- Compiler.ps1
|
||||||
|
|-- Functions/
|
||||||
|
|-- Templates/
|
||||||
|
`-- Deployments/
|
||||||
|
```
|
||||||
|
|
||||||
|
- `Compiler.ps1`: Hauptanwendung, UI, Parser- und Resolver-Logik
|
||||||
|
- `Functions/`: zusaetzliche Funktionen fuer Import, Export, Merge und UI-Aktualisierung
|
||||||
|
- `Templates/`: wiederverwendbare Konfigurationsbausteine
|
||||||
|
- `Deployments/`: exportierte oder vorbereitete Zielkonfigurationen
|
||||||
|
|
||||||
|
## Bedienung
|
||||||
|
|
||||||
|
1. Anwendung starten.
|
||||||
|
2. Falls noetig ueber `Einstellungen -> Ordner waehlen...` den Root-Ordner setzen.
|
||||||
|
3. Templates aus den Kategorien laden.
|
||||||
|
4. Gewuenschte Templates per Doppelklick zur Auswahl hinzufuegen.
|
||||||
|
5. Die Auswahl zusammenfuehren.
|
||||||
|
6. Das Ergebnis im TreeView pruefen.
|
||||||
|
7. Die zusammengefuehrte Konfiguration als `psd1` exportieren.
|
||||||
|
|
||||||
|
Import und Export werden ueber den Deployment-Ordner abgewickelt.
|
||||||
|
|
||||||
|
## Template-Modell
|
||||||
|
|
||||||
|
Templates bestehen aus drei optionalen Hauptbereichen:
|
||||||
|
|
||||||
|
- `Parameters`
|
||||||
|
- `Variables`
|
||||||
|
- `Resources`
|
||||||
|
|
||||||
|
Ein vereinfachtes Beispiel:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
@{
|
||||||
|
Parameters = @{
|
||||||
|
DatabasePrefix = @{
|
||||||
|
Type = 'string'
|
||||||
|
DefaultValue = 'SP'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Variables = @{
|
||||||
|
ConfigDbName = "[concat(parameters('DatabasePrefix'),'_','Farm_Config')]"
|
||||||
|
}
|
||||||
|
|
||||||
|
Resources = @{
|
||||||
|
NonNodeData = @{
|
||||||
|
Services = @{
|
||||||
|
Example = @{
|
||||||
|
DatabaseName = "[variables('ConfigDbName')]"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ausdruckssyntax
|
||||||
|
|
||||||
|
Die Auswertung ist ARM-inspiriert. Template-Ausdruecke stehen in eckigen Klammern:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
"[concat(parameters('Prefix'),'_','Database')]"
|
||||||
|
```
|
||||||
|
|
||||||
|
Unterstuetzte Referenzen:
|
||||||
|
|
||||||
|
- `parameters('Name')`
|
||||||
|
- `variables('Name')`
|
||||||
|
|
||||||
|
Zusaetzlich werden aus Rueckwaertskompatibilitaet auch diese Varianten verstanden:
|
||||||
|
|
||||||
|
- `Parameter('Name')`
|
||||||
|
- `Variable('Name')`
|
||||||
|
|
||||||
|
Unterstuetzte Funktionen:
|
||||||
|
|
||||||
|
- `concat(...)`
|
||||||
|
- `toLower(...)`
|
||||||
|
- `toUpper(...)`
|
||||||
|
- `substring(...)`
|
||||||
|
- `replace(...)`
|
||||||
|
- `indexOf(...)`
|
||||||
|
- `firstIndexOf(...)`
|
||||||
|
- `lastIndexOf(...)`
|
||||||
|
|
||||||
|
Funktionsnamen werden ohne freie PowerShell-Ausfuehrung ausgewertet. Die `psd1`-Dateien werden als Daten geparst, nicht als beliebiger Script-Code interpretiert.
|
||||||
|
|
||||||
|
## Aufloesungsreihenfolge
|
||||||
|
|
||||||
|
Die Aufloesung erfolgt in dieser Reihenfolge:
|
||||||
|
|
||||||
|
1. Parameterwerte und Defaultwerte
|
||||||
|
2. Variablen
|
||||||
|
3. Ressourcenwerte
|
||||||
|
|
||||||
|
Zirkulaere Variablenreferenzen werden erkannt und als Fehler behandelt.
|
||||||
|
|
||||||
|
## Merge-Verhalten
|
||||||
|
|
||||||
|
Beim Zusammenfuehren mehrerer Templates werden vorhandene Eintraege rekursiv kombiniert:
|
||||||
|
|
||||||
|
- Hashtables werden rekursiv gemerged
|
||||||
|
- Arrays werden anhand passender Name-Felder zusammengefuehrt
|
||||||
|
- fehlende Werte aus Templates werden in das Ergebnis uebernommen
|
||||||
|
|
||||||
|
Die finale Anzeige im TreeView basiert auf dem zusammengefuehrten und bereits aufgeloesten Modell.
|
||||||
|
|
||||||
|
## Export
|
||||||
|
|
||||||
|
Der Export schreibt die aktuelle TreeView-Struktur wieder in eine `psd1`-Datei.
|
||||||
|
|
||||||
|
Standardziel beim Speichern ist:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Deployments\merged_config.psd1
|
||||||
|
```
|
||||||
|
|
||||||
|
## Hinweise
|
||||||
|
|
||||||
|
- Einstellungen werden benutzerbezogen gespeichert.
|
||||||
|
- Logs werden pro Tag unter `%APPDATA%\DSC Tool\Logs` geschrieben.
|
||||||
|
- Templates sollten deklarativ bleiben und nur Daten plus Template-Ausdruecke enthalten.
|
||||||
|
- Fuer neue Templates wird die ARM-aehnliche Syntax mit `parameters()` und `variables()` empfohlen.
|
||||||
|
|
||||||
|
## Beispielinhalt
|
||||||
|
|
||||||
|
Im Repository ist bereits ein groesseres Beispiel enthalten:
|
||||||
|
|
||||||
|
- `Templates\Service\SharePointServer.psd1`
|
||||||
|
|
||||||
|
Dieses Template zeigt die Verwendung von:
|
||||||
|
|
||||||
|
- Parametern
|
||||||
|
- Variablen
|
||||||
|
- verschachtelten Ressourcen
|
||||||
|
- String-Funktionen wie `concat()` und `substring()`
|
||||||
|
|
||||||
|
## Weiterentwicklung
|
||||||
|
|
||||||
|
Sinnvolle naechste Schritte fuer das Projekt sind:
|
||||||
|
|
||||||
|
- Tests fuer Parser, Resolver und Merge-Verhalten
|
||||||
|
- typsicherer Export-Roundtrip
|
||||||
|
- robustere Initialisierung der Pfade und Settings
|
||||||
|
- weitere Template-Funktionen nach Bedarf
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
@{
|
|
||||||
Resources = @{
|
|
||||||
NonNodeData = @{
|
|
||||||
Services = @{
|
|
||||||
ActiveDirectory = @{
|
|
||||||
Domain = @{
|
|
||||||
FQDN = "contoso.local"
|
|
||||||
NetBIOS = "Contoso"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
161
Templates/Environment/Environment.Default.psd1
Normal file
161
Templates/Environment/Environment.Default.psd1
Normal file
@@ -0,0 +1,161 @@
|
|||||||
|
@{
|
||||||
|
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.'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 = @()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
200
Templates/Service/SharePointServer.Default.psd1
Normal file
200
Templates/Service/SharePointServer.Default.psd1
Normal 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')]"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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')]"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user