Skip to content

Commit 37d878e

Browse files
committed
Merge branch 'main' of https://github.com/Gijsreyn/operation-methods into gh-57/main/add-uri-functions
2 parents 7c85e43 + e57d7e2 commit 37d878e

File tree

5 files changed

+444
-3
lines changed

5 files changed

+444
-3
lines changed
Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
---
2+
description: Reference for the 'items' DSC configuration document function
3+
ms.date: 10/11/2025
4+
ms.topic: reference
5+
title: items
6+
---
7+
8+
## Synopsis
9+
10+
Converts a dictionary object to an array of key-value pairs.
11+
12+
## Syntax
13+
14+
```Syntax
15+
items(inputObject)
16+
```
17+
18+
## Description
19+
20+
The `items()` function converts a dictionary object to an array of key-value pairs.
21+
22+
- Each element in the returned array is an object with two properties: `key` (the
23+
property name) and `value` (the property value).
24+
25+
This function is useful for iterating over object properties in DSC configurations,
26+
especially when used with loops. It's the companion function to [`toObject()`][03],
27+
which converts an array back to an object.
28+
29+
## Examples
30+
31+
### Example 1 - Convert simple object to array
32+
33+
This example uses [`createObject()`][00] to create a simple object and converts it
34+
to an array of key-value pairs.
35+
36+
```yaml
37+
# items.example.1.dsc.config.yaml
38+
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
39+
resources:
40+
- name: Echo
41+
type: Microsoft.DSC.Debug/Echo
42+
properties:
43+
output: "[items(createObject('a', 1, 'b', 2, 'c', 3))]"
44+
```
45+
46+
```bash
47+
dsc config get --file items.example.1.dsc.config.yaml
48+
```
49+
50+
```yaml
51+
results:
52+
- name: Echo
53+
type: Microsoft.DSC.Debug/Echo
54+
result:
55+
actualState:
56+
output:
57+
- key: a
58+
value: 1
59+
- key: b
60+
value: 2
61+
- key: c
62+
value: 3
63+
messages: []
64+
hadErrors: false
65+
```
66+
67+
### Example 2 - Access keys and values
68+
69+
This example shows how to access the keys and values from the items array using array
70+
indexing.
71+
72+
```yaml
73+
# items.example.2.dsc.config.yaml
74+
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
75+
resources:
76+
- name: Echo
77+
type: Microsoft.DSC.Debug/Echo
78+
properties:
79+
output: "[items(createObject('firstName', 'John', 'lastName', 'Doe'))[0].key]"
80+
```
81+
82+
```bash
83+
dsc config get --file items.example.2.dsc.config.yaml
84+
```
85+
86+
```yaml
87+
results:
88+
- name: Echo
89+
type: Microsoft.DSC.Debug/Echo
90+
result:
91+
actualState:
92+
output: firstName
93+
messages: []
94+
hadErrors: false
95+
```
96+
97+
### Example 3 - Get length of object
98+
99+
This example shows how to use `items()` with [`length()`][01] to count the number of
100+
properties in an object.
101+
102+
```yaml
103+
# items.example.3.dsc.config.yaml
104+
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
105+
resources:
106+
- name: Echo
107+
type: Microsoft.DSC.Debug/Echo
108+
properties:
109+
output: "[length(items(createObject('a', 1, 'b', 2, 'c', 3)))]"
110+
```
111+
112+
```bash
113+
dsc config get --file items.example.3.dsc.config.yaml
114+
```
115+
116+
```yaml
117+
results:
118+
- name: Echo
119+
type: Microsoft.DSC.Debug/Echo
120+
result:
121+
actualState:
122+
output: 3
123+
messages: []
124+
hadErrors: false
125+
```
126+
127+
### Example 4 - Handle nested objects
128+
129+
This example demonstrates using `items()` with objects that contain nested objects.
130+
It uses [`length()`][01] and [`copyIndex()`][02] with the `copy` feature to iterate
131+
over each user.
132+
133+
```yaml
134+
# items.example.4.dsc.config.yaml
135+
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
136+
parameters:
137+
users:
138+
type: object
139+
defaultValue:
140+
admin:
141+
name: Administrator
142+
role: admin
143+
guest:
144+
name: Guest User
145+
role: guest
146+
resources:
147+
- name: "[format('User-{0}', copyIndex())]"
148+
copy:
149+
name: userLoop
150+
count: "[length(items(parameters('users')))]"
151+
type: Microsoft.DSC.Debug/Echo
152+
properties:
153+
output: "[items(parameters('users'))[copyIndex()].value.name]"
154+
```
155+
156+
```bash
157+
dsc config get --file items.example.4.dsc.config.yaml
158+
```
159+
160+
```yaml
161+
results:
162+
- name: User-0
163+
type: Microsoft.DSC.Debug/Echo
164+
result:
165+
actualState:
166+
output: Administrator
167+
- name: User-1
168+
type: Microsoft.DSC.Debug/Echo
169+
result:
170+
actualState:
171+
output: Guest User
172+
messages: []
173+
hadErrors: false
174+
```
175+
176+
## Parameters
177+
178+
### inputObject
179+
180+
The dictionary object to convert to an array of key-value pairs.
181+
182+
```yaml
183+
Type: object
184+
Required: true
185+
Position: 1
186+
```
187+
188+
## Output
189+
190+
Returns an array where each element is an object with `key` and `value` properties.
191+
192+
```yaml
193+
Type: array
194+
```
195+
196+
## Related functions
197+
198+
- [`createObject()`][00] - Creates an object from key-value pairs
199+
- [`length()`][01] - Returns the number of elements in an array or object
200+
- [`toObject()`][03] - Converts an array of key-value pairs to an object
201+
202+
<!-- Link reference definitions -->
203+
[00]: ./createObject.md
204+
[01]: ./length.md
205+
[02]: ./copyIndex.md
206+
[03]: ./toObject.md

dsc/tests/dsc_functions.tests.ps1

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -860,6 +860,49 @@ Describe 'tests for function expressions' {
860860
$out.results[0].result.actualState.output | Should -Be $expected
861861
}
862862

863+
It 'items function converts object to array: <expression>' -TestCases @(
864+
@{ expression = "[length(items(createObject('a', 1, 'b', 2)))]"; expected = 2 }
865+
@{ expression = "[length(items(createObject()))]"; expected = 0 }
866+
@{ expression = "[items(createObject('name', 'John'))[0].key]"; expected = 'name' }
867+
@{ expression = "[items(createObject('name', 'John'))[0].value]"; expected = 'John' }
868+
@{ expression = "[items(createObject('a', 1, 'b', 2, 'c', 3))[1].key]"; expected = 'b' }
869+
@{ expression = "[items(createObject('x', 'hello', 'y', 'world'))[0].value]"; expected = 'hello' }
870+
) {
871+
param($expression, $expected)
872+
873+
$escapedExpression = $expression -replace "'", "''"
874+
$config_yaml = @"
875+
`$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
876+
resources:
877+
- name: Echo
878+
type: Microsoft.DSC.Debug/Echo
879+
properties:
880+
output: '$escapedExpression'
881+
"@
882+
$out = $config_yaml | dsc config get -f - | ConvertFrom-Json
883+
$out.results[0].result.actualState.output | Should -Be $expected
884+
}
885+
886+
It 'items function handles nested values: <expression>' -TestCases @(
887+
@{ expression = "[items(createObject('person', createObject('name', 'John')))[0].value.name]"; expected = 'John' }
888+
@{ expression = "[items(createObject('list', createArray('a','b','c')))[0].value[1]]"; expected = 'b' }
889+
@{ expression = "[length(items(createObject('obj', createObject('x', 1, 'y', 2)))[0].value)]"; expected = 2 }
890+
) {
891+
param($expression, $expected)
892+
893+
$escapedExpression = $expression -replace "'", "''"
894+
$config_yaml = @"
895+
`$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
896+
resources:
897+
- name: Echo
898+
type: Microsoft.DSC.Debug/Echo
899+
properties:
900+
output: '$escapedExpression'
901+
"@
902+
$out = $config_yaml | dsc config get -f - | ConvertFrom-Json
903+
$out.results[0].result.actualState.output | Should -Be $expected
904+
}
905+
863906
It 'uri function works for: <base> + <relative>' -TestCases @(
864907
@{ base = 'https://example.com/'; relative = 'path/file.html' }
865908
@{ base = 'https://example.com/'; relative = '/path/file.html' }
@@ -939,9 +982,9 @@ Describe 'tests for function expressions' {
939982
@{ expression = "[uriComponent('user+tag@example.com')]"; expected = 'user%2Btag%40example.com' }
940983
@{ expression = "[uriComponent('1234567890')]"; expected = '1234567890' }
941984
@{ expression = "[uriComponent('100%')]"; expected = '100%25' }
985+
@{ expression = "[uriComponent(' ')]"; expected = '%20' }
942986
) {
943987
param($expression, $expected)
944-
945988
$escapedExpression = $expression -replace "'", "''"
946989
$config_yaml = @"
947990
`$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
@@ -984,4 +1027,3 @@ Describe 'tests for function expressions' {
9841027
$out = $config_yaml | dsc config get -f - | ConvertFrom-Json
9851028
$out.results[0].result.actualState.output | Should -Be $expected
9861029
}
987-
}

lib/dsc-lib/locales/en-us.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,10 @@ description = "Returns a single array or object with the common elements from th
367367
invoked = "intersection function"
368368
invalidArgType = "All arguments must either be arrays or objects"
369369

370+
[functions.items]
371+
description = "Converts a dictionary object to an array of objects with key and value properties"
372+
notObject = "Argument must be an object"
373+
370374
[functions.indexOf]
371375
description = "Returns the index of the first occurrence of an item in an array"
372376
invoked = "indexOf function"
@@ -531,7 +535,7 @@ invoked = "uniqueString function"
531535
[functions.uri]
532536
description = "Creates an absolute URI by combining the baseUri and the relativeUri string"
533537
emptyBaseUri = "The baseUri parameter cannot be empty. An absolute URI requires a valid base URI."
534-
notAbsoluteUri = "The baseUri must be an absolute URI (must include a scheme such as http:// or https://)."
538+
notAbsoluteUri = "The baseUri must be an absolute URI (must include a scheme such as https:// or file://)."
535539
invalidRelativeUri = "Invalid URI: The relative URI contains an invalid sequence. Three or more consecutive slashes (///) are not allowed."
536540

537541
[functions.uriComponent]

0 commit comments

Comments
 (0)