$MyInvocation.MyCommand.Name becomes null in Where-Object block
See original GitHub issueIssue description: Unable to use $MyInvocation.MyCommand.Name in Where-Object block as it becomes null. ForEach and For-EachObject works fine. I see this only with Where-Object.
I understand there are workarounds but just want to know if this is expected behavior or not as I was not able to find document that describes scope in Where-Object.
Steps to reproduce
Copy the following script to test.ps1
1 | Where-Object{
Write-Host('MyInvocation in Where-Object: ' + $MyInvocation.MyCommand.Name)
}
1 | ForEach-Object{
Write-Host('MyInvocation in ForEach-Object: ' + $MyInvocation.MyCommand.Name)
}
ForEach($FileName in 1){
Write-Host('MyInvocation in ForEach: ' + $MyInvocation.MyCommand.Name)
}
Then run
.\test.ps1
Expected behavior
## Expected output in case script name is test.ps1.
MyInvocation in Where-Object: test.ps1
MyInvocation in ForEach-Object: test.ps1
MyInvocation in ForEach: test.ps1
Actual behavior
## Expected output in case script name is test.ps1.
MyInvocation in Where-Object: <-------- $MyInvocation.MyCommand.Name becomes null
MyInvocation in ForEach-Object: test.ps1
MyInvocation in ForEach: test.ps1
Environment data
> $PSVersionTable
Name Value
---- -----
PSVersion 6.2.1
PSEdition Core
GitCommitId 6.2.1
OS Microsoft Windows 10.0.18362
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
Issue Analytics
- State:
- Created 4 years ago
- Comments:16 (8 by maintainers)
Top Results From Across the Web
$MyInvocation.MyCommand.Path returning NULL
$MyInvocation.MyCommand.Path will only return path if called from the $script: scope . See $MyInvocation.MyCommand.Path is $null in PowerGUI ...
Read more >$MyInvocation.MyCommand object is set to null when you ...
$MyInvocation.MyCommand object is set to null when you run the script by using PowerShell 3.0 in Windows 8 or in Windows Server 2012....
Read more >param block breaks script?? Weird behavior, probably ...
I'm still trying to automate some of the things I "just do" at the command line in PS. Specifically, the complaint comes in:...
Read more >Public/Update-OSMedia.ps1 21.10.13.1
if ($MyInvocation.MyCommand.Name -eq 'New-OSBuild') { if ($PSCmdlet.ParameterSetName -eq 'Taskless') { #$Task = Get-OSMedia -Revision OK | Where-Object {$_.
Read more >PowerShell: The automatic variable $MyInvocation
The automatic variable $myInvocation stores information about the current command if the command is a function, a script or a script block.
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
I agree. We need to decide which behavior is the correct one. From my personal view,
Where-Object
seems doing the right thing because just like @BrucePay said, a script block is an anonymous function.Here is another example:
Here,
b.ps1
contains an invocation of a script block, and as we can see, the script block doesn’t usesb.ps1
as the command name.#10454 is related to this issue. The PR made an optimization to override
ForEahc-Object
with dot-sourcing a filter-like script block for some common uses ofForEach-Object
, and when that optimization kicks in,$MyInvocation.MyCommand.Name
isnull
forForEach-Object
too. Whether that should be fixed and how to fix it depends on the conclusion of this issue.Here are the output of
$MyInvocation
fromWhere-Object
andForEach-Object
in the repro scenario as inpreview.3
:Here is the output of
$MyInvocation
fromForEach-Object
in the repro scenario with the optimization change in #10454:@PowerShell/powershell-committee reviewed this. Inspecting the code, it appears that both
Where-Object
andForEach-Object
both have code to set MyInvocation, but using different APIs. It seems that user found utility in getting this information so we recommend thatWhere-Object
should behave likeForEach-Object
even if it is technically correct that it’s an anonymous function.