diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WriteProgressCmdlet.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WriteProgressCmdlet.cs index fd5476751ad..0751954c54e 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WriteProgressCmdlet.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WriteProgressCmdlet.cs @@ -17,7 +17,6 @@ public sealed class WriteProgressCommand : PSCmdlet /// [Parameter( Position = 0, - Mandatory = true, HelpMessageBaseName = HelpMessageBaseName, HelpMessageResourceId = "ActivityParameterHelpMessage")] public string Activity { get; set; } @@ -96,7 +95,29 @@ protected override void ProcessRecord() { - ProgressRecord pr = new(Id, Activity, Status); + ProgressRecord pr; + if (string.IsNullOrEmpty(Activity)) + { + if (!Completed) + { + ThrowTerminatingError(new ErrorRecord( + new ArgumentException("Missing value for mandatory parameter.", nameof(Activity)), + "MissingActivity", + ErrorCategory.InvalidArgument, + Activity)); + return; + } + else + { + pr = new(Id); + pr.StatusDescription = Status; + } + } + else + { + pr = new(Id, Activity, Status); + } + pr.ParentActivityId = ParentId; pr.PercentComplete = PercentComplete; pr.SecondsRemaining = SecondsRemaining; diff --git a/src/System.Management.Automation/engine/ProgressRecord.cs b/src/System.Management.Automation/engine/ProgressRecord.cs index cd5b33107aa..c9e0008a53d 100644 --- a/src/System.Management.Automation/engine/ProgressRecord.cs +++ b/src/System.Management.Automation/engine/ProgressRecord.cs @@ -59,6 +59,25 @@ class ProgressRecord this.status = statusDescription; } + /// + /// Initializes a new instance of the ProgressRecord class and defines the activity Id. + /// + /// + /// A unique numeric key that identifies the activity to which this record applies. + /// + public + ProgressRecord(int activityId) + { + if (activityId < 0) + { + // negative Ids are reserved to indicate "no id" for parent Ids. + + throw PSTraceSource.NewArgumentOutOfRangeException(nameof(activityId), activityId, ProgressRecordStrings.ArgMayNotBeNegative, "activityId"); + } + + this.id = activityId; + } + /// /// Cloning constructor (all fields are value types - can treat our implementation of cloning as "deep" copy) /// @@ -488,9 +507,13 @@ internal static ProgressRecord FromPSObjectForRemoting(PSObject progressAsPSObje /// This object as a PSObject property bag. internal PSObject ToPSObjectForRemoting() { - PSObject progressAsPSObject = RemotingEncoder.CreateEmptyPSObject(); + // Activity used to be mandatory but that's no longer the case. + // We ensure the string has a value to maintain compatibility with older versions. + string activity = string.IsNullOrEmpty(Activity) ? " " : Activity; - progressAsPSObject.Properties.Add(new PSNoteProperty(RemoteDataNameStrings.ProgressRecord_Activity, this.Activity)); + PSObject progressAsPSObject = RemotingEncoder.CreateEmptyPSObject(); + + progressAsPSObject.Properties.Add(new PSNoteProperty(RemoteDataNameStrings.ProgressRecord_Activity, activity)); progressAsPSObject.Properties.Add(new PSNoteProperty(RemoteDataNameStrings.ProgressRecord_ActivityId, this.ActivityId)); progressAsPSObject.Properties.Add(new PSNoteProperty(RemoteDataNameStrings.ProgressRecord_StatusDescription, this.StatusDescription)); diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/Write-Progress.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/Write-Progress.Tests.ps1 index 97fd19da1b8..25770eb9a67 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/Write-Progress.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/Write-Progress.Tests.ps1 @@ -1,10 +1,6 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. Describe "Write-Progress DRT Unit Tests" -Tags "CI" { - It "Should be able to throw exception when missing mandatory parameters" { - { Write-Progress $null } | Should -Throw -ErrorId 'ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.WriteProgressCommand' - } - It "Should be able to throw exception when running Write-Progress with bad percentage" { { Write-Progress -Activity 'myactivity' -Status 'mystatus' -percent 101 } | Should -Throw -ErrorId 'ParameterArgumentValidationError,Microsoft.PowerShell.Commands.WriteProgressCommand' @@ -33,4 +29,8 @@ Describe "Write-Progress DRT Unit Tests" -Tags "CI" { { Write-Progress -Activity $activity -Status ('b' * ([console]::WindowWidth + 1)) -Id 1 } | Should -Not -Throw Write-Progress -Activity $activity -Id 1 -Completed } + + It 'Should be able to complete a progress record with no activity specified' { + { Write-Progress -Completed } | Should -Not -Throw + } }