$MyInvocation.Statement is blank when called from FileExplorer context menu in Windows 11

I want to log when my PowerShell scripts run (command AND parameters; essentially exactly how they were called). $MyInvocation.Statement looks to contain exactly what I’m after, so I set a variable to that value, then wrote the contents of that variable to my log.

The problem I’m having is that the variable isn’t always populated. It appears to NOT be loaded (that is, be blank) when I use “PwSh.exe ” (like from a File Explorer context menu), but it works fine when I open a terminal window and call the script there (“ ”). Can someone explain to me why this is happening and what I might be able to do to get the full command that was used to run a specific script?

If you really need to see the code, it’s basically just 2 lines:

$CommandLine = $MyInvocation.Statement
Write-Host $CommandLine

When run from an embedded script via “PwSh.exe”, $CommandLine is blank. From a Windows Terminal session, using the same script and parameters results in $CommandLine containing the exact command.

Thanks …

Mark

What does your context menu command look like?

(An example, but when I copy/pasted, it dropped one of the leading backslashes):

PwSh \LocalHost\Scripts\Archive.PS1 “%1”

Pretty sure that’s the equivalent of pwsh -file . Powershell treats this as a file/script execution which isn’t the same as a command execution. Real head scratcher there…

You should still be able to see the command in $MyInvocation.MyCommand I believe

Probably, but then it doesn’t contain the parameters (I don’t think). I was hoping to be able to just retrieve exactly what was being RUN, whatever that is. When I saw .Statement and it was exactly what I was after, I thought I had it. Rats.

You can see if BoundParameters still has your params then just concat together

$myinvocation has some weirdness to it. If you haven’t read these, I’d check them out for more details.

Thanks. I can accomplish this a lot of ways. I just find it curious that the “.Statement” property is exactly what I was after and still think it’s crazy that it’s not populated in that “PwSh.exe -File” scenario. Oh well.

Thanks. I had read most of those articles already and surmised that there was some “strangeness” going on. While I’m still curious, I’m going to move forward with a workaround …

Just to close the loop on this topic … In case anyone else is having similar issues.

First, I ended up looking into various options using what Justin & Doug suggested, but as I know exactly enough to be dangerous, I needed a bit of help with the particulars. That is, coercing $PSBoundParameters into how the command line would have looked.

I suspect some (if not many) of you have heard the “AI blathering” and might be getting weary of it. But in this case, I actually found CoPilot to be quite helpful. I started out basically from scratch and the answer it gave me didn’t work, but its last statement was “let me know how it goes”, so I did. It actually responded similarly to Doug (“some silliness” or words to that effect) and offered other ideas, but when I clarified things, it was really helpful. This line of code is ultimately what took $PSboundParameters and formatted them back like they would be in a command line:

ForEach ($Key In $Parameters.Keys) {$ParmsString += " -$Key $($Parameters[$Key])"}

Again, thanks for your thoughts and comments.

Mark

Edit 1/15/2025 9 am: It turned out that “.Statement” didn’t do what I really wanted. When scripts call each other, what ends up in “.Statement” looks to be the line of code (variables NAMES still present as opposed to those variables’ VALUES). Oh well, always learning!!!

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.