Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
a76568c
Add 7.4.14 changelog (#26998)
jshigetomi Mar 11, 2026
7498139
Update `Microsoft.PowerShell.PSResourceGet` version to 1.2.0 (#27003)
anamnavi Mar 11, 2026
9952b1c
Add &! ThreadJob background operator support
Copilot Jan 1, 2026
18e965a
Add tests for ThreadJob background operator
Copilot Jan 1, 2026
02340e5
Add exception handling for Start-ThreadJob cmdlet lookup
Copilot Jan 1, 2026
2f6da6e
Use specific exception types in catch blocks for Start-ThreadJob lookup
Copilot Jan 1, 2026
c613740
Fix compilation errors: move BackgroundThreadJob to ChainableAst and …
Copilot Jan 2, 2026
45bca2e
Move BackgroundThreadJob property to PipelineBaseAst base class
Copilot Jan 2, 2026
7445375
Address PR review feedback: improve tests and simplify exception hand…
Copilot Mar 11, 2026
d1d9b35
Fix binary-breaking change: move AmpersandExclaim token to end of enum
Copilot Mar 11, 2026
5bc1f38
Remove accidentally committed backup file
Copilot Mar 11, 2026
a81349f
Fix parser error with &! operator - set flags correctly
Copilot Mar 11, 2026
e2369fe
Fix &! operator recognition in PipelineRule switch statement
Copilot Mar 11, 2026
fd460ff
Fix missing backgroundThreadJob variable declaration in PipelineRule
Copilot Mar 11, 2026
e4f72c5
Fix ThreadJob detection by using GetCommand instead of GetCmdlet
Copilot Mar 11, 2026
5ab73a2
Fix compilation error: properly handle CommandInfo type checking
Copilot Mar 11, 2026
ae5b54c
Fix WorkingDirectory parameter error with Start-ThreadJob
Copilot Mar 11, 2026
6b7f510
Fix script block literal execution with &! operator
Copilot Mar 11, 2026
537695b
Fix compilation error: cast PipelineBaseAst to PipelineAst before acc…
Copilot Mar 11, 2026
f550669
Fix BackgroundThreadJob property not set on PipelineChainAst
Copilot Mar 11, 2026
36665dd
Apply review feedback: fix TypeNames checks, add try/finally cleanup,…
Copilot Mar 11, 2026
0f7124d
Fix parser CommandRule, scriptblock body extraction, and ThreadJob cm…
Copilot Mar 11, 2026
27f100f
Move AmpersandExclaim to Operator sections
kilasuit Mar 12, 2026
771b8d9
Apply PR review feedback: use GetScriptBlock() and HashSet for magic …
Copilot Mar 12, 2026
69cefb0
Move AmpersandExclaim to Operator section in PSToken
kilasuit Mar 12, 2026
8493245
Move AmpersandExclaim entries based on feedback
kilasuit Mar 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 77 additions & 0 deletions CHANGELOG/7.4.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,82 @@
# 7.4 Changelog

## [7.4.14]

### General Cmdlet Updates and Fixes

- Fix `PSMethodInvocationConstraints.GetHashCode` method (#26959)

### Tools

- Add merge conflict marker detection to `linux-ci` workflow and refactor existing actions to use reusable `get-changed-files` action (#26362)
- Add reusable `get-changed-files` action and refactor existing actions (#26361)
- Refactor analyze job to reusable workflow and enable on Windows CI (#26342)

### Tests

- Skip the flaky `Update-Help` test for the `PackageManagement` module (#26871)
- Fix `$PSDefaultParameterValues` leak causing tests to skip unexpectedly (#26869)
- Add GitHub Actions annotations for Pester test failures (#26800)
- Mark flaky `Update-Help` web tests as pending to unblock CI (#26805)
- Update the `Update-Help` tests to use `-Force` to remove read-only files (#26786)
- Fix merge conflict checker for empty file lists and filter `*.cs` files (#26387)
- Add markdown link verification for PRs (#26340)

### Build and Packaging Improvements

<details>

<summary>

<p>Update .NET SDK to 8.0.419</p>

</summary>

<ul>
<li>Update MaxVisitCount and MaxHashtableKeyCount if visitor safe value context indicates SkipLimitCheck is true (Internal 38882)</li>
<li>Hardcode Official templates (#26962)</li>
<li>Split TPN manifest and Component Governance manifest (#26961)</li>
<li>Correct the package name for .deb and .rpm packages (#26960)</li>
<li>Bring over all changes for MSIX packaging template (#26933)</li>
<li>.NET Resolution and Store Publishing Updates (#26930)</li>
<li>Update Application Insights package version to 2.23.0 (#26883)</li>
<li>Update metadata.json to update the Latest attribute with a better name (#26872)</li>
<li>Update <code>Get-ChangeLog</code> to handle backport PRs correctly (#26870)</li>
<li>Remove unused runCodesignValidationInjection variable from pipeline templates (#26868)</li>
<li>Refactor: Centralize xUnit tests into reusable workflow and remove legacy verification (#26864)</li>
<li>Fix buildinfo.json uploading for preview, LTS, and stable releases (#26863)</li>
<li>Fix macOS preview package identifier detection to use version string (#26774)</li>
<li>Update the macOS package name for preview releases to match the previous pattern (#26435)</li>
<li>Fix condition syntax for StoreBroker package tasks in MSIX pipeline (#26434)</li>
<li>Fix template path for rebuild branch check in package.yml (#26433)</li>
<li>Add rebuild branch support with conditional MSIX signing (#26418)</li>
<li>Move package validation to package pipeline (#26417)</li>
<li>Backport Store publishing improvements (#26401)</li>
<li>Fix path to metadata.json in channel selection script (#26399)</li>
<li>Optimize/split Windows package signing (#26413)</li>
<li>Improve ADO package build and validation across platforms (#26405)</li>
<li>Separate Store Automation Service Endpoints, Resolve AppID (#26396)</li>
<li>Fix the task name to not use the pre-release task (#26395)</li>
<li>Remove usage of fpm for DEB package generation (#26382)</li>
<li>Replace fpm with native macOS packaging tools (pkgbuild/productbuild) (#26344)</li>
<li>Replace fpm with native rpmbuild for RPM package generation (#26337)</li>
<li>Add log grouping to build.psm1 for collapsible GitHub Actions logs (#26363)</li>
<li>Convert Azure DevOps Linux Packaging pipeline to GitHub Actions workflow (#26336)</li>
<li>Integrate Windows packaging into windows-ci workflow using reusable workflow (#26335)</li>
<li>Add network isolation policy parameter to vPack pipeline (#26339)</li>
<li>GitHub Workflow cleanup (#26334)</li>
<li>Add build to vPack Pipeline (#25980)</li>
<li>Update vPack name (#26222)</li>
</ul>

</details>

### Documentation and Help Content

- Update Third Party Notices (#26892)

[7.4.14]: https://github.com/PowerShell/PowerShell/compare/v7.4.13...v7.4.14

## [7.4.13]

### Build and Packaging Improvements
Expand Down
2 changes: 1 addition & 1 deletion src/Modules/PSGalleryModules.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<ItemGroup>
<PackageReference Include="PowerShellGet" Version="2.2.5" />
<PackageReference Include="PackageManagement" Version="1.4.8.1" />
<PackageReference Include="Microsoft.PowerShell.PSResourceGet" Version="1.2.0-rc3" />
<PackageReference Include="Microsoft.PowerShell.PSResourceGet" Version="1.2.0" />
<PackageReference Include="Microsoft.PowerShell.Archive" Version="1.2.5" />
<PackageReference Include="PSReadLine" Version="2.4.5" />
<PackageReference Include="Microsoft.PowerShell.ThreadJob" Version="2.2.0" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ public static PSTokenType GetPSTokenType(Token token)
/* AndAnd */ PSTokenType.Operator,
/* OrOr */ PSTokenType.Operator,
/* Ampersand */ PSTokenType.Operator,
/* AmpersandExclaim */ PSTokenType.Operator,
/* Pipe */ PSTokenType.Operator,
/* Comma */ PSTokenType.Operator,
/* MinusMinus */ PSTokenType.Operator,
Expand Down Expand Up @@ -303,6 +304,7 @@ public static PSTokenType GetPSTokenType(Token token)
/* Hidden */ PSTokenType.Keyword,
/* Base */ PSTokenType.Keyword,
/* Default */ PSTokenType.Keyword,
/* Clean */ PSTokenType.Keyword,

#endregion Flags for keywords

Expand Down
49 changes: 47 additions & 2 deletions src/System.Management.Automation/engine/parser/Parser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5346,6 +5346,7 @@ private StatementAst FunctionDeclarationRule(Token functionToken)
case TokenKind.AndAnd:
case TokenKind.OrOr:
case TokenKind.Ampersand:
case TokenKind.AmpersandExclaim:
case TokenKind.Variable:
case TokenKind.SplattedVariable:
case TokenKind.HereStringExpandable:
Expand Down Expand Up @@ -5849,6 +5850,7 @@ private PipelineBaseAst PipelineChainRule()
Token currentChainOperatorToken = null;
Token nextToken = null;
bool background = false;
bool backgroundThreadJob = false;
while (true)
{
// Look for the next pipeline in the chain,
Expand Down Expand Up @@ -5938,6 +5940,24 @@ private PipelineBaseAst PipelineChainRule()
background = true;
goto default;

// ThreadJob background operator
case TokenKind.AmpersandExclaim:
SkipToken();
nextToken = PeekToken();

switch (nextToken.Kind)
{
case TokenKind.AndAnd:
case TokenKind.OrOr:
SkipToken();
ReportError(nextToken.Extent, nameof(ParserStrings.BackgroundOperatorInPipelineChain), ParserStrings.BackgroundOperatorInPipelineChain);
return new ErrorStatementAst(ExtentOf(currentPipelineChain ?? nextPipeline, nextToken.Extent));
}

background = true;
backgroundThreadJob = true;
goto default;

// No more chain operators -- return
default:
// If we haven't seen a chain yet, pass through the pipeline
Expand All @@ -5951,15 +5971,18 @@ private PipelineBaseAst PipelineChainRule()

// Set background on the pipeline AST
nextPipeline.Background = true;
nextPipeline.BackgroundThreadJob = backgroundThreadJob;
return nextPipeline;
}

return new PipelineChainAst(
var chainAst = new PipelineChainAst(
ExtentOf(currentPipelineChain.Extent, nextPipeline.Extent),
currentPipelineChain,
nextPipeline,
currentChainOperatorToken.Kind,
background);
chainAst.BackgroundThreadJob = backgroundThreadJob;
return chainAst;
}

// Assemble the new chain statement AST
Expand Down Expand Up @@ -6008,6 +6031,7 @@ private PipelineBaseAst PipelineRule(
Token nextToken = null;
bool scanning = true;
bool background = false;
bool backgroundThreadJob = false;
ExpressionAst expr = startExpression;
while (scanning)
{
Expand Down Expand Up @@ -6125,6 +6149,20 @@ private PipelineBaseAst PipelineRule(
background = true;
break;

case TokenKind.AmpersandExclaim:
if (!allowBackground)
{
// Handled by invoking rule
scanning = false;
continue;
}

SkipToken();
scanning = false;
background = true;
backgroundThreadJob = true;
break;

case TokenKind.Pipe:
SkipToken();
SkipNewlines();
Expand Down Expand Up @@ -6156,7 +6194,12 @@ private PipelineBaseAst PipelineRule(
return null;
}

return new PipelineAst(ExtentOf(startExtent, pipelineElements[pipelineElements.Count - 1]), pipelineElements, background);
var pipeline = new PipelineAst(ExtentOf(startExtent, pipelineElements[pipelineElements.Count - 1]), pipelineElements, background);
if (backgroundThreadJob)
{
pipeline.BackgroundThreadJob = true;
}
return pipeline;
}

private RedirectionAst RedirectionRule(RedirectionToken redirectionToken, RedirectionAst[] redirections, ref IScriptExtent extent)
Expand Down Expand Up @@ -6316,6 +6359,7 @@ private ExpressionAst GetCommandArgument(CommandArgumentContext context, Token t
case TokenKind.AndAnd:
case TokenKind.OrOr:
case TokenKind.Ampersand:
case TokenKind.AmpersandExclaim:
case TokenKind.MinusMinus:
case TokenKind.Comma:
UngetToken(token);
Expand Down Expand Up @@ -6520,6 +6564,7 @@ internal Ast CommandRule(bool forDynamicKeyword)
case TokenKind.AndAnd:
case TokenKind.OrOr:
case TokenKind.Ampersand:
case TokenKind.AmpersandExclaim:
UngetToken(token);
scanning = false;
continue;
Expand Down
13 changes: 11 additions & 2 deletions src/System.Management.Automation/engine/parser/ast.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5610,7 +5610,9 @@ public PipelineChainAst(
/// </returns>
public override Ast Copy()
{
return new PipelineChainAst(Extent, CopyElement(LhsPipelineChain), CopyElement(RhsPipeline), Operator, Background);
var copy = new PipelineChainAst(Extent, CopyElement(LhsPipelineChain), CopyElement(RhsPipeline), Operator, Background);
copy.BackgroundThreadJob = this.BackgroundThreadJob;
return copy;
}

internal override object Accept(ICustomAstVisitor visitor)
Expand Down Expand Up @@ -5675,6 +5677,11 @@ public virtual ExpressionAst GetPureExpression()
{
return null;
}

/// <summary>
/// Indicates that this pipeline should be run in the background as a ThreadJob.
/// </summary>
public bool BackgroundThreadJob { get; internal set; }
}

/// <summary>
Expand Down Expand Up @@ -5793,7 +5800,9 @@ public override ExpressionAst GetPureExpression()
public override Ast Copy()
{
var newPipelineElements = CopyElements(this.PipelineElements);
return new PipelineAst(this.Extent, newPipelineElements, this.Background);
var copy = new PipelineAst(this.Extent, newPipelineElements, this.Background);
copy.BackgroundThreadJob = this.BackgroundThreadJob;
return copy;
}

#region Visitors
Expand Down
11 changes: 7 additions & 4 deletions src/System.Management.Automation/engine/parser/token.cs
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,9 @@ public enum TokenKind
/// <summary>The null conditional index access operator '?[]'.</summary>
QuestionLBracket = 104,

/// <summary>The ThreadJob background operator '&amp;!'.</summary>
AmpersandExclaim = 106,

#endregion Operators

#region Keywords
Expand Down Expand Up @@ -881,7 +884,7 @@ public static class TokenTraits
/* QuestionQuestion */ TokenFlags.BinaryOperator | TokenFlags.BinaryPrecedenceCoalesce,
/* QuestionDot */ TokenFlags.SpecialOperator | TokenFlags.DisallowedInRestrictedMode,
/* QuestionLBracket */ TokenFlags.None,
/* Reserved slot 7 */ TokenFlags.None,
/* AmpersandExclaim */ TokenFlags.SpecialOperator | TokenFlags.ParseModeInvariant,
/* Reserved slot 8 */ TokenFlags.None,
/* Reserved slot 9 */ TokenFlags.None,
/* Reserved slot 10 */ TokenFlags.None,
Expand Down Expand Up @@ -1081,7 +1084,7 @@ public static class TokenTraits
/* QuestionQuestion */ "??",
/* QuestionDot */ "?.",
/* QuestionLBracket */ "?[",
/* Reserved slot 7 */ string.Empty,
/* AmpersandExclaim */ "&!",
/* Reserved slot 8 */ string.Empty,
/* Reserved slot 9 */ string.Empty,
/* Reserved slot 10 */ string.Empty,
Expand Down Expand Up @@ -1160,10 +1163,10 @@ public static class TokenTraits
static TokenTraits()
{
Diagnostics.Assert(
s_staticTokenFlags.Length == ((int)TokenKind.Clean + 1),
s_staticTokenFlags.Length == ((int)TokenKind.AmpersandExclaim + 1),
"Table size out of sync with enum - _staticTokenFlags");
Diagnostics.Assert(
s_tokenText.Length == ((int)TokenKind.Clean + 1),
s_tokenText.Length == ((int)TokenKind.AmpersandExclaim + 1),
"Table size out of sync with enum - _tokenText");
// Some random assertions to make sure the enum and the traits are in sync
Diagnostics.Assert(GetTraits(TokenKind.Begin) == (TokenFlags.Keyword | TokenFlags.ScriptBlockBlockName),
Expand Down
9 changes: 8 additions & 1 deletion src/System.Management.Automation/engine/parser/tokenizer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4975,12 +4975,19 @@ internal Token NextToken()
return ScanNumber(c);

case '&':
if (PeekChar() == '&')
c1 = PeekChar();
if (c1 == '&')
{
SkipChar();
return NewToken(TokenKind.AndAnd);
}

if (c1 == '!')
{
SkipChar();
return NewToken(TokenKind.AmpersandExclaim);
}

return NewToken(TokenKind.Ampersand);

case '|':
Expand Down
Loading
Loading