Skip to content

Invoke-Command: improve handling of variables with $using: expression#16113

Merged
rjmholt merged 3 commits into
PowerShell:masterfrom
dwtaber:InvokeCommandFixUsingExpressionsWithQualifiedVarPath
Oct 6, 2021
Merged

Invoke-Command: improve handling of variables with $using: expression#16113
rjmholt merged 3 commits into
PowerShell:masterfrom
dwtaber:InvokeCommandFixUsingExpressionsWithQualifiedVarPath

Conversation

@dwtaber

@dwtaber dwtaber commented Sep 16, 2021

Copy link
Copy Markdown
Contributor

PR Summary

This PR improves Invoke-Command's handling of cases that combine $using: expressions with variable namespace notation when the -ComputerName parameter is used.
Fixes #9204
Fixes #16019

PR Context

When the -ComputerName parameter is used, Invoke-Command is unable to check which version of PowerShell is available on the remote computer and assumes v2.0. Because PowerShell 2.0 can't parse $using: expressions, the ScriptBlock is modified before sending, with $using: variables renamed to replace the $using: expression with $__using_. Currently, the code that renames these variables doesn't check whether the variable path is qualified. In cases where variable namespace notation is used, this code produces variable names like $__using_env:foo, preventing the remote computer from parsing the variables correctly. The changes in this PR add handling for qualified variable paths, producing variable names like $__using_env_foo

This PR does not fix all issues with the handling of $using: expressions. Variable names that include special characters still aren't parsed correctly, for instance. Since a user technically could name a variable $__using_env_foo, this might be considered an "unlikely grey area" breaking change. Long-term, it might be worth reconsidering how Invoke-Command handles the -ComputerName parameter; always falling back to v2.0 seems unnecessarily restrictive.

PR Checklist

@dwtaber dwtaber requested a review from daxian-dbw as a code owner September 16, 2021 15:35
@ghost ghost assigned rjmholt Sep 16, 2021
@ghost

ghost commented Sep 16, 2021

Copy link
Copy Markdown

CLA assistant check
All CLA requirements met.

@iSazonov

Copy link
Copy Markdown
Collaborator

When the -ComputerName parameter is used, Invoke-Command is unable to check which version of PowerShell is available on the remote computer and assumes v2.0.

I wonder why we need the workaround if we can prepare full fix.

If I understand correctly, with ComputerName we create new runspace but do not open it in CreateHelpersForSpecifiedComputerNames(), as result we can not detect remote PowerShell version. So I guess we need to open the new runspace in CreateHelpersForSpecifiedComputerNames().

@dwtaber

dwtaber commented Sep 16, 2021

Copy link
Copy Markdown
Contributor Author

When the -ComputerName parameter is used, Invoke-Command is unable to check which version of PowerShell is available on the remote computer and assumes v2.0.

I wonder why we need the workaround if we can prepare full fix.

If I understand correctly, with ComputerName we create new runspace but do not open it in CreateHelpersForSpecifiedComputerNames(), as result we can not detect remote PowerShell version. So I guess we need to open the new runspace in CreateHelpersForSpecifiedComputerNames().

Implementing proper version detection for the -ComputerName parameter seems preferable to me as well. Since the current behavior (falling back to v2) is documented at various points in the code comments, it seemed to be an intentional design choice, maybe based on factors I wasn't aware of. Honestly, this is the first pull request I've submitted, and I didn't want to overstep with a potentially significant change to how Invoke-Command connections work, so I went with a more conservative fix, but I'm not married to it.

@dwtaber

dwtaber commented Sep 22, 2021

Copy link
Copy Markdown
Contributor Author

Can I get some guidance on the two tests that have failed? It looks like Invoke-WebRequest failed to reach a URI, but I can't see how my changes would have affected that cmdlet. Is it possible the resource was just unavailable when the test was run?

I'd also appreciate any suggestions on writing a Pester test for this issue. I don't think any of the current remoting tests target a remote computer, so they don't offer much guidance. So far I've been testing against computers available to me, but obviously that's too context-dependent to be of use to anyone else. Are there any designated endpoints for this sort of testing?

@iSazonov

Copy link
Copy Markdown
Collaborator

I restarted CI-static.

@ghost ghost added the Review - Needed The PR is being reviewed label Sep 30, 2021
@ghost

ghost commented Sep 30, 2021

Copy link
Copy Markdown

This pull request has been automatically marked as Review Needed because it has been there has not been any activity for 7 days.
Maintainer, please provide feedback and/or mark it as Waiting on Author

if (varAst != null)
{
string varName = varAst.VariablePath.UserPath;
var varPath = varAst.VariablePath;

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.

Please use the type name instead of var here

if (astStartOffset >= endOffset) { break; }

string varName = varAst.VariablePath.UserPath;
var varPath = varAst.VariablePath;

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.

Ditto

foreach (var varAst in usingVariables)
{
string varName = varAst.VariablePath.UserPath;
var varPath = varAst.VariablePath;

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.

Ditto

@rjmholt

rjmholt commented Oct 5, 2021

Copy link
Copy Markdown
Collaborator

Not sure what the state of testing is for $using: vars, but would be good if we had some to cover the code path this change affects

@ghost ghost removed the Review - Needed The PR is being reviewed label Oct 5, 2021
@rjmholt rjmholt requested a review from PaulHigin October 5, 2021 22:19
@rjmholt

rjmholt commented Oct 5, 2021

Copy link
Copy Markdown
Collaborator

Tagging @PaulHigin for review as well

@dwtaber

dwtaber commented Oct 6, 2021

Copy link
Copy Markdown
Contributor Author

Git/GitHub novice question: when updating from the master branch, I should have used a fast-forward merge to avoid creating a separate merge commit, right? How much of a problem is it that I, uh, didn't do that?

@iSazonov

iSazonov commented Oct 6, 2021

Copy link
Copy Markdown
Collaborator

@dwtaber Never mind - we use "squash and merge" to get one commit in main branch.

@PaulHigin PaulHigin left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Changes look good to me.

@rjmholt rjmholt enabled auto-merge (squash) October 6, 2021 17:43
@rjmholt rjmholt merged commit 53ac646 into PowerShell:master Oct 6, 2021
@dwtaber dwtaber deleted the InvokeCommandFixUsingExpressionsWithQualifiedVarPath branch October 6, 2021 20:56
@iSazonov iSazonov added the CL-General Indicates that a PR should be marked as a general cmdlet change in the Change Log label Oct 7, 2021
@iSazonov iSazonov modified the milestones: 7.2.0-preview.10, 7.2.0-rc.1 Oct 7, 2021
@dwtaber

dwtaber commented Oct 28, 2021

Copy link
Copy Markdown
Contributor Author

@rjmholt, judging by its file history, it looks like System.Management.Automation/engine/parser/ast.cs wasn't updated during the merge, so the bug addressed by this PR still exists.

@daxian-dbw daxian-dbw removed this from the 7.2.0-rc.1 milestone Oct 28, 2021
@daxian-dbw

daxian-dbw commented Oct 28, 2021

Copy link
Copy Markdown
Member

@dwtaber Changes from this PR exists in the master branch. The PR will not be included in 7.2.0-rc.1 though. It will be included in 7.3.0-preview.1.

@dwtaber

dwtaber commented Oct 28, 2021

Copy link
Copy Markdown
Contributor Author

@dwtaber Changes from this PR exists in the master branch. The PR will not be included in 7.2.0-rc.1 though. It will be included in 7.3.0-preview.1.

Ah, okay. Thanks for clarifying!

@ghost

ghost commented Dec 16, 2021

Copy link
Copy Markdown

🎉v7.3.0-preview.1 has been released which incorporates this pull request.:tada:

Handy links:

@God-damnit-all

God-damnit-all commented Dec 23, 2021

Copy link
Copy Markdown
Contributor

I really wish this had made it into the stable release of 7.2, I try to avoid using preview-exclusive stuff in my code, so having to wait for 7.3's stable release really sucks.

Is there any chance this could be slipped into a 7.2 build, i.e. 7.2.2?

@TravisEz13

Copy link
Copy Markdown
Member

@PowerShell/powershell-maintainers
We only take security fixes and regression to LTS. This is appropriate for 7.3. Rejecting back-port.

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

8 participants