Skip to content

Commit 65b2ba8

Browse files
committed
Merge remote-tracking branch 'origin/development' into claude/issue-10033-20251202-1615
2 parents 08016df + 2323952 commit 65b2ba8

1,283 files changed

Lines changed: 31327 additions & 7456 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/CONTRIBUTING-TESTING.md

Lines changed: 571 additions & 0 deletions
Large diffs are not rendered by default.

.github/copilot-instructions.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@
2323
- Install: `Install-Module PSScriptAnalyzer -RequiredVersion 1.18.2`
2424
- Used by: `Invoke-DbatoolsFormatter` command and CI builds
2525

26-
3. **Pester v5.6.1** - Required for running tests
27-
- Install: `Install-Module Pester -RequiredVersion 5.6.1`
26+
3. **Pester v5.7.1** - Required for running tests
27+
- Install: `Install-Module Pester -RequiredVersion 5.7.1`
2828
- Tests MUST use Pester v5 syntax (no `-ForEach` parameter, strict scoping)
2929

3030
## PR Summary Guidelines
@@ -151,7 +151,7 @@ When generating PR summaries:
151151
Install-Module PSScriptAnalyzer -RequiredVersion 1.18.2 -Force
152152
153153
# 3. Install Pester (for testing)
154-
Install-Module Pester -RequiredVersion 5.6.1 -Force
154+
Install-Module Pester -RequiredVersion 5.7.1 -Force
155155
156156
# 4. Import the module to verify setup
157157
Import-Module .\dbatools.psd1
@@ -431,9 +431,9 @@ Context "Parameter validation" {
431431
## Environment Variables & Test Config
432432

433433
**AppVeyor test instances:**
434-
- `$script:instance1` = SQL Server 2008 R2
435-
- `$script:instance2` = SQL Server 2016
436-
- `$script:instance3` = SQL Server 2017
434+
- `$TestConfig.InstanceSingle` = SQL Server 2022
435+
- `$TestConfig.InstanceMulti1` = SQL Server 2022
436+
- `$TestConfig.InstanceMulti2` = SQL Server 2017
437437

438438
**GitHub Actions:**
439439
- Linux: `localhost`, `localhost:14333` (Docker containers)
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
{
2-
"version": "2025.11.29-preview-new-20251129132142",
3-
"notes": "Version of dbatools.library to use for CI/CD and development."
2+
"version": "2025.12.28",
3+
"notes": "Version of dbatools.library to use for CI/CD and development"
44
}

.github/prompts/migration.md

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
# Pester v4 to v5 Migration Guide
2+
3+
## CORE PESTER v5 REQUIREMENTS
4+
5+
### Mandatory Header Structure
6+
Every test file must include this header:
7+
8+
```powershell
9+
#Requires -Module @{ ModuleName="Pester"; ModuleVersion="5.0" }
10+
param(
11+
$ModuleName = "YourModuleName",
12+
$CommandName = "StaticCommandName", # Always use static command name
13+
$PSDefaultParameterValues = $TestConfig.Defaults
14+
)
15+
```
16+
17+
**Critical Requirements:**
18+
- Replace "StaticCommandName" with the actual command name being tested as a static string
19+
- **Remove all dynamic command name derivation** from file paths or directory structures
20+
- Strip out all `knownParameters` validation code (old Pester v4 pattern)
21+
22+
### Critical Structural Changes
23+
24+
#### Test Block Organization
25+
- **All setup code** must be in `BeforeAll` or `BeforeEach` blocks
26+
- **All cleanup code** must be in `AfterAll` or `AfterEach` blocks
27+
- **All test assertions** must be in `It` blocks
28+
- **No loose code** allowed in `Describe` or `Context` blocks
29+
- **Never use `-ForEach` parameter** on any test blocks
30+
31+
```powershell
32+
# Pester v5 Structure
33+
Describe $CommandName {
34+
BeforeAll {
35+
# All setup code here
36+
}
37+
38+
AfterAll {
39+
# All cleanup code here
40+
}
41+
42+
Context "Specific scenario" {
43+
BeforeAll {
44+
# Context-specific setup
45+
}
46+
47+
It "Should do something" {
48+
# Test assertions only
49+
}
50+
}
51+
}
52+
```
53+
54+
### Variable Scoping Changes
55+
- Replace all `$script:` with `$global:` for variables that need to persist across Pester blocks
56+
- Pester v5 has stricter scoping - variables in `BeforeAll` may not be available in `It` blocks without proper scoping
57+
- Add explicit scope declarations when variables cross Pester block boundaries
58+
59+
### PowerShell Syntax Updates Required for Pester v5
60+
61+
#### Variable References
62+
- Replace `$_` with `$PSItem` (recommended for clarity, except where `$_` is required for compatibility)
63+
64+
#### Skip Conditions
65+
- Use boolean values for skip conditions (`$true`/`$false`), not strings
66+
67+
#### Array Operations
68+
- Replace `$results.Count` with `$results.Status.Count` for accurate counting
69+
- Add explicit array initialization: `$array = @()`
70+
- Wrap result collection in array subexpression operator: `$results = @(Get-Something)`
71+
72+
#### Parameter Quoting
73+
Remove unnecessary quotes from parameter values:
74+
```powershell
75+
# Convert this:
76+
"$CommandName" -Tag "IntegrationTests"
77+
# To this:
78+
$CommandName -Tag IntegrationTests
79+
```
80+
81+
#### String Formatting
82+
- Replace multi-line concatenated strings with here-strings when appropriate
83+
84+
### Resource Management
85+
- Always include cleanup code in `AfterAll`/`AfterEach` blocks
86+
- Use `-ErrorAction SilentlyContinue` on cleanup operations
87+
- Create unique temporary resources using `Get-Random`
88+
89+
```powershell
90+
BeforeAll {
91+
$tempPath = "$env:TEMP\TestRun-$(Get-Random)"
92+
$resourcesToCleanup = @()
93+
}
94+
95+
AfterAll {
96+
Remove-Item -Path $tempPath -Recurse -ErrorAction SilentlyContinue
97+
Remove-Item -Path $resourcesToCleanup -ErrorAction SilentlyContinue
98+
}
99+
```
100+
101+
### Where-Object Conversion Rules
102+
Transform Where-Object script blocks to direct property comparisons when possible:
103+
104+
```powershell
105+
# Pester v5 Preferred - direct property comparison
106+
$master = $databases | Where-Object Name -eq "master"
107+
$systemDbs = $databases | Where-Object Name -in "master", "model", "msdb", "tempdb"
108+
109+
# Required - script block for complex filtering only
110+
$hasParameters = (Get-Command $CommandName).Parameters.Values.Name | Where-Object { $PSItem -notin ("WhatIf", "Confirm") }
111+
```
112+
113+
Only use script blocks when direct property comparison is not possible.
114+
115+
## MIGRATION CHECKLIST
116+
117+
**Header and Structure:**
118+
- [ ] Added mandatory `#Requires` header
119+
- [ ] Replaced dynamic command name derivation with static command name
120+
- [ ] Stripped out old `knownParameters` validation code
121+
- [ ] Moved all loose code into appropriate `BeforeAll`/`AfterAll` blocks
122+
- [ ] Removed any `-ForEach` parameters from test blocks
123+
- [ ] All test assertions properly placed in `It` blocks
124+
125+
**Variable Scoping:**
126+
- [ ] Changed `$script:` to `$global:` where needed
127+
- [ ] Added explicit scope declarations for cross-block variables
128+
- [ ] Verified variable scoping works across Pester blocks
129+
130+
**Syntax Transformations:**
131+
- [ ] Replaced `$_` with `$PSItem` (except where compatibility requires `$_`)
132+
- [ ] Replaced string-based skip conditions with boolean values
133+
- [ ] Updated array operations (`$results.Count``$results.Status.Count`)
134+
- [ ] Added explicit array initialization where needed
135+
- [ ] Removed unnecessary parameter quotes
136+
- [ ] Applied Where-Object conversions where possible
137+
- [ ] Replaced concatenated strings with here-strings where appropriate
138+
139+
**Resource Management:**
140+
- [ ] Added proper cleanup code with error suppression
141+
- [ ] Created unique temporary resources using `Get-Random`
142+
- [ ] Ensured all created resources have corresponding cleanup
143+
144+
**Migration Policy:**
145+
- [ ] Do not invent new integration tests - if they don't exist, there's a reason

.github/prompts/pipeline-output.md

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
# Pipeline Output Patterns
2+
3+
**CRITICAL RULE**: NEVER collect objects in an ArrayList or array and output them at the end. Output objects to the pipeline immediately as they are created.
4+
5+
## Why Immediate Output
6+
7+
- **Memory Efficiency**: Objects are released to the pipeline immediately, not held in memory
8+
- **User Experience**: Users see results streaming in real-time, not waiting until the end
9+
- **Pipeline Compatibility**: Enables proper pipeline chaining and early termination (Ctrl+C)
10+
- **Error Resilience**: Partial results are available even if the command fails partway through
11+
12+
## Correct Pattern - Output Immediately
13+
14+
```powershell
15+
foreach ($instance in $SqlInstance) {
16+
$server = Connect-DbaInstance -SqlInstance $instance -SqlCredential $SqlCredential
17+
18+
foreach ($db in $server.Databases) {
19+
# Output each object immediately to the pipeline
20+
[PSCustomObject]@{
21+
ComputerName = $server.ComputerName
22+
InstanceName = $server.ServiceName
23+
SqlInstance = $server.DomainInstanceName
24+
Database = $db.Name
25+
Size = $db.Size
26+
}
27+
}
28+
}
29+
```
30+
31+
## Wrong Patterns - DO NOT USE
32+
33+
### ArrayList Collection (OLD PATTERN)
34+
35+
```powershell
36+
# WRONG - This is an outdated anti-pattern
37+
$results = New-Object System.Collections.ArrayList
38+
39+
foreach ($instance in $SqlInstance) {
40+
$server = Connect-DbaInstance -SqlInstance $instance -SqlCredential $SqlCredential
41+
42+
foreach ($db in $server.Databases) {
43+
$null = $results.Add([PSCustomObject]@{
44+
ComputerName = $server.ComputerName
45+
Database = $db.Name
46+
})
47+
}
48+
}
49+
50+
# WRONG - Holding everything until the end
51+
$results
52+
```
53+
54+
### Array Concatenation (Worst Performance)
55+
56+
```powershell
57+
# WRONG - Array concatenation is extremely slow
58+
$results = @()
59+
60+
foreach ($db in $databases) {
61+
$results += [PSCustomObject]@{
62+
Name = $db.Name
63+
}
64+
}
65+
66+
$results
67+
```
68+
69+
## No -Detailed or -Simple Parameters
70+
71+
Do NOT create `-Detailed` or `-Simple` switch parameters that change the output object structure. This is an outdated pattern that creates confusion and breaks pipeline expectations.
72+
73+
```powershell
74+
# WRONG - Do not create output mode switches
75+
param(
76+
[switch]$Detailed,
77+
[switch]$Simple
78+
)
79+
80+
if ($Detailed) {
81+
# Return more properties
82+
} elseif ($Simple) {
83+
# Return fewer properties
84+
}
85+
```
86+
87+
Instead, return a consistent object with all relevant properties. Users can select the properties they want with `Select-Object`.
88+
89+
## Process Block Pattern
90+
91+
When using `ValueFromPipeline`, output in the `process` block, not `end`:
92+
93+
```powershell
94+
function Get-DbaExample {
95+
[CmdletBinding()]
96+
param (
97+
[Parameter(ValueFromPipeline)]
98+
[DbaInstanceParameter[]]$SqlInstance,
99+
[PSCredential]$SqlCredential
100+
)
101+
102+
process {
103+
foreach ($instance in $SqlInstance) {
104+
$server = Connect-DbaInstance -SqlInstance $instance -SqlCredential $SqlCredential
105+
106+
foreach ($item in $server.SomeCollection) {
107+
# Output immediately in process block
108+
[PSCustomObject]@{
109+
ComputerName = $server.ComputerName
110+
InstanceName = $server.ServiceName
111+
SqlInstance = $server.DomainInstanceName
112+
Name = $item.Name
113+
}
114+
}
115+
}
116+
}
117+
}
118+
```
119+
120+
## Summary
121+
122+
- Output objects immediately as they are created
123+
- Never use ArrayList, Generic.List, or array += to collect results
124+
- Never use `-Detailed`/`-Simple` output mode switches
125+
- Process pipeline input in the `process` block, not `end`
126+
- Let PowerShell's pipeline handle the collection if the user needs it

.github/prompts/prompt.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
Pester v4 to v5 Migration
2+
3+
**MIGRATE** the Pester test file `--FILEPATH--` from version 4 to version 5. **APPLY ALL CHANGES DIRECTLY TO THE FILE AND SAVE IT.**
4+
5+
Follow the migration guidelines in style.md. This is a PowerShell module test file.
6+
7+
Command name:
8+
--CMDNAME--
9+
10+
Parameters for this command:
11+
--PARMZ--
12+
13+
**IMPORTANT**: Write all changes directly to the file. Do not just describe the changes - implement them and save the updated file. Verify your changes adhere to the coding and migration guidelines before saving.

0 commit comments

Comments
 (0)