Contribution Review Guide
Three pull requests addressing 3 open issues — 12 files changed across the PowerShell engine, cmdlets, and CIM infrastructure.
Overview
Each card links to its detailed section below. All changes are built and tested against the latest master.
PR A — UUID v7 for New-Guid #27033
New-Guid from UUID v4 to v7 per
#24895.
WG approved — no switches needed.
UUID v7 (RFC 9562) embeds a millisecond-precision
timestamp, making GUIDs monotonically sortable — ideal for database keys and distributed systems.
Guid.CreateVersion7() is available since .NET 9; PowerShell targets .NET 11.
What changed
| File | Change |
|---|---|
NewGuidCommand.cs |
Guid.NewGuid() → Guid.CreateVersion7() |
New-Guid.Tests.ps1 |
Added version-nibble test: position 14 == 7 |
Before / After
// Before (line 52)
guid = Empty.ToBool() ? Guid.Empty : Guid.NewGuid();
// After
guid = Empty.ToBool() ? Guid.Empty : Guid.CreateVersion7();
New Pester test
It "Should generate a UUID v7" {
$guid = New-Guid
$guid.ToString()[14] | Should -BeExactly '7'
}
Why UUID string position 14?
UUID format: xxxxxxxx-xxxx-Vxxx-xxxx-xxxxxxxxxxxx
The V at 0-indexed position 14 is the version nibble. For v7, it's 7.
Related
- Previous attempt: #26256 (Copilot, closed/stale)
- WG decision: @SteveL-MSFT comment
PR B — Fix -Switch:$false Handling #27034
The bug
When -ListAvailable:$false or -Stack:$false is passed, PowerShell’s
parameter binder selects the switch’s ParameterSetName but the cmdlet code branches on the
set name without checking the actual switch value.
| Cmdlet | Bug behavior | Expected |
|---|---|---|
Get-Culture -ListAvailable:$false |
Dumps all ~800 cultures | Returns current culture |
Get-Location -Stack:$false |
Shows location stack | Returns current directory |
Fix pattern
Wrap the switch-path code in if (SwitchParam) with an else fallback to default behavior.
// Before
case ListAvailableParameterSet:
foreach (var ci in CultureInfo.GetCultures(...))
WriteObject(ci);
break;
// After
case ListAvailableParameterSet:
if (ListAvailable)
{
foreach (var ci in CultureInfo.GetCultures(...))
WriteObject(ci);
}
else
{
WriteObject(Host.CurrentCulture);
}
break;
What changed
| File | Change |
|---|---|
GetCultureCommand.cs | Guard ListAvailableParameterSet with if (ListAvailable) |
Navigation.cs | Guard StackParameterSet with if (Stack) |
Get-Culture.Tests.ps1 | Add -ListAvailable:$false test |
Get-Location.Tests.ps1 | Add -Stack:$false test |
PR C — PVS-Studio Static Analyzer Fixes #27035
| Item | File | Bug | Severity | Fix |
|---|---|---|---|---|
| 9 | StringUtil.cs |
?? operator precedence — appendStr length silently ignored |
Medium | Added parentheses |
| 2 | CimCmdlets/Utils.cs |
Unsafe double-checked locking | Low | Added volatile |
| 6 | ConsoleHost.cs |
RunspaceRef used before null check |
High | Moved null check first |
| 1 | CimGetInstance.cs |
GetCimInstanceParameter can return null, dereferenced |
High | Added null guard |
| 5 | ShowCommandCommandInfo.cs |
Members["Module"] accessed without null-conditional |
Medium | Added ?. |
| 7 | typeDataQuery.cs |
vd.mainControl accessed when vd == null |
High | Split into separate checks |
Before / After for each item
Item 9 — Operator precedence in StringUtil.cs
// Before (line 246) — ?? has lower priority than +
int capacity = length + prependStr?.Length ?? 0 + appendStr?.Length ?? 0;
// After — explicit grouping
int capacity = length + (prependStr?.Length ?? 0) + (appendStr?.Length ?? 0);
Item 2 — Missing volatile in Utils.cs
// Before
private static bool logInitialized = false;
// After
private static volatile bool logInitialized = false;
Item 6 — Null check order in ConsoleHost.cs
// Before — RunspaceRef used before null check
if (_isRunspacePushed)
return RunspaceRef.OldRunspace as LocalRunspace;
if (RunspaceRef == null) return null;
// After — null check first
if (RunspaceRef == null) return null;
if (_isRunspacePushed)
return RunspaceRef.OldRunspace as LocalRunspace;
Item 1 — Null dereference in CimGetInstance.cs
// Before — instance used without null check
CimInstance instance = GetCimInstanceParameter(cmdlet);
nameSpace = instance.CimSystemProperties.Namespace;
// After — null guard added
CimInstance instance = GetCimInstanceParameter(cmdlet);
if (instance != null)
{
nameSpace = instance.CimSystemProperties.Namespace;
...
}
Item 5 — Null access in ShowCommandCommandInfo.cs
// Before
this.Module = other.Members["Module"].Value as ShowCommandModuleInfo;
// After
this.Module = other.Members["Module"]?.Value as ShowCommandModuleInfo;
Item 7 — Null dereference in typeDataQuery.cs
// Before — vd.mainControl accessed in both branches
if (vd == null || mainControlType != vd.mainControl.GetType())
{
ActiveTracer.WriteLine("NOT MATCH ...",
ControlBase.GetControlShapeName(vd.mainControl), ...);
}
// After — separate checks
if (vd == null)
{
ActiveTracer.WriteLine("NOT MATCH null view definition");
continue;
}
if (mainControlType != vd.mainControl.GetType())
{
ActiveTracer.WriteLine("NOT MATCH ...", ...);
continue;
}
Skipped Items (with rationale)
Four items from #25289 were intentionally left for maintainer guidance.
| Item | File | Status | Why |
|---|---|---|---|
| 3 | GetEventCommand.cs |
Skipped | suppressOpener has no format placeholders — may be intentional. Needs maintainer input. |
| 4 | New-Object.cs |
Skipped | Switch doesn’t cover FullLanguage — may be a deliberate fall-through. Needs WG guidance. |
| 8 | xmlSerializer.autogen.cs |
Skipped | Auto-generated file. Fix would be overwritten on next generation. |
| 10 | Command.cs |
Skipped | PipelineResultTypes Flags enum values — changing is a public API breaking change. |
Test Results
| PR | Suite | Result | Details |
|---|---|---|---|
| A | Pester — New-Guid | 9/9 pass | 8 existing + 1 new v7 nibble test |
| A | Smoke test | pass | (New-Guid).ToString()[14] returns 7 |
| B | Pester — Get-Culture | 12/12 pass | 11 existing + 1 new -ListAvailable:$false |
| B | Pester — Get-Location | 2/2 pass | 1 existing + 1 new -Stack:$false |
| B | Smoke test | pass | Both cmdlets return correct default with :$false |
| C | Full build | 0 errors | Clean compile, all 6 changes verified |