Compare commits

..

2 Commits

7 changed files with 734 additions and 28 deletions

View File

@@ -0,0 +1,512 @@
$script:ModuleRoot = Split-Path -Path $PSScriptRoot -Parent
Import-Module (Join-Path -Path $script:ModuleRoot -ChildPath "Resolve-DSCConfigurationData.psd1") -Force
Describe "Resolve-DSCConfigurationData" {
It "resolves parameters using Value before DefaultValue" {
$ConfigurationData = @{
Parameters = @{
Name = @{
DefaultValue = "Default"
Value = "Deployment"
}
}
Resources = @{
Value = "[parameters('Name')]"
}
}
$Result = Resolve-DSCConfigurationData -ConfigurationData $ConfigurationData
$Result.Resources.Value | Should Be "Deployment"
}
It "allows parameter values listed in AllowedValues" {
$ConfigurationData = @{
Parameters = @{
Stage = @{
Value = "Test"
AllowedValues = @(
"Install",
"Test",
"Release"
)
}
}
Resources = @{
Stage = "[parameters('Stage')]"
}
}
$Result = Resolve-DSCConfigurationData -ConfigurationData $ConfigurationData
$Result.Resources.Stage | Should Be "Test"
}
It "validates DefaultValue against AllowedValues when Value is not set" {
$ConfigurationData = @{
Parameters = @{
Stage = @{
DefaultValue = "Release"
AllowedValues = @(
"Install",
"Test",
"Release"
)
}
}
Resources = @{
Stage = "[parameters('Stage')]"
}
}
$Result = Resolve-DSCConfigurationData -ConfigurationData $ConfigurationData
$Result.Resources.Stage | Should Be "Release"
}
It "throws when a parameter value is not listed in AllowedValues" {
$ConfigurationData = @{
Parameters = @{
Stage = @{
Value = "Production"
AllowedValues = @(
"Install",
"Test",
"Release"
)
}
}
Resources = @{
Stage = "[parameters('Stage')]"
}
}
{ Resolve-DSCConfigurationData -ConfigurationData $ConfigurationData } | Should Throw
}
It "validates array parameter items against AllowedValues" {
$ConfigurationData = @{
Parameters = @{
ServerRoles = @{
Type = "array"
Value = @(
"WebFrontEnd",
"Application"
)
AllowedValues = @(
"WebFrontEnd",
"Application",
"Search"
)
}
}
Resources = @{
Roles = "[parameters('ServerRoles')]"
}
}
$Result = Resolve-DSCConfigurationData -ConfigurationData $ConfigurationData
$Result.Resources.Roles[0] | Should Be "WebFrontEnd"
$Result.Resources.Roles[1] | Should Be "Application"
}
It "throws when an array parameter item is not listed in AllowedValues" {
$ConfigurationData = @{
Parameters = @{
ServerRoles = @{
Type = "array"
Value = @(
"WebFrontEnd",
"InvalidRole"
)
AllowedValues = @(
"WebFrontEnd",
"Application",
"Search"
)
}
}
}
{ Resolve-DSCConfigurationData -ConfigurationData $ConfigurationData } | Should Throw
}
It "validates required parameters" {
$ConfigurationData = @{
Parameters = @{
DatabasePrefix = @{
Type = "string"
Required = $true
}
}
}
{ Resolve-DSCConfigurationData -ConfigurationData $ConfigurationData } | Should Throw
}
It "validates parameter length constraints" {
$ConfigurationData = @{
Parameters = @{
DatabasePrefix = @{
Value = "S"
MinLength = 2
MaxLength = 10
}
}
}
{ Resolve-DSCConfigurationData -ConfigurationData $ConfigurationData } | Should Throw
}
It "validates parameter patterns" {
$ConfigurationData = @{
Parameters = @{
DatabasePrefix = @{
Value = "Share Point"
Pattern = "^[A-Za-z][A-Za-z0-9_-]*$"
}
}
}
{ Resolve-DSCConfigurationData -ConfigurationData $ConfigurationData } | Should Throw
}
It "validates supported parameter types" {
$ConfigurationData = @{
Parameters = @{
Name = @{
Type = "string"
Value = "SharePoint"
}
Port = @{
Type = "int"
Value = 1433
}
Enabled = @{
Type = "bool"
Value = $true
}
Roles = @{
Type = "array"
Value = @(
"WebFrontEnd",
"Application"
)
}
SecretReference = @{
Type = "secureString"
Value = @{
SecretName = "SharePointFarmPassphrase"
}
Sensitive = $true
}
CredentialReference = @{
Type = "credential"
Value = @{
CredentialName = "SharePointSetup"
}
Sensitive = $true
}
}
Resources = @{
Name = "[parameters('Name')]"
Port = "[parameters('Port')]"
Enabled = "[parameters('Enabled')]"
RoleCount = "[length(parameters('Roles'))]"
}
}
$Result = Resolve-DSCConfigurationData -ConfigurationData $ConfigurationData
$Result.Resources.Name | Should Be "SharePoint"
$Result.Resources.Port | Should Be 1433
$Result.Resources.Enabled | Should Be $true
$Result.Resources.RoleCount | Should Be 2
}
It "throws when parameter type validation fails" {
$ConfigurationData = @{
Parameters = @{
Port = @{
Type = "int"
Value = "1433"
}
}
}
{ Resolve-DSCConfigurationData -ConfigurationData $ConfigurationData } | Should Throw
}
It "validates numeric ranges" {
$ConfigurationData = @{
Parameters = @{
Port = @{
Type = "int"
Value = 1433
MinValue = 1
MaxValue = 65535
}
}
Resources = @{
Port = "[parameters('Port')]"
}
}
$Result = Resolve-DSCConfigurationData -ConfigurationData $ConfigurationData
$Result.Resources.Port | Should Be 1433
}
It "throws when numeric range validation fails" {
$ConfigurationData = @{
Parameters = @{
Port = @{
Type = "int"
Value = 70000
MinValue = 1
MaxValue = 65535
}
}
}
{ Resolve-DSCConfigurationData -ConfigurationData $ConfigurationData } | Should Throw
}
It "supports localized deprecated parameter messages" {
$ConfigurationData = @{
Parameters = @{
OldDatabasePrefix = @{
Value = "SharePoint"
Deprecated = @{
Message = @{
"de-DE" = "Der Parameter [OldDatabasePrefix] ist veraltet. Verwende [DatabasePrefix]."
"en-US" = "Parameter [OldDatabasePrefix] is deprecated. Use [DatabasePrefix]."
}
}
}
}
Resources = @{
Value = "[parameters('OldDatabasePrefix')]"
}
}
$Warnings = @()
$Result = Resolve-DSCConfigurationData -ConfigurationData $ConfigurationData -WarningVariable Warnings 3>$null
$Result.Resources.Value | Should Be "SharePoint"
$Warnings.Count | Should Be 1
([string]$Warnings[0]) | Should Match "OldDatabasePrefix"
}
It "resolves variables that reference parameters" {
$ConfigurationData = @{
Parameters = @{
Prefix = @{
Value = "SharePoint"
}
}
Variables = @{
ConfigDbName = "[concat(parameters('Prefix'), '_Farm_Config')]"
}
Resources = @{
DatabaseName = "[variables('ConfigDbName')]"
}
}
$Result = Resolve-DSCConfigurationData -ConfigurationData $ConfigurationData
$Result.Variables.ConfigDbName | Should Be "SharePoint_Farm_Config"
$Result.Resources.DatabaseName | Should Be "SharePoint_Farm_Config"
}
It "resolves nested functions" {
$ConfigurationData = @{
Parameters = @{
Prefix = @{
Value = "sharepoint"
}
}
Resources = @{
Name = "[concat(toUpper(parameters('Prefix')), '_Services')]"
}
}
$Result = Resolve-DSCConfigurationData -ConfigurationData $ConfigurationData
$Result.Resources.Name | Should Be "SHAREPOINT_Services"
}
It "resolves string helper functions" {
$ConfigurationData = @{
Resources = @{
Lower = "[toLower('BGW-LAN')]"
Upper = "[toUpper('bgw-lan')]"
First = "[firstIndexOf('a', 'b', 'c')]"
Last = "[lastIndexOf('a', 'b', 'c')]"
Index = "[indexOf('BGW', 1)]"
Substring = "[substring('SharePoint', 5, 5)]"
Replace = "[replace('BGW-LAN', '-', '_')]"
}
}
$Result = Resolve-DSCConfigurationData -ConfigurationData $ConfigurationData
$Result.Resources.Lower | Should Be "bgw-lan"
$Result.Resources.Upper | Should Be "BGW-LAN"
$Result.Resources.First | Should Be "a"
$Result.Resources.Last | Should Be "c"
$Result.Resources.Index | Should Be "G"
$Result.Resources.Substring | Should Be "Point"
$Result.Resources.Replace | Should Be "BGW_LAN"
}
It "resolves formatting, fallback, and conditional functions" {
$ConfigurationData = @{
Parameters = @{
DatabasePrefix = @{
Value = "SharePoint"
}
DomainLabel = @{
Value = "LAN"
}
Stage = @{
Value = "Test"
}
OptionalValue = @{
Value = ""
}
}
Resources = @{
Formatted = "[format('{0}_{1}_{2}', parameters('DatabasePrefix'), parameters('DomainLabel'), parameters('Stage'))]"
Fallback = "[coalesce(parameters('OptionalValue'), 'DefaultValue')]"
Conditional = "[if(equals(parameters('Stage'), 'Test'), 'TST', 'PRD')]"
NotEquals = "[notEquals(parameters('Stage'), 'Prod')]"
AndValue = "[and(equals(parameters('Stage'), 'Test'), not(empty(parameters('DatabasePrefix'))))]"
OrValue = "[or(equals(parameters('Stage'), 'Prod'), equals(parameters('Stage'), 'Test'))]"
}
}
$Result = Resolve-DSCConfigurationData -ConfigurationData $ConfigurationData
$Result.Resources.Formatted | Should Be "SharePoint_LAN_Test"
$Result.Resources.Fallback | Should Be "DefaultValue"
$Result.Resources.Conditional | Should Be "TST"
$Result.Resources.NotEquals | Should Be $true
$Result.Resources.AndValue | Should Be $true
$Result.Resources.OrValue | Should Be $true
}
It "resolves collection and string inspection functions" {
$ConfigurationData = @{
Parameters = @{
DomainFQDN = @{
Value = "bgw-online.de"
}
}
Resources = @{
Split = "[split(parameters('DomainFQDN'), '.')]"
Joined = "[join(split(parameters('DomainFQDN'), '.'), '_')]"
JoinedNotEmpty = "[joinNotEmpty('_', 'SharePoint', '', 'LAN', 'Test', '', 'Services')]"
Take = "[join(take(split(parameters('DomainFQDN'), '.'), 1), '_')]"
Skip = "[join(skip(split(parameters('DomainFQDN'), '.'), 1), '_')]"
First = "[first(split(parameters('DomainFQDN'), '.'))]"
Last = "[last(split(parameters('DomainFQDN'), '.'))]"
Unique = "[join(unique(split('SP.SP.SQL', '.')), '_')]"
Sort = "[join(sort(split('SQL.SP.APP', '.')), '_')]"
ContainsString = "[contains(parameters('DomainFQDN'), 'online')]"
ContainsArray = "[contains(split(parameters('DomainFQDN'), '.'), 'de')]"
StartsWith = "[startsWith(parameters('DomainFQDN'), 'bgw')]"
EndsWith = "[endsWith(parameters('DomainFQDN'), 'DE')]"
Length = "[length(split(parameters('DomainFQDN'), '.'))]"
Empty = "[empty('')]"
}
}
$Result = Resolve-DSCConfigurationData -ConfigurationData $ConfigurationData
$Result.Resources.Split[0] | Should Be "bgw-online"
$Result.Resources.Split[1] | Should Be "de"
$Result.Resources.Joined | Should Be "bgw-online_de"
$Result.Resources.JoinedNotEmpty | Should Be "SharePoint_LAN_Test_Services"
$Result.Resources.Take | Should Be "bgw-online"
$Result.Resources.Skip | Should Be "de"
$Result.Resources.First | Should Be "bgw-online"
$Result.Resources.Last | Should Be "de"
$Result.Resources.Unique | Should Be "SP_SQL"
$Result.Resources.Sort | Should Be "APP_SP_SQL"
$Result.Resources.ContainsString | Should Be $true
$Result.Resources.ContainsArray | Should Be $true
$Result.Resources.StartsWith | Should Be $true
$Result.Resources.EndsWith | Should Be $true
$Result.Resources.Length | Should Be 2
$Result.Resources.Empty | Should Be $true
}
It "resolves trim and padding functions" {
$ConfigurationData = @{
Resources = @{
Trim = "[trim(' SharePoint ')]"
TrimStart = "[trimStart(' SharePoint')]"
TrimEnd = "[trimEnd('SharePoint ')]"
PadLeft = "[padLeft('1', 2, '0')]"
PadRight = "[padRight('SP', 4, '0')]"
DefaultIfEmpty = "[defaultIfEmpty('', 'SharePoint')]"
Sanitized = "[sanitizeName(' SharePoint LAN/Test DB ')]"
Normalized = "[normalizeSeparator('__SharePoint___LAN_Test__', '_')]"
Prefix = "[prefixIfNotEmpty('LAN', 'BGW-')]"
EmptyPrefix = "[prefixIfNotEmpty('', 'BGW-')]"
Suffix = "[suffixIfNotEmpty('SharePoint', '_DB')]"
EmptySuffix = "[suffixIfNotEmpty('', '_DB')]"
}
}
$Result = Resolve-DSCConfigurationData -ConfigurationData $ConfigurationData
$Result.Resources.Trim | Should Be "SharePoint"
$Result.Resources.TrimStart | Should Be "SharePoint"
$Result.Resources.TrimEnd | Should Be "SharePoint"
$Result.Resources.PadLeft | Should Be "01"
$Result.Resources.PadRight | Should Be "SP00"
$Result.Resources.DefaultIfEmpty | Should Be "SharePoint"
$Result.Resources.Sanitized | Should Be "SharePoint_LAN_Test_DB"
$Result.Resources.Normalized | Should Be "SharePoint_LAN_Test"
$Result.Resources.Prefix | Should Be "BGW-LAN"
$Result.Resources.EmptyPrefix | Should Be ""
$Result.Resources.Suffix | Should Be "SharePoint_DB"
$Result.Resources.EmptySuffix | Should Be ""
}
It "resolves values inside arrays recursively" {
$ConfigurationData = @{
Parameters = @{
NodeName = @{
Value = "SP01"
}
}
AllNodes = @(
@{
NodeName = "[parameters('NodeName')]"
}
)
}
$Result = Resolve-DSCConfigurationData -ConfigurationData $ConfigurationData
$Result.AllNodes[0].NodeName | Should Be "SP01"
}
It "throws for circular variables" {
$ConfigurationData = @{
Variables = @{
A = "[variables('B')]"
B = "[variables('A')]"
}
Resources = @{
Value = "[variables('A')]"
}
}
{ Resolve-DSCConfigurationData -ConfigurationData $ConfigurationData } | Should Throw
}
}

View File

@@ -42,6 +42,7 @@ function Assert-ConfigurationDataParameter {
return return
} }
Assert-ConfigurationDataParameterType -Name $Name -Definition $Definition -Value $Value
Assert-ConfigurationDataParameterAllowedValue -Name $Name -Definition $Definition -Value $Value Assert-ConfigurationDataParameterAllowedValue -Name $Name -Definition $Definition -Value $Value
if(Test-ConfigurationDataMapContainsKey -Map $Definition -Key "MinLength"){ if(Test-ConfigurationDataMapContainsKey -Map $Definition -Key "MinLength"){
@@ -64,4 +65,20 @@ function Assert-ConfigurationDataParameter {
throw "Parameter [$Name] value [$Value] does not match pattern [$Pattern]." throw "Parameter [$Name] value [$Value] does not match pattern [$Pattern]."
} }
} }
if(Test-ConfigurationDataMapContainsKey -Map $Definition -Key "MinValue"){
Assert-ConfigurationDataParameterNumericValue -Name $Name -Value $Value
$MinValue = [decimal](Get-ConfigurationDataMapValue -Map $Definition -Key "MinValue")
if(([decimal]$Value) -lt $MinValue){
throw "Parameter [$Name] value [$Value] is less than MinValue [$MinValue]."
}
}
if(Test-ConfigurationDataMapContainsKey -Map $Definition -Key "MaxValue"){
Assert-ConfigurationDataParameterNumericValue -Name $Name -Value $Value
$MaxValue = [decimal](Get-ConfigurationDataMapValue -Map $Definition -Key "MaxValue")
if(([decimal]$Value) -gt $MaxValue){
throw "Parameter [$Name] value [$Value] is greater than MaxValue [$MaxValue]."
}
}
} }

View File

@@ -21,6 +21,16 @@ function Assert-ConfigurationDataParameterAllowedValue {
return return
} }
if($Value -is [System.Array] -and $Value -isnot [string]){
foreach($Item in @($Value)){
if($AllowedValues -notcontains $Item){
throw "Parameter [$Name] value [$Item] is not allowed. Allowed values are: $($AllowedValues -join ', ')."
}
}
return
}
if($AllowedValues -notcontains $Value){ if($AllowedValues -notcontains $Value){
throw "Parameter [$Name] value [$Value] is not allowed. Allowed values are: $($AllowedValues -join ', ')." throw "Parameter [$Name] value [$Value] is not allowed. Allowed values are: $($AllowedValues -join ', ')."
} }

View File

@@ -0,0 +1,21 @@
function Assert-ConfigurationDataParameterNumericValue {
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true)]
[string]
$Name,
[AllowNull()]
$Value
)
if($null -eq $Value -or $Value -is [bool] -or ($Value -isnot [ValueType])){
throw "Parameter [$Name] value [$Value] is not numeric."
}
try {
[void]([decimal]$Value)
} catch {
throw "Parameter [$Name] value [$Value] is not numeric."
}
}

View File

@@ -0,0 +1,61 @@
function Assert-ConfigurationDataParameterType {
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true)]
[string]
$Name,
[Parameter(Mandatory=$true)]
$Definition,
[AllowNull()]
$Value
)
if(-not (Test-ConfigurationDataMapContainsKey -Map $Definition -Key "Type")){
return
}
$TypeName = ([string](Get-ConfigurationDataMapValue -Map $Definition -Key "Type")).ToLowerInvariant()
switch($TypeName){
"string" {
if($Value -isnot [string]){
throw "Parameter [$Name] expects type [string], but received [$($Value.GetType().Name)]."
}
}
{ $_ -in @("int", "integer") } {
if(-not (Test-ConfigurationDataValueIsInteger -Value $Value)){
throw "Parameter [$Name] expects type [int], but received [$($Value.GetType().Name)]."
}
}
{ $_ -in @("bool", "boolean") } {
if($Value -isnot [bool]){
throw "Parameter [$Name] expects type [bool], but received [$($Value.GetType().Name)]."
}
}
"array" {
if($Value -isnot [System.Array] -or $Value -is [string]){
throw "Parameter [$Name] expects type [array], but received [$($Value.GetType().Name)]."
}
}
{ $_ -in @("hashtable", "object") } {
if(-not (Test-ConfigurationDataMap -Value $Value)){
throw "Parameter [$Name] expects type [hashtable], but received [$($Value.GetType().Name)]."
}
}
"securestring" {
if(($Value -isnot [string]) -and ($Value -isnot [System.Security.SecureString]) -and (-not (Test-ConfigurationDataMap -Value $Value))){
throw "Parameter [$Name] expects type [secureString], but received [$($Value.GetType().Name)]."
}
}
"credential" {
if(($Value -isnot [System.Management.Automation.PSCredential]) -and (-not (Test-ConfigurationDataMap -Value $Value))){
throw "Parameter [$Name] expects type [credential], but received [$($Value.GetType().Name)]."
}
}
default {
throw "Parameter [$Name] uses unsupported type [$TypeName]."
}
}
}

View File

@@ -0,0 +1,20 @@
function Test-ConfigurationDataValueIsInteger {
[CmdletBinding()]
Param(
[AllowNull()]
$Value
)
if($null -eq $Value -or $Value -is [bool]){
return $false
}
return ($Value -is [byte]) -or
($Value -is [sbyte]) -or
($Value -is [int16]) -or
($Value -is [uint16]) -or
($Value -is [int]) -or
($Value -is [uint32]) -or
($Value -is [long]) -or
($Value -is [uint64])
}

121
Readme.md
View File

@@ -1,4 +1,4 @@
# Resolve-DSCConfigurationData # Resolve-DSCConfigurationData
`Resolve-DSCConfigurationData` resolves parameter, variable, and expression references in DSC configuration data. `Resolve-DSCConfigurationData` resolves parameter, variable, and expression references in DSC configuration data.
@@ -47,6 +47,10 @@ This block shows all currently supported parameter properties.
MinLength = 2 MinLength = 2
MaxLength = 32 MaxLength = 32
# Optional numeric range validation. Applies to numeric values such as Type = 'int'.
MinValue = 1
MaxValue = 65535
# Optional regex validation. # Optional regex validation.
Pattern = '^[A-Za-z][A-Za-z0-9_-]*$' Pattern = '^[A-Za-z][A-Za-z0-9_-]*$'
@@ -75,11 +79,72 @@ This block shows all currently supported parameter properties.
Notes: Notes:
- `Value` wins over `DefaultValue`. - `Value` wins over `DefaultValue`.
- `Required`, `AllowedValues`, `MinLength`, `MaxLength`, and `Pattern` are validated by the resolver. - `Type`, `Required`, `AllowedValues`, `MinLength`, `MaxLength`, `MinValue`, `MaxValue`, and `Pattern` are validated by the resolver.
- `AllowedValues` validates scalar values directly and array values item by item.
- `Sensitive` is currently metadata only. - `Sensitive` is currently metadata only.
- `Deprecated.Message` can be a string or a localized hashtable. - `Deprecated.Message` can be a string or a localized hashtable.
- Optional string parameters can allow empty values with a pattern like `'^$|^[A-Za-z][A-Za-z0-9_-]*$'`. - Optional string parameters can allow empty values with a pattern like `'^$|^[A-Za-z][A-Za-z0-9_-]*$'`.
Supported parameter types:
- `string`
- `int` / `integer`
- `bool` / `boolean`
- `array`
- `hashtable` / `object`
- `secureString`
- `credential`
`secureString` and `credential` are intended for secret references, not raw secrets in PSD1 files:
```powershell
FarmPassphrase = @{
Type = 'secureString'
Required = $true
Sensitive = $true
Value = @{
SecretName = 'SharePointFarmPassphrase'
}
}
SetupCredential = @{
Type = 'credential'
Required = $true
Sensitive = $true
Value = @{
CredentialName = 'SharePointSetup'
}
}
```
Array values can be restricted item by item:
```powershell
ServerRoles = @{
Type = 'array'
Value = @(
'WebFrontEnd',
'Application'
)
AllowedValues = @(
'WebFrontEnd',
'Application',
'Search'
)
}
```
Numeric values can be restricted with `MinValue` and `MaxValue`:
```powershell
SqlPort = @{
Type = 'int'
DefaultValue = 1433
MinValue = 1
MaxValue = 65535
}
```
## Variable Example ## Variable Example
Variables may reference parameters and other variables. Nested variable references are supported. Circular references are rejected. Variables may reference parameters and other variables. Nested variable references are supported. Circular references are rejected.
@@ -93,7 +158,7 @@ Variables may reference parameters and other variables. Nested variable referenc
} }
DomainLabel = @{ DomainLabel = @{
Type = 'string' Type = 'string'
Value = 'LAN' Value = 'corp'
} }
Landscape = @{ Landscape = @{
Type = 'string' Type = 'string'
@@ -122,9 +187,9 @@ Example output:
```text ```text
StageCode : TST StageCode : TST
DatabasePrefix : SharePoint_LAN_TST DatabasePrefix : SharePoint_corp_TST
ServiceDbPrefix : SharePoint_LAN_TST_Services ServiceDbPrefix : SharePoint_corp_TST_Services
ConfigDbName : SharePoint_LAN_TST_Farm_Config ConfigDbName : SharePoint_corp_TST_Farm_Config
``` ```
## Functions ## Functions
@@ -149,12 +214,12 @@ ConfigDbName : SharePoint_LAN_TST_Farm_Config
```powershell ```powershell
"[format('{0}_{1}_{2}', parameters('DatabasePrefix'), parameters('DomainLabel'), parameters('Landscape'))]" "[format('{0}_{1}_{2}', parameters('DatabasePrefix'), parameters('DomainLabel'), parameters('Landscape'))]"
# SharePoint_LAN_Test # SharePoint_corp_Test
``` ```
```powershell ```powershell
"[joinNotEmpty('_', parameters('DatabasePrefix'), parameters('DomainLabel'), '', 'Services')]" "[joinNotEmpty('_', parameters('DatabasePrefix'), parameters('DomainLabel'), '', 'Services')]"
# SharePoint_LAN_Services # SharePoint_corp_Services
``` ```
```powershell ```powershell
@@ -185,13 +250,13 @@ ConfigDbName : SharePoint_LAN_TST_Farm_Config
### Case And Text ### Case And Text
```powershell ```powershell
"[toLower('BGW-LAN')]" "[toLower('Contoso-CORP')]"
# bgw-lan # contoso-corp
``` ```
```powershell ```powershell
"[toUpper('bgw-lan')]" "[toUpper('contoso-corp')]"
# BGW-LAN # CONTOSO-CORP
``` ```
```powershell ```powershell
@@ -201,8 +266,8 @@ ConfigDbName : SharePoint_LAN_TST_Farm_Config
``` ```
```powershell ```powershell
"[replace('BGW-LAN', '-', '_')]" "[replace('Contoso-CORP', '-', '_')]"
# BGW_LAN # Contoso_CORP
``` ```
```powershell ```powershell
@@ -211,7 +276,7 @@ ConfigDbName : SharePoint_LAN_TST_Farm_Config
``` ```
```powershell ```powershell
"[indexOf('BGW', 1)]" "[indexOf('CON', 1)]"
# G # G
``` ```
@@ -228,23 +293,23 @@ ConfigDbName : SharePoint_LAN_TST_Farm_Config
### Name Cleanup ### Name Cleanup
```powershell ```powershell
"[sanitizeName(' SharePoint LAN/Test DB ')]" "[sanitizeName(' SharePoint corp/Test DB ')]"
# SharePoint_LAN_Test_DB # SharePoint_corp_Test_DB
``` ```
```powershell ```powershell
"[sanitizeName(' SharePoint LAN/Test DB ', '-')]" "[sanitizeName(' SharePoint corp/Test DB ', '-')]"
# SharePoint-LAN-Test-DB # SharePoint-corp-Test-DB
``` ```
```powershell ```powershell
"[normalizeSeparator('__SharePoint___LAN_Test__', '_')]" "[normalizeSeparator('__SharePoint___corp_Test__', '_')]"
# SharePoint_LAN_Test # SharePoint_corp_Test
``` ```
```powershell ```powershell
"[prefixIfNotEmpty('LAN', 'BGW-')]" "[prefixIfNotEmpty('corp', 'Contoso-')]"
# BGW-LAN # Contoso-corp
``` ```
```powershell ```powershell
@@ -256,17 +321,17 @@ ConfigDbName : SharePoint_LAN_TST_Farm_Config
```powershell ```powershell
"[split(parameters('DomainFQDN'), '.')]" "[split(parameters('DomainFQDN'), '.')]"
# @('bgw-online', 'de') # @('contoso', 'com')
``` ```
```powershell ```powershell
"[join(split(parameters('DomainFQDN'), '.'), '_')]" "[join(split(parameters('DomainFQDN'), '.'), '_')]"
# bgw-online_de # contoso_com
``` ```
```powershell ```powershell
"[first(split(parameters('DomainFQDN'), '.'))]" "[first(split(parameters('DomainFQDN'), '.'))]"
# bgw-online # contoso
``` ```
```powershell ```powershell
@@ -276,7 +341,7 @@ ConfigDbName : SharePoint_LAN_TST_Farm_Config
```powershell ```powershell
"[take(split(parameters('DomainFQDN'), '.'), 1)]" "[take(split(parameters('DomainFQDN'), '.'), 1)]"
# @('bgw-online') # @('contoso')
``` ```
```powershell ```powershell
@@ -307,7 +372,7 @@ ConfigDbName : SharePoint_LAN_TST_Farm_Config
``` ```
```powershell ```powershell
"[startsWith(parameters('DomainFQDN'), 'bgw')]" "[startsWith(parameters('DomainFQDN'), 'contoso')]"
# True # True
``` ```