Skip to content

Commit 61da4b7

Browse files
authored
Merge pull request #1142 from Gijsreyn/gh-57/main/add-range-function
Add `range()` function
2 parents 0ec3d7c + bc783f8 commit 61da4b7

File tree

5 files changed

+442
-0
lines changed

5 files changed

+442
-0
lines changed
Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
1+
---
2+
description: Reference for the 'range' DSC configuration document function
3+
ms.date: 09/26/2025
4+
ms.topic: reference
5+
title: range
6+
---
7+
8+
## Synopsis
9+
10+
Creates an array of integers from a starting integer and containing a number of
11+
items.
12+
13+
## Syntax
14+
15+
```Syntax
16+
range(startIndex, count)
17+
```
18+
19+
## Description
20+
21+
The `range()` function generates a sequence of consecutive integers starting
22+
from `startIndex` and containing `count` number of items. This is useful for
23+
creating numeric sequences, iterating over indices, or generating test data.
24+
25+
The sum of `startIndex` and `count` must not exceed 2,147,483,647 (the maximum
26+
value for a 32-bit signed integer). The `count` parameter must be a
27+
non-negative integer up to 10,000.
28+
29+
## Examples
30+
31+
### Example 1 - Generate server port numbers for load balancer configuration
32+
33+
Use `range()` to create a sequence of port numbers for configuring multiple
34+
backend servers in a load balancer. This ensures consistent port allocation
35+
across your infrastructure.
36+
37+
```yaml
38+
# range.example.1.dsc.config.yaml
39+
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
40+
resources:
41+
- name: Load Balancer Ports
42+
type: Microsoft.DSC.Debug/Echo
43+
properties:
44+
output:
45+
backendPorts: "[range(8080, 5)]"
46+
alternativePorts: "[range(9000, 3)]"
47+
```
48+
49+
```bash
50+
dsc config get --file range.example.1.dsc.config.yaml
51+
```
52+
53+
```yaml
54+
results:
55+
- name: Load Balancer Ports
56+
type: Microsoft.DSC.Debug/Echo
57+
result:
58+
actualState:
59+
output:
60+
backendPorts:
61+
- 8080
62+
- 8081
63+
- 8082
64+
- 8083
65+
- 8084
66+
alternativePorts:
67+
- 9000
68+
- 9001
69+
- 9002
70+
messages: []
71+
hadErrors: false
72+
```
73+
74+
### Example 2 - Create worker node identifiers for container orchestration
75+
76+
Generate sequential identifiers for worker nodes in a container cluster. This
77+
is helpful when provisioning multiple identical workers that need unique
78+
numeric identifiers.
79+
80+
```yaml
81+
# range.example.2.dsc.config.yaml
82+
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
83+
resources:
84+
- name: Worker Node IDs
85+
type: Microsoft.DSC.Debug/Echo
86+
properties:
87+
output:
88+
workerIds: "[range(1, 8)]"
89+
testNodeIds: "[range(100, 3)]"
90+
```
91+
92+
```bash
93+
dsc config get --file range.example.2.dsc.config.yaml
94+
```
95+
96+
```yaml
97+
results:
98+
- name: Worker Node IDs
99+
type: Microsoft.DSC.Debug/Echo
100+
result:
101+
actualState:
102+
output:
103+
workerIds:
104+
- 1
105+
- 2
106+
- 3
107+
- 4
108+
- 5
109+
- 6
110+
- 7
111+
- 8
112+
testNodeIds:
113+
- 100
114+
- 101
115+
- 102
116+
messages: []
117+
hadErrors: false
118+
```
119+
120+
### Example 3 - Generate database partition numbers with negative starting values
121+
122+
Create partition identifiers that include negative numbers, useful for
123+
time-series data partitioning or when working with offset-based indexing
124+
systems.
125+
126+
```yaml
127+
# range.example.3.dsc.config.yaml
128+
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
129+
resources:
130+
- name: Database Partitions
131+
type: Microsoft.DSC.Debug/Echo
132+
properties:
133+
output:
134+
timeOffsets: "[range(-3, 7)]"
135+
emptyRange: "[range(50, 0)]"
136+
```
137+
138+
```bash
139+
dsc config get --file range.example.3.dsc.config.yaml
140+
```
141+
142+
```yaml
143+
results:
144+
- name: Database Partitions
145+
type: Microsoft.DSC.Debug/Echo
146+
result:
147+
actualState:
148+
output:
149+
timeOffsets:
150+
- -3
151+
- -2
152+
- -1
153+
- 0
154+
- 1
155+
- 2
156+
- 3
157+
emptyRange: []
158+
messages: []
159+
hadErrors: false
160+
```
161+
162+
### Example 4 - Create year sequences for data archiving policies
163+
164+
Generate sequences of years for implementing data retention policies or
165+
creating time-based archive structures. This example shows practical year
166+
ranges for typical business scenarios.
167+
168+
```yaml
169+
# range.example.4.dsc.config.yaml
170+
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
171+
resources:
172+
- name: Archive Years
173+
type: Microsoft.DSC.Debug/Echo
174+
properties:
175+
output:
176+
recentYears: "[range(2020, 5)]"
177+
fiscalYears: "[range(2022, 3)]"
178+
```
179+
180+
```bash
181+
dsc config get --file range.example.4.dsc.config.yaml
182+
```
183+
184+
```yaml
185+
results:
186+
- name: Archive Years
187+
type: Microsoft.DSC.Debug/Echo
188+
result:
189+
actualState:
190+
output:
191+
recentYears:
192+
- 2020
193+
- 2021
194+
- 2022
195+
- 2023
196+
- 2024
197+
fiscalYears:
198+
- 2022
199+
- 2023
200+
- 2024
201+
messages: []
202+
hadErrors: false
203+
```
204+
205+
## Parameters
206+
207+
### startIndex
208+
209+
The first integer in the array.
210+
211+
```yaml
212+
Type: int
213+
Required: true
214+
Position: 1
215+
```
216+
217+
### count
218+
219+
The number of integers in the array. Must be a non-negative integer up to
220+
10,000. The sum of `startIndex` and `count` must not exceed 2,147,483,647.
221+
222+
```yaml
223+
Type: int
224+
Required: true
225+
Position: 2
226+
```
227+
228+
## Output
229+
230+
Returns an array of consecutive integers starting from `startIndex`.
231+
232+
```yaml
233+
Type: array
234+
```
235+
236+
## Related functions
237+
238+
- [`createArray()`][00] - Creates an array from individual values
239+
- [`length()`][01] - Returns the number of elements in an array
240+
- [`first()`][02] - Returns the first element of an array
241+
- [`skip()`][03] - Returns array elements after skipping a specified number
242+
243+
<!-- Link reference definitions -->
244+
[00]: ./createArray.md
245+
[01]: ./length.md
246+
[02]: ./first.md
247+
[03]: ./skip.md

dsc/tests/dsc_functions.tests.ps1

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -622,4 +622,48 @@ Describe 'tests for function expressions' {
622622
$context.os.architecture | Should -BeExactly $os.architecture
623623
$context.security | Should -BeExactly $out.metadata.'Microsoft.DSC'.securityContext
624624
}
625+
626+
It 'range function works: <expression>' -TestCases @(
627+
@{ expression = '[range(1, 3)]'; expected = @(1, 2, 3) }
628+
@{ expression = '[range(0, 5)]'; expected = @(0, 1, 2, 3, 4) }
629+
@{ expression = '[range(-2, 4)]'; expected = @(-2, -1, 0, 1) }
630+
@{ expression = '[range(10, 0)]'; expected = @() }
631+
@{ expression = '[range(100, 3)]'; expected = @(100, 101, 102) }
632+
@{ expression = '[first(range(2147473647, 10000))]'; expected = 2147473647 }
633+
) {
634+
param($expression, $expected)
635+
636+
$config_yaml = @"
637+
`$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
638+
resources:
639+
- name: Echo
640+
type: Microsoft.DSC.Debug/Echo
641+
properties:
642+
output: "$expression"
643+
"@
644+
$out = dsc -l trace config get -i $config_yaml 2>$TestDrive/error.log | ConvertFrom-Json
645+
$LASTEXITCODE | Should -Be 0 -Because (Get-Content $TestDrive/error.log -Raw)
646+
($out.results[0].result.actualState.output | Out-String) | Should -BeExactly ($expected | Out-String)
647+
}
648+
649+
It 'range function handles errors correctly: <expression>' -TestCases @(
650+
@{ expression = '[range(1, -1)]'; expectedError = 'Count must be non-negative' }
651+
@{ expression = '[range(1, 10001)]'; expectedError = 'Count must not exceed 10000' }
652+
@{ expression = '[range(2147483647, 1)]'; expectedError = 'Sum of startIndex and count must not exceed 2147483647' }
653+
) {
654+
param($expression, $expectedError)
655+
656+
$config_yaml = @"
657+
`$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
658+
resources:
659+
- name: Echo
660+
type: Microsoft.DSC.Debug/Echo
661+
properties:
662+
output: "$expression"
663+
"@
664+
$out = dsc -l trace config get -i $config_yaml 2>$TestDrive/error.log
665+
$LASTEXITCODE | Should -Not -Be 0
666+
$errorContent = Get-Content $TestDrive/error.log -Raw
667+
$errorContent | Should -Match ([regex]::Escape($expectedError))
668+
}
625669
}

dsc_lib/locales/en-us.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,16 @@ description = "Concatenates multiple strings into a file path"
434434
traceArgs = "Executing path function with args: %{args}"
435435
argsMustBeStrings = "Arguments must all be strings"
436436

437+
[functions.range]
438+
description = "Creates an array of integers from a starting integer and containing a number of items"
439+
invoked = "range function"
440+
startIndexNotInt = "Start index must be an integer"
441+
countNotInt = "Count must be an integer"
442+
countNegative = "Count must be non-negative"
443+
countTooLarge = "Count must not exceed 10000"
444+
sumTooLarge = "Sum of startIndex and count must not exceed 2147483647"
445+
sumOverflow = "Sum of startIndex and count causes overflow"
446+
437447
[functions.reference]
438448
description = "Retrieves the output of a previously executed resource"
439449
invoked = "reference function"

dsc_lib/src/functions/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ pub mod null;
5252
pub mod or;
5353
pub mod parameters;
5454
pub mod path;
55+
pub mod range;
5556
pub mod reference;
5657
pub mod resource_id;
5758
pub mod secret;
@@ -168,6 +169,7 @@ impl FunctionDispatcher {
168169
Box::new(or::Or{}),
169170
Box::new(parameters::Parameters{}),
170171
Box::new(path::Path{}),
172+
Box::new(range::Range{}),
171173
Box::new(reference::Reference{}),
172174
Box::new(resource_id::ResourceId{}),
173175
Box::new(secret::Secret{}),

0 commit comments

Comments
 (0)