PowerShell

Unraveling the Mystery of $MyInvocation

You have seen $MyInvocation before. It was probably in a piece of code online or on GitHub. Perhaps, you observed it used in a module you downloaded from the PowerShell Gallery or came across it in a PowerShell book you are reading. And like me, you have probably wondered to yourself what its use was. When I would see it, my brain always registered it as noise that was not essential to the functionality of the code. I thought it was used for verbose logging and other informational recordings. However, I have seen it in enough code to make me want to understand what it is and why to use it. Let’s investigate more.

 

 

Sponsored Content

What is “Inside Microsoft Teams”?

“Inside Microsoft Teams” is a webcast series, now in Season 4 for IT pros hosted by Microsoft Product Manager, Stephen Rose. Stephen & his guests comprised of customers, partners, and real-world experts share best practices of planning, deploying, adopting, managing, and securing Teams. You can watch any episode at your convenience, find resources, blogs, reviews of accessories certified for Teams, bonus clips, and information regarding upcoming live broadcasts. Our next episode, “Polaris Inc., and Microsoft Teams- Reinventing how we work and play” will be airing on Oct. 28th from 10-11am PST.

Starting Simple with Get-Help

My research began with a simple get-help command. This is the place you always start to investigate things in PowerShell. Not really knowing what to search on exactly, I started out here:

Once I found the about_Automatic_Variables topic, I was hopeful I would find more and I did. The $MyInvocation automatic variable provides information about the current command, including name, parameters, and information about how the command was invoked. Further, it notes that $MyInvocation only gets populated for scripts, functions, and script blocks. That was enough information to get me started.

Retrieving Properties with Get-Member

Next, I used the get-member command to retrieve the properties of $MyInvocation. I wanted to see what kind of useful information it contained.

$MyInvocation | Get-Member

$MyInvocation contains about 15 different properties. I tried displaying the contents of the automatic variable and was disappointed. It tells me the command that ran and a couple of other properties. It told me the HistoryID, which is the command number in my get-history list. It also told me a couple of other properties but I am not quite sure of the importance.


Next, I recalled from the help that this variable only gets populated for scripts, functions, and script blocks. This means that trying to display it in the console would not give me useful information.

Investigating $MyInvocation in a Script

I then wrote a simple script and saved it as a file names script.ps1. I ran the script from inside the ISE using the green Play button and I got one additional property populated, InvocationName. This tells me the name of the script, which is interesting. I still wanted more!

$MyInvocation | format-list

Next, I tried running the same script from the console window and I got the Line and Position Message properties populated. Neither of these came with any useful information.

With that output being underwhelming, I decided to check it out within a function instead.

Getting Invocation Information Out of Your Functions

Next, I took that same one-line script, enclosed it in a function Get-MyInvocation {} declaration, and saved it as Get-MyInvocation.ps1. I loaded it into memory using the ISE and called it from the console. This is the same thing I did in the script example but I received the same result I received when I ran the script. For the next test, I placed the call to the function directly in the file with the function and saved that as Get-MyInvocationScript.ps1.

function get-MyInvocation {
   $MyInvocation | format-list
   }
get-MyInvocation

We are starting to get somewhere! Notice the information that is available on $MyInvocation within the function. It tells me script name (C:\temp\get-myinvocationScript.ps1), which is the name of the script that I ran. I also get information about the line of the script. Granted, there is only one line in the script, which is the one that calls the function on line 7. Additionally, it tells me the script root directory in PSScriptRoot and the path to the script in PSCommandPath.

What Can I Do with $MyInvocation?

Earlier in the article, I mentioned using $MyInvocation for verbose logging, almost with an air of disdain. However, this is one of the really cool uses of the properties of $MyInvocation because you understand where the information comes from. Perhaps, you have a script that calls multiple functions. Within the functions, you include verbose logging that tells you exactly what function the information is coming from by using $MyInvocation.MyCommand. This makes debugging much more simple. On the other hand, you may have a script that calls a function multiple times with different parameters. You could use the $MyInvocation.ScriptLineNumber property to figure out which function call brought in the problem. But speaking of parameters…

Reporting Parameter Information with $MyInvocation

Let’s now add a parameter to the get-MyInvocation function. I added a string parameter named $MyInfo to the function and write-host will display it to the console.

function get-MyInvocation {
   param (
   [string]$MyInfo
   )

   Write-Host 'The input parameter $MyInfo is'"$($MyInfo)"
   $MyInvocation | format-list
   }

Next, I change the get-myInvocationScript script to use some parameters. In this example, I am using the -MyInfo parameter as well as an undeclared parameter, -AnotherArg.

. .\get-MyInvocation.ps1
get-MyInvocation -MyInfo "WOW!!!" -AnotherArg "OMG"

When I run get-MyInvocationScript, I get information about both parameters that were passed from the calling script. The MyInfo parameter and the value “WOW!” are now listed in the BoundParameters section. The AnotherArg parameter and the value “OMG” show up in the UnboundArguments list. I can see exactly what was passed into the function this way. Think back to the earlier example where a function call occurred multiple times with different parameters in the same script. In that example, using the information from $MyInvocation can really help narrow down the problem areas in a script.

$MyInvocation Mystery Solved!

After learning more about it, I now see the usefulness of using $MyInvocation. Yes, it still holds true that the meat of the code does not require its use. To continue with the food analogy, I mentally compared $MyInvocation to a garnish. It is pretty but not very useful. After exploring it some more, I find it is more like a vegetable. Vegetables are side dishes that can add nutrients to your body and easier debugging keeps your code healthy. In complicated code, such as recursive functions, $MyInvocation becomes a handy informational tool for your PowerShell toolbox.

Related Topics:

BECOME A PETRI MEMBER:

Don't have a login but want to join the conversation? Sign up for a Petri Account

Register
Comments (0)

Leave a Reply

External Sharing and Guest User Access in Microsoft 365 and Teams

This eBook will dive into policy considerations you need to make when creating and managing guest user access to your Teams network, as well as the different layers of guest access and the common challenges that accompany a more complicated Microsoft 365 infrastructure.

You will learn:

  • Who should be allowed to be invited as a guest?
  • What type of guests should be able to access files in SharePoint and OneDrive?
  • How should guests be offboarded?
  • How should you determine who has access to sensitive information in your environment?

Sponsored by: