Enhance configuration data handling with new reference resolution functions, dummy secret support, and update module version to 1.1.0
This commit is contained in:
39
Private/Get-ConfigurationDataObjectPropertyValue.ps1
Normal file
39
Private/Get-ConfigurationDataObjectPropertyValue.ps1
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
function Get-ConfigurationDataObjectPropertyValue {
|
||||||
|
[CmdletBinding()]
|
||||||
|
Param(
|
||||||
|
[Parameter(Mandatory=$true)]
|
||||||
|
[AllowNull()]
|
||||||
|
$Value,
|
||||||
|
|
||||||
|
[Parameter(Mandatory=$true)]
|
||||||
|
[string]
|
||||||
|
$Property,
|
||||||
|
|
||||||
|
[Parameter(Mandatory=$false)]
|
||||||
|
[string]
|
||||||
|
$Path = ""
|
||||||
|
)
|
||||||
|
|
||||||
|
if([string]::IsNullOrWhiteSpace($Property)){
|
||||||
|
throw "Configuration data reference property must not be empty."
|
||||||
|
}
|
||||||
|
|
||||||
|
if($null -eq $Value){
|
||||||
|
throw "Configuration data reference property [$Property] was requested from a null value at path [$Path]."
|
||||||
|
}
|
||||||
|
|
||||||
|
if($Value -is [System.Collections.IDictionary]){
|
||||||
|
if(-not $Value.Contains($Property)){
|
||||||
|
throw "Configuration data reference property [$Property] was not found at path [$Path]."
|
||||||
|
}
|
||||||
|
|
||||||
|
return $Value[$Property]
|
||||||
|
}
|
||||||
|
|
||||||
|
$ObjectProperty = $Value.PSObject.Properties[$Property]
|
||||||
|
if($null -eq $ObjectProperty){
|
||||||
|
throw "Configuration data reference property [$Property] was not found at path [$Path]."
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ObjectProperty.Value
|
||||||
|
}
|
||||||
61
Private/Get-ConfigurationDataPathValue.ps1
Normal file
61
Private/Get-ConfigurationDataPathValue.ps1
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
function Get-ConfigurationDataPathValue {
|
||||||
|
[CmdletBinding()]
|
||||||
|
Param(
|
||||||
|
[Parameter(Mandatory=$true)]
|
||||||
|
[AllowNull()]
|
||||||
|
$Value,
|
||||||
|
|
||||||
|
[Parameter(Mandatory=$true)]
|
||||||
|
[string]
|
||||||
|
$Path
|
||||||
|
)
|
||||||
|
|
||||||
|
if([string]::IsNullOrWhiteSpace($Path)){
|
||||||
|
throw "Configuration data reference path must not be empty."
|
||||||
|
}
|
||||||
|
|
||||||
|
$Current = $Value
|
||||||
|
$Segments = @($Path -split '\.')
|
||||||
|
|
||||||
|
foreach($Segment in $Segments){
|
||||||
|
if([string]::IsNullOrWhiteSpace($Segment)){
|
||||||
|
throw "Configuration data reference path [$Path] contains an empty segment."
|
||||||
|
}
|
||||||
|
|
||||||
|
if($null -eq $Current){
|
||||||
|
throw "Configuration data reference path [$Path] was not found. Segment [$Segment] resolved from a null value."
|
||||||
|
}
|
||||||
|
|
||||||
|
if($Current -is [System.Collections.IDictionary]){
|
||||||
|
if(-not $Current.Contains($Segment)){
|
||||||
|
throw "Configuration data reference path [$Path] was not found. Segment [$Segment] is missing."
|
||||||
|
}
|
||||||
|
|
||||||
|
$Current = $Current[$Segment]
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if($Current -is [System.Array] -and $Current -isnot [string]){
|
||||||
|
$Index = 0
|
||||||
|
if(-not [int]::TryParse($Segment, [ref]$Index)){
|
||||||
|
throw "Configuration data reference path [$Path] expected a numeric array index at segment [$Segment]."
|
||||||
|
}
|
||||||
|
|
||||||
|
if($Index -lt 0 -or $Index -ge @($Current).Count){
|
||||||
|
throw "Configuration data reference path [$Path] array index [$Index] is out of range."
|
||||||
|
}
|
||||||
|
|
||||||
|
$Current = @($Current)[$Index]
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
$Property = $Current.PSObject.Properties[$Segment]
|
||||||
|
if($null -eq $Property){
|
||||||
|
throw "Configuration data reference path [$Path] was not found. Property [$Segment] is missing."
|
||||||
|
}
|
||||||
|
|
||||||
|
$Current = $Property.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
return $Current
|
||||||
|
}
|
||||||
@@ -24,6 +24,17 @@ function Invoke-ConfigurationDataExpressionFunction {
|
|||||||
Assert-ConfigurationDataExpressionArgumentCount -Name $Name -Arguments $Arguments -Count 1
|
Assert-ConfigurationDataExpressionArgumentCount -Name $Name -Arguments $Arguments -Count 1
|
||||||
return Resolve-ConfigurationDataVariable -Name ([string]$Arguments[0]) -Context $Context
|
return Resolve-ConfigurationDataVariable -Name ([string]$Arguments[0]) -Context $Context
|
||||||
}
|
}
|
||||||
|
"reference" {
|
||||||
|
if($Arguments.Count -eq 1){
|
||||||
|
return Resolve-ConfigurationDataReference -Path ([string]$Arguments[0]) -Context $Context
|
||||||
|
}
|
||||||
|
|
||||||
|
if($Arguments.Count -eq 2){
|
||||||
|
return Resolve-ConfigurationDataReference -Path ([string]$Arguments[0]) -Property ([string]$Arguments[1]) -Context $Context
|
||||||
|
}
|
||||||
|
|
||||||
|
throw "Function [$Name] expects 1 or 2 arguments, but received [$($Arguments.Count)]."
|
||||||
|
}
|
||||||
"concat" {
|
"concat" {
|
||||||
return (@($Arguments) | ForEach-Object { [string]$_ }) -join ""
|
return (@($Arguments) | ForEach-Object { [string]$_ }) -join ""
|
||||||
}
|
}
|
||||||
|
|||||||
68
Private/New-ConfigurationDataDummySecretValue.ps1
Normal file
68
Private/New-ConfigurationDataDummySecretValue.ps1
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
function New-ConfigurationDataDummySecretValue {
|
||||||
|
[CmdletBinding()]
|
||||||
|
Param(
|
||||||
|
[Parameter(Mandatory=$true)]
|
||||||
|
[ValidateSet("credential", "securestring", "string")]
|
||||||
|
[string]
|
||||||
|
$ExpectedType,
|
||||||
|
|
||||||
|
[Parameter(Mandatory=$false)]
|
||||||
|
[System.Collections.IDictionary]
|
||||||
|
$Reference,
|
||||||
|
|
||||||
|
[Parameter(Mandatory=$false)]
|
||||||
|
[string]
|
||||||
|
$ParameterName = ""
|
||||||
|
)
|
||||||
|
|
||||||
|
$Name = ""
|
||||||
|
if($null -ne $Reference -and (Test-ConfigurationDataMapContainsKey -Map $Reference -Key "Name")){
|
||||||
|
$Name = [string](Get-ConfigurationDataMapValue -Map $Reference -Key "Name" -DefaultValue "")
|
||||||
|
}
|
||||||
|
|
||||||
|
$UserName = ""
|
||||||
|
if($null -ne $Reference -and (Test-ConfigurationDataMapContainsKey -Map $Reference -Key "UserName")){
|
||||||
|
$UserName = [string](Get-ConfigurationDataMapValue -Map $Reference -Key "UserName" -DefaultValue "")
|
||||||
|
}
|
||||||
|
|
||||||
|
if([string]::IsNullOrWhiteSpace($UserName)){
|
||||||
|
$UserNameSource = $ParameterName
|
||||||
|
if([string]::IsNullOrWhiteSpace($UserNameSource)){
|
||||||
|
$UserNameSource = $Name
|
||||||
|
}
|
||||||
|
|
||||||
|
if([string]::IsNullOrWhiteSpace($UserNameSource)){
|
||||||
|
$UserNameSource = "Credential"
|
||||||
|
}
|
||||||
|
|
||||||
|
$UserNameLeaf = @($UserNameSource -split '[\\/]+')[-1]
|
||||||
|
if([string]::IsNullOrWhiteSpace($UserNameLeaf)){
|
||||||
|
$UserNameLeaf = "Credential"
|
||||||
|
}
|
||||||
|
|
||||||
|
$UserName = "DUMMY\$UserNameLeaf"
|
||||||
|
}
|
||||||
|
|
||||||
|
switch($ExpectedType.ToLowerInvariant()){
|
||||||
|
"credential" {
|
||||||
|
return [pscredential]::new(
|
||||||
|
$UserName,
|
||||||
|
(ConvertTo-SecureString -String "DummyPassword!" -AsPlainText -Force)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
"securestring" {
|
||||||
|
return ConvertTo-SecureString -String "DummySecret!" -AsPlainText -Force
|
||||||
|
}
|
||||||
|
"string" {
|
||||||
|
if([string]::IsNullOrWhiteSpace($Name)){
|
||||||
|
$Name = $ParameterName
|
||||||
|
}
|
||||||
|
|
||||||
|
if([string]::IsNullOrWhiteSpace($Name)){
|
||||||
|
return "DummySecret"
|
||||||
|
}
|
||||||
|
|
||||||
|
return "DummySecret:$Name"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,10 +7,13 @@ function New-ConfigurationDataResolutionContext {
|
|||||||
)
|
)
|
||||||
|
|
||||||
$Context = [PSCustomObject]@{
|
$Context = [PSCustomObject]@{
|
||||||
|
ConfigurationData = $ConfigurationData
|
||||||
Parameters = @{}
|
Parameters = @{}
|
||||||
Variables = @{}
|
Variables = @{}
|
||||||
VariableDefinitions = @{}
|
VariableDefinitions = @{}
|
||||||
ResolvingVariables = @{}
|
ResolvingVariables = @{}
|
||||||
|
ReferenceCache = @{}
|
||||||
|
ResolvingReferences = @{}
|
||||||
}
|
}
|
||||||
|
|
||||||
if($ConfigurationData.ContainsKey("Parameters") -and $null -ne $ConfigurationData.Parameters){
|
if($ConfigurationData.ContainsKey("Parameters") -and $null -ne $ConfigurationData.Parameters){
|
||||||
|
|||||||
@@ -7,7 +7,11 @@ function Resolve-ConfigurationDataParameterSecrets {
|
|||||||
|
|
||||||
[Parameter(Mandatory=$false)]
|
[Parameter(Mandatory=$false)]
|
||||||
[hashtable]
|
[hashtable]
|
||||||
$ProviderSettings = @{}
|
$ProviderSettings = @{},
|
||||||
|
|
||||||
|
[Parameter(Mandatory=$false)]
|
||||||
|
[switch]
|
||||||
|
$UseDummySecrets
|
||||||
)
|
)
|
||||||
|
|
||||||
$ResolvedConfigurationData = $ConfigurationData.Clone()
|
$ResolvedConfigurationData = $ConfigurationData.Clone()
|
||||||
@@ -32,7 +36,11 @@ function Resolve-ConfigurationDataParameterSecrets {
|
|||||||
$ExpectedType = $TypeName.ToLowerInvariant()
|
$ExpectedType = $TypeName.ToLowerInvariant()
|
||||||
foreach($ValueKey in @("Value", "DefaultValue")){
|
foreach($ValueKey in @("Value", "DefaultValue")){
|
||||||
if((Test-ConfigurationDataMapContainsKey -Map $Definition -Key $ValueKey) -and (Test-ConfigurationDataSecretReference -Value $Definition[$ValueKey])){
|
if((Test-ConfigurationDataMapContainsKey -Map $Definition -Key $ValueKey) -and (Test-ConfigurationDataSecretReference -Value $Definition[$ValueKey])){
|
||||||
$Definition[$ValueKey] = Resolve-ConfigurationDataSecretReference -Reference $Definition[$ValueKey] -ExpectedType $ExpectedType -ProviderSettings $ProviderSettings
|
if($UseDummySecrets){
|
||||||
|
$Definition[$ValueKey] = New-ConfigurationDataDummySecretValue -ExpectedType $ExpectedType -Reference $Definition[$ValueKey] -ParameterName $Parameter.Name
|
||||||
|
}else{
|
||||||
|
$Definition[$ValueKey] = Resolve-ConfigurationDataSecretReference -Reference $Definition[$ValueKey] -ExpectedType $ExpectedType -ProviderSettings $ProviderSettings
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
46
Private/Resolve-ConfigurationDataReference.ps1
Normal file
46
Private/Resolve-ConfigurationDataReference.ps1
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
function Resolve-ConfigurationDataReference {
|
||||||
|
[CmdletBinding()]
|
||||||
|
Param(
|
||||||
|
[Parameter(Mandatory=$true)]
|
||||||
|
[string]
|
||||||
|
$Path,
|
||||||
|
|
||||||
|
[Parameter(Mandatory=$false)]
|
||||||
|
[AllowEmptyString()]
|
||||||
|
[string]
|
||||||
|
$Property = "",
|
||||||
|
|
||||||
|
[Parameter(Mandatory=$true)]
|
||||||
|
$Context
|
||||||
|
)
|
||||||
|
|
||||||
|
$ReferenceKey = $Path
|
||||||
|
if(-not [string]::IsNullOrWhiteSpace($Property)){
|
||||||
|
$ReferenceKey = "$Path::$Property"
|
||||||
|
}
|
||||||
|
|
||||||
|
if($Context.ReferenceCache.ContainsKey($ReferenceKey)){
|
||||||
|
return $Context.ReferenceCache[$ReferenceKey]
|
||||||
|
}
|
||||||
|
|
||||||
|
if($Context.ResolvingReferences.ContainsKey($ReferenceKey)){
|
||||||
|
$Stack = @($Context.ResolvingReferences.Keys) + $ReferenceKey
|
||||||
|
throw "Circular configuration data reference detected: $($Stack -join ' -> ')."
|
||||||
|
}
|
||||||
|
|
||||||
|
$Context.ResolvingReferences[$ReferenceKey] = $true
|
||||||
|
try {
|
||||||
|
$RawValue = Get-ConfigurationDataPathValue -Value $Context.ConfigurationData -Path $Path
|
||||||
|
$ResolvedValue = Resolve-ConfigurationDataValue -Value $RawValue -Context $Context
|
||||||
|
|
||||||
|
if(-not [string]::IsNullOrWhiteSpace($Property)){
|
||||||
|
$ResolvedValue = Get-ConfigurationDataObjectPropertyValue -Value $ResolvedValue -Property $Property -Path $Path
|
||||||
|
}
|
||||||
|
|
||||||
|
$Context.ReferenceCache[$ReferenceKey] = $ResolvedValue
|
||||||
|
return $ResolvedValue
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
$Context.ResolvingReferences.Remove($ReferenceKey)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,6 +15,9 @@ function Resolve-ConfigurationDataValue {
|
|||||||
if($Value -is [System.Collections.Specialized.OrderedDictionary]){
|
if($Value -is [System.Collections.Specialized.OrderedDictionary]){
|
||||||
$Resolved = [ordered]@{}
|
$Resolved = [ordered]@{}
|
||||||
foreach($Entry in $Value.GetEnumerator()){
|
foreach($Entry in $Value.GetEnumerator()){
|
||||||
|
if($Entry.Name -eq "Sealed"){
|
||||||
|
continue
|
||||||
|
}
|
||||||
$Resolved[$Entry.Name] = Resolve-ConfigurationDataValue -Value $Entry.Value -Context $Context
|
$Resolved[$Entry.Name] = Resolve-ConfigurationDataValue -Value $Entry.Value -Context $Context
|
||||||
}
|
}
|
||||||
return $Resolved
|
return $Resolved
|
||||||
@@ -23,6 +26,9 @@ function Resolve-ConfigurationDataValue {
|
|||||||
if($Value -is [System.Collections.Hashtable]){
|
if($Value -is [System.Collections.Hashtable]){
|
||||||
$Resolved = @{}
|
$Resolved = @{}
|
||||||
foreach($Entry in $Value.GetEnumerator()){
|
foreach($Entry in $Value.GetEnumerator()){
|
||||||
|
if($Entry.Name -eq "Sealed"){
|
||||||
|
continue
|
||||||
|
}
|
||||||
$Resolved[$Entry.Name] = Resolve-ConfigurationDataValue -Value $Entry.Value -Context $Context
|
$Resolved[$Entry.Name] = Resolve-ConfigurationDataValue -Value $Entry.Value -Context $Context
|
||||||
}
|
}
|
||||||
return $Resolved
|
return $Resolved
|
||||||
|
|||||||
@@ -27,7 +27,9 @@ function Resolve-DSCConfigurationData {
|
|||||||
$ProviderSettings = Import-PowerShellDataFile -Path $ProviderSettingsPath
|
$ProviderSettings = Import-PowerShellDataFile -Path $ProviderSettingsPath
|
||||||
}
|
}
|
||||||
|
|
||||||
if(-not $SkipSecrets){
|
if($SkipSecrets){
|
||||||
|
$ConfigurationData = Resolve-ConfigurationDataParameterSecrets -ConfigurationData $ConfigurationData -ProviderSettings $ProviderSettings -UseDummySecrets
|
||||||
|
}else{
|
||||||
Unlock-ConfigurationDataSecretManagementVault -ProviderSettings $ProviderSettings
|
Unlock-ConfigurationDataSecretManagementVault -ProviderSettings $ProviderSettings
|
||||||
$ConfigurationData = Resolve-ConfigurationDataParameterSecrets -ConfigurationData $ConfigurationData -ProviderSettings $ProviderSettings
|
$ConfigurationData = Resolve-ConfigurationDataParameterSecrets -ConfigurationData $ConfigurationData -ProviderSettings $ProviderSettings
|
||||||
}
|
}
|
||||||
|
|||||||
40
Readme.md
40
Readme.md
@@ -64,6 +64,9 @@ This block shows all currently supported parameter properties.
|
|||||||
# Metadata for later reporting/output tooling. The resolver does not mask values yet.
|
# Metadata for later reporting/output tooling. The resolver does not mask values yet.
|
||||||
Sensitive = $false
|
Sensitive = $false
|
||||||
|
|
||||||
|
# Prevents child templates from changing this parameter definition during merge.
|
||||||
|
Sealed = $false
|
||||||
|
|
||||||
# Emits a warning when the parameter is present.
|
# Emits a warning when the parameter is present.
|
||||||
Deprecated = @{
|
Deprecated = @{
|
||||||
Message = @{
|
Message = @{
|
||||||
@@ -89,6 +92,7 @@ Notes:
|
|||||||
- `Type`, `Required`, `AllowedValues`, `MinLength`, `MaxLength`, `MinValue`, `MaxValue`, 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.
|
- `AllowedValues` validates scalar values directly and array values item by item.
|
||||||
- `Sensitive` is currently metadata only.
|
- `Sensitive` is currently metadata only.
|
||||||
|
- `Sealed = $true` on a parameter seals the whole parameter definition during merge. Child templates cannot change any property of that parameter.
|
||||||
- `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_-]*$'`.
|
||||||
|
|
||||||
@@ -139,7 +143,11 @@ $resolved = Resolve-DSCConfigurationData -ConfigurationData $merged -ProviderSet
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Use `-SkipSecrets` when you only want structural validation/resolution without loading provider secrets.
|
Use `-SkipSecrets` when you only want structural validation/resolution without loading provider secrets. Secret references are replaced with typed dummy values, so references such as `reference(..., 'UserName')` keep working in tests and previews.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$preview = Resolve-DSCConfigurationData -ConfigurationData $merged -SkipSecrets
|
||||||
|
```
|
||||||
|
|
||||||
SecretManagement is the only built-in secret resolver provider. KeePass, SecretStore, Azure Key Vault, and other backends should be registered as SecretManagement vaults.
|
SecretManagement is the only built-in secret resolver provider. KeePass, SecretStore, Azure Key Vault, and other backends should be registered as SecretManagement vaults.
|
||||||
|
|
||||||
@@ -207,6 +215,30 @@ $resolved = Resolve-DSCConfigurationData `
|
|||||||
-ProviderSettingsPath 'C:\DSC\Contoso\ProviderSettings.SecretManagement.psd1'
|
-ProviderSettingsPath 'C:\DSC\Contoso\ProviderSettings.SecretManagement.psd1'
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Sealed Template Blocks
|
||||||
|
|
||||||
|
`Sealed = $true` can also be placed on any hashtable block in the configuration data. During merge, child templates cannot add or overwrite anything at that node or below it.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
Resources = @{
|
||||||
|
NonNodeData = @{
|
||||||
|
Services = @{
|
||||||
|
SharePoint = @{
|
||||||
|
Farm = @{
|
||||||
|
ManagedAccounts = @{
|
||||||
|
Sealed = $true
|
||||||
|
|
||||||
|
FarmAccount = "[parameters('FarmCredential')]"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The `Sealed` marker is kept during merge so later merge steps can enforce it. `Resolve-DSCConfigurationData` removes the marker from the final resolved data so DSC resource loops do not see it as a normal configuration item.
|
||||||
|
|
||||||
Inspect the configured provider and registered vault:
|
Inspect the configured provider and registered vault:
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
@@ -382,12 +414,16 @@ ConfigDbName : SharePoint_corp_TST_Farm_Config
|
|||||||
```powershell
|
```powershell
|
||||||
"[parameters('DatabasePrefix')]"
|
"[parameters('DatabasePrefix')]"
|
||||||
"[variables('ServiceDbPrefix')]"
|
"[variables('ServiceDbPrefix')]"
|
||||||
|
"[reference('Resources.NonNodeData.Services.SharePoint.Farm.ManagedAccounts.FarmAccount')]"
|
||||||
|
"[reference('Resources.NonNodeData.Services.SharePoint.Farm.ManagedAccounts.FarmAccount', 'UserName')]"
|
||||||
```
|
```
|
||||||
|
|
||||||
`parameters(name)` returns the effective parameter value. `Value` is used before `DefaultValue`.
|
`parameters(name)` returns the effective parameter value. `Value` is used before `DefaultValue`.
|
||||||
|
|
||||||
`variables(name)` resolves another variable. Variables may reference other variables.
|
`variables(name)` resolves another variable. Variables may reference other variables.
|
||||||
|
|
||||||
|
`reference(path)` resolves another value from the configuration data by path. `reference(path, property)` resolves the value and then returns a property from it, such as `UserName` from a `PSCredential`.
|
||||||
|
|
||||||
### String Composition
|
### String Composition
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
@@ -590,6 +626,8 @@ ConfigDbName : SharePoint_corp_TST_Farm_Config
|
|||||||
|
|
||||||
- `parameters(name)`
|
- `parameters(name)`
|
||||||
- `variables(name)`
|
- `variables(name)`
|
||||||
|
- `reference(path)`
|
||||||
|
- `reference(path, property)`
|
||||||
- `concat(value1, value2, ...)`
|
- `concat(value1, value2, ...)`
|
||||||
- `format(formatString, value1, value2, ...)`
|
- `format(formatString, value1, value2, ...)`
|
||||||
- `coalesce(value1, value2, ...)`
|
- `coalesce(value1, value2, ...)`
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
@{
|
@{
|
||||||
RootModule = "Resolve-DSCConfigurationData.psm1"
|
RootModule = "Resolve-DSCConfigurationData.psm1"
|
||||||
ModuleVersion = "1.0.2"
|
ModuleVersion = "1.1.0"
|
||||||
GUID = "1d6ba0d4-93d5-4b0f-94c7-bf10a30fe0e8"
|
GUID = "1d6ba0d4-93d5-4b0f-94c7-bf10a30fe0e8"
|
||||||
Author = "Torsten Brendgen"
|
Author = "Torsten Brendgen"
|
||||||
Copyright = "(c) Torsten Brendgen. All rights reserved."
|
Copyright = "(c) Torsten Brendgen. All rights reserved."
|
||||||
|
|||||||
Reference in New Issue
Block a user