Mark Export-Csv -Path and -LiteralPath parameters as mandatory in separate parameter sets (#27670) - #27856
Open
Vedaang Sharma (gtathelegend) wants to merge 1 commit into
Conversation
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
Copilot started reviewing on behalf of
Vedaang Sharma (gtathelegend)
August 14, 2026 19:51
View session
Author
|
@microsoft-github-policy-service agree |
Open
5 tasks
Contributor
There was a problem hiding this comment.
Pull request overview
This pull request updates Export-Csv to make -Path and -LiteralPath declaratively mandatory in mutually exclusive parameter sets, so PowerShell’s parameter binder (and Get-Command metadata) enforces the required path semantics instead of relying on imperative runtime checks. It also simplifies delimiter selection logic and adds new validation/tests around delimiter/culture and literal path behavior.
Changes:
- Mark
Export-Csv-Pathand-LiteralPathasMandatory = truein separate parameter sets (PathvsLiteralPath) and remove the previous runtime “must specify exactly one” validation. - Add explicit validation preventing
-Delimiterand-UseCulturefrom being specified together, and simplify delimiter resolution logic. - Expand Pester coverage for
-LiteralPathscenarios, parameter set metadata, and new validation behavior.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
src/Microsoft.PowerShell.Commands.Utility/commands/utility/CsvCommands.cs |
Adds mandatory Path/LiteralPath parameter sets for Export-Csv, removes old path validation, and introduces delimiter/culture mutual-exclusion + simplified delimiter selection. |
src/Microsoft.PowerShell.Commands.Utility/resources/CsvCommandStrings.resx |
Adds a localized error string for delimiter/culture mutual exclusion. |
test/powershell/Modules/Microsoft.PowerShell.Utility/Export-Csv.Tests.ps1 |
Updates/extends tests for binder-enforced path requirements, parameter-set ambiguity, literal-path behavior, and delimiter/culture validation. |
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+125
to
+130
| if (this.MyInvocation.BoundParameters.ContainsKey(nameof(Delimiter)) && this.MyInvocation.BoundParameters.ContainsKey(nameof(UseCulture))) | ||
| { | ||
| InvalidOperationException exception = new(CsvCommandStrings.CannotSpecifyDelimiterAndUseCulture); | ||
| ErrorRecord errorRecord = new(exception, "CannotSpecifyDelimiterAndUseCulture", ErrorCategory.InvalidData, null); | ||
| this.ThrowTerminatingError(errorRecord); | ||
| } |
Comment on lines
25
to
+27
| It "Should throw if an output file isn't specified" { | ||
| { $testObject | Export-Csv -ErrorAction Stop } | Should -Throw -ErrorId "CannotSpecifyPathAndLiteralPath,Microsoft.PowerShell.Commands.ExportCsvCommand" | ||
| { $testObject | Export-Csv -ErrorAction Stop } | Should -Throw | ||
| } |
Comment on lines
+31
to
33
| [Parameter(Position = 1)] | ||
| [ValidateNotNull] | ||
| public char Delimiter { get; set; } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
This PR resolves issue #27670 where
Export-Csvdid not declare-Pathand-LiteralPathas mandatory parameters or assign them to parameter sets in command metadata.Previously,
Export-Csvrelied on imperative runtime validation inBeginProcessing()andCreateFileStream()to throw a customCannotSpecifyPathAndLiteralPathexception when path parameters were missing or mutually specified. This prevented PowerShell's parameter binder from enforcing these requirements declaratively.Motivation
Relying on manual imperative checks inside cmdlet processing bypasses PowerShell's engine parameter binding framework:
Get-Command Export-Csvmetadata did not report-Pathor-LiteralPathas mandatory parameters.Aligning
Export-Csvwith sibling utility cmdlets such asExport-ClixmlandOut-Fileby marking-Pathand-LiteralPathasMandatory = truein mutually exclusive parameter sets (PathandLiteralPath) provides declarative binding, accurate command metadata, and consistent parameter-set behavior.Investigation
Inspection of existing PowerShell utility cmdlets established clear precedents:
Export-Clixml(src/Microsoft.PowerShell.Commands.Utility/commands/utility/XmlCommands.cs) uses separate path parameter sets with mandatory-Pathand-LiteralPathparameters.Out-File(src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/out-file/Out-File.cs) similarly uses separate parameter sets with mandatory path parameters.Export-Csvalready declaredDefaultParameterSetName = "Path"on its[Cmdlet]attribute, but its path parameters did not explicitly declareParameterSetNameandMandatory = true.By declaring
PathandLiteralPathas mandatory parameters in separate parameter sets:AmbiguousParameterSetbinding error.The change also required reviewing the existing delimiter/culture parameter-set handling.
ImportExportCSVHelper.SetDelimiter()previously depended on parameter-set names associated with the older delimiter/culture matrix. The delimiter calculation was simplified so that it derives the effective delimiter fromUseCulture, an explicitly supplied delimiter, or the default comma, independently of whetherPathorLiteralPathis selected.Implementation
In
src/Microsoft.PowerShell.Commands.Utility/commands/utility/CsvCommands.cs:ExportCsvCommand.Path[Parameter(Position = 0, Mandatory = true, ParameterSetName = "Path")]_specifiedPathtracking field.ExportCsvCommand.LiteralPath[Parameter(Mandatory = true, ParameterSetName = "LiteralPath")]_isLiteralPath = truein the setter.Path validation
!(_specifiedPath ^ _isLiteralPath)validation.CannotSpecifyPathAndLiteralPathexception path._path == nullruntime validation fromCreateFileStream().Delimiter and culture handling
-Delimiterand-UseCulturefrom being specified together.ImportExportCSVHelper.SetDelimiter()to calculate the effective delimiter independently of the selected path parameter set.In
src/Microsoft.PowerShell.Commands.Utility/resources/CsvCommandStrings.resx:CannotSpecifyDelimiterAndUseCultureerror message.Tests
In
test/powershell/Modules/Microsoft.PowerShell.Utility/Export-Csv.Tests.ps1:-Pathand-LiteralPathproducesAmbiguousParameterSet.-LiteralPathwith-Delimiter.-LiteralPathwith-UseCulture.[output].csv.Get-Command Export-Csv.-LiteralPathby itself.-Delimiterand-UseCulturecannot be specified together.Verification
powershell-win-core(net11.0\win7-x64) built successfully with 0 errors.test/powershell/Modules/Microsoft.PowerShell.Utility/Export-Csv.Tests.ps1-Pathworks when specified individually.-LiteralPathworks when specified individually.Get-Command Export-Csvreports both path parameters as mandatory in their respective parameter sets.Compatibility / Behavior
-Pathand-LiteralPathnow fails during parameter binding because the selected path parameter is mandatory.-Pathand-LiteralPathnow fails during parameter binding withAmbiguousParameterSet.-Pathand-LiteralPathinvocation patterns continue to work.-LiteralPathcontinues to preserve literal path semantics.-Pathand-LiteralPathis now represented directly through parameter sets.Files Changed
src/Microsoft.PowerShell.Commands.Utility/commands/utility/CsvCommands.cssrc/Microsoft.PowerShell.Commands.Utility/resources/CsvCommandStrings.resxtest/powershell/Modules/Microsoft.PowerShell.Utility/Export-Csv.Tests.ps1Issue
Fixes #27670