Skip to content

Fix using expression for invalid property#27349

Open
jborean93 wants to merge 2 commits into
PowerShell:masterfrom
jborean93:using-exception
Open

Fix using expression for invalid property#27349
jborean93 wants to merge 2 commits into
PowerShell:masterfrom
jborean93:using-exception

Conversation

@jborean93
Copy link
Copy Markdown
Collaborator

PR Summary

Fixes the using expression builder when encountering a using expression with invalid property. Previously such a property would stop the using builder from working on the remaining using statements while ignoring the error. From this change it will still ignore the error but continue working on the remaining expressions.

PR Context

Fixes: #27340

Currently if a using expression throws an error, like an invalid property, when building the using expression it would stop the using value builder from processing the remaining expressions. With this change it instead still continues to process the remaining expressions while still keeping the invalid one as $null like before.

This fixes this statement:

$var1 = 1
$var2 = 2
$var3 = 3
1 | ForEach-Object -Parallel {
    Write-Host "var1 $using:var1"
    Write-Host "var2 $($using:var2.InvalidProp)"
    Write-Host "var3 $using:var3"
}
var1 1
InvalidOperation: 
Line |
   3 |      Write-Host "var2 $($using:var2.InvalidProp)"
     |                         ~~~~~~~~~~~~~~~~~~~~~~~
     | A Using variable cannot be retrieved. A Using variable can be used only with Invoke-Command, Start-Job, or InlineScript in the script workflow. When it is used with Invoke-Command, the Using variable is valid only if the script block is invoked on a remote computer.
var2 
InvalidOperation: 
Line |
   4 |      Write-Host "var3 $using:var3"
     |      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | A Using variable cannot be retrieved. A Using variable can be used only with Invoke-Command, Start-Job, or InlineScript in the script workflow. When it is used with Invoke-Command, the Using variable is valid only if the script block is invoked on a remote computer.

With the changes here it now becomes

var1 1
var2 
var3 3

This better reflects how the same statement would work in a normal invocation with the same vars outside of $using:.

$var1 = 1
$var2 = 2
$var3 = 3
& {
    Write-Host "var1 $var1"
    Write-Host "var2 $($var2.InvalidProp)"
    Write-Host "var3 $var3"
}

# var1 1
# var2 
# var3 3

The only exception to this was if the inner scriptblock had enabled strict mode but the existing logic isn't equipped to deal with this as it already ignores errors on the client side. All this PR does is to continue resolving the remaining expressions rather than leaving it as unset.

PR Checklist

Fixes the using expression builder when encountering a using expression
with invalid property. Previously such a property would stop the using
builder from working on the remaining using statements while ignoring
the error. From this change it will still ignore the error but continue
working on the remaining expressions.
@jborean93 jborean93 requested a review from a team as a code owner April 24, 2026 00:12
Copilot AI review requested due to automatic review settings April 24, 2026 00:12
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes $using: value collection so that a failure to evaluate one using expression (e.g., invalid property access) does not prevent subsequent $using: expressions from being collected. This aligns remoting and ForEach-Object -Parallel behavior with normal script evaluation expectations and addresses #27340.

Changes:

  • Adjusted $using: value collection to handle per-expression failures and continue processing remaining using expressions.
  • Added regression tests for remoting loopback and ForEach-Object -Parallel to ensure subsequent $using: references still resolve when one using expression is invalid.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
src/System.Management.Automation/engine/runtime/ScriptBlockToPowerShell.cs Moves exception handling to per-using-expression evaluation so later $using: values are still collected.
test/powershell/engine/Remoting/RemoteSession.Basic.Tests.ps1 Adds remoting regression test to ensure invalid $using: property access doesn’t break subsequent $using: references.
test/powershell/Modules/Microsoft.PowerShell.Utility/Foreach-Object-Parallel.Tests.ps1 Adds ForEach-Object -Parallel regression test covering the same scenario.

Comment thread test/powershell/engine/Remoting/RemoteSession.Basic.Tests.ps1 Outdated
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@iSazonov iSazonov added the CL-General Indicates that a PR should be marked as a general cmdlet change in the Change Log label Apr 24, 2026
{
if (rte.ErrorRecord.FullyQualifiedErrorId.Equals("VariableIsUndefined", StringComparison.Ordinal))
{
throw InterpreterError.NewInterpreterException(
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we simply re-throw?

throw;

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure, I just re-used what was already there but haven't actually looked deeper into what the NewInterpreterException is doing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CL-General Indicates that a PR should be marked as a general cmdlet change in the Change Log

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Unexecuted null refs in remote sessions cause variable resets

3 participants