Invoke-Command $using improvements #24025
Open
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.
PR Summary
Always use the v5.1 $using: logic when dealing with any connection type that is not based on the WSManConnectionInfo. This allows the caller to use the more advanced $using features like vars with special names, $using vars inside sub scopes and more. WSMan based connections might still communicate with older versions but as the oldest supported version is v3 on Server 2012 we don't need to keep the default as v2 to support some of the newer features.
PR Context
There are three different ways that
Invoke-Command
deals with$using:
inside a ScriptBlock:$using:var
to$__using_var
and modifies the param block to pass in that variable$using:var
and passes it to the remote pipeline through--%
$using:
in child scopesThe V2 method is quite rudimentary, it fails when using a variable with an invalid char in like
-
, or in a very improbable scenario someone named their var as$__using_var
themselves. The-
problem is typically encountered when you try to inject a function into the scriptblock, for example this fails todayThe workaround is to store the function in an intermediate var or define the function without
-
in the name:The V3/4, V5 logic works just fine with vars with special chars in the name
The current logic for determining what logic to use is as follows
NewProcessConnectionInfo
use V5Start-Job
or if using-Session $s
where the$s
is fromNew-PSSession -UseWindowsPowerShell
PSSession
through the-Session
parameter use V2PSSession
supports disconnection operationsPSVersionTable.PSVersion
to determine the versionThis means that V3/4, V5 is only used when the
PSSession
fromNew-PSSession -UseWindowsPowerShell
orNew-PSSession -ComputerName ...
is given toInvoke-Command -Session ...
. The more common scenarios likeInvoke-Command -ComputerName ...
orInvoke-Command -HostName ...
will always use the old V2 logic and thus cannot use the newer$using:
features.This PR simplifies the checks to set the baseline to V3/4 for a WSMan based connection and treat the rest of the connection types as V5. This is because only the WSMan connection was supported before 5.1 and can guarantee the target is PowerShell 5.1 or newer. The baseline for WSMan was set to V3/4 as V2 was last in box with Windows 7/Server 2008/08 R2 which is end of life. V3/4 is also strictly end of life but considering it's still supported in Azure I didn't think it was time to drop that just yet.
PR Checklist
.h
,.cpp
,.cs
,.ps1
and.psm1
files have the correct copyright headerWIP:
or[ WIP ]
to the beginning of the title (theWIP
bot will keep its status check atPending
while the prefix is present) and remove the prefix when the PR is ready.$using:
- [ ] Issue filed:
(which runs in a different PS Host).