(aka How to add C-style __LINE__ and __FILE__ macros to PowerShell)
When troubleshooting PowerShell scripts, it can be useful to log, store or output the current line number and and file name position so that you know where your script was when something happened. This information is given to you automatically when there is an error, however if you’re not facing a PowerShell error but you have a problem with the logic in your script, you need to manually retrieve it from PowerShell.
The MyInvocation variable was designed for this purpose, providing you with details about the invocation of the current script or function as well as details about the current command that you are executing. The trouble is that when you use $MyInvocation directly in a script file, the details it provides are about the invocation of the script, meaning the command used to invoke the script, and not about the current line within the script. Fortunately, though, as with many things PowerShell there is a way. To be able to use $MyInvocation to retrieve details about the current line in a script, you need to wrap it in a function and call that function. When you do this, $MyInvocation will give you details about the command used to call the function that contains it, and if that command is inside a script file the details will include the script file name as well as the line number of the command.
Armed with that knowledge, you can create a few useful functions in your profile, and they will allow you to retrieve the current file name and line number from within any script you use. Here are my interpretations of those functions:
#region Script Diagnostic Functions
function Get-CurrentLineNumber {
$MyInvocation.ScriptLineNumber
}
New-Alias -Name __LINE__ -Value Get-CurrentLineNumber –Description ‘Returns the current line number in a PowerShell script file.‘
function Get-CurrentFileName {
$MyInvocation.ScriptName
}
New-Alias -Name __FILE__ -Value Get-CurrentFileName -Description ‘Returns the name of the current PowerShell script file.‘
#endregion
A few good uses for these functions might be:
- In complicated scripts where you want to verify the order of execution of certain lines of script.
- When you are returning a value in multiple locations and you would like to simply know which location you returned from while troubleshooting without stepping through any lines in your script.
I hope this is useful for you. I just started using these functions and they are already coming in quite handy for me.
Enjoy!
Kirk out.
Share this post: | ![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
Thank you very much, this will be very helpfull for logging what is happening in our automation.
The `$MyInvocation.ScriptLineNumber` variable is not the Current Line Number. It’s the Line number from where the function that you’re in was called.
Take this gist, for example: https://gist.github.com/VertigoRay/7b73da2cace3d49a2cf2 Output is in the comments.
Hi Ray,
You’re right about $MyInvocation.ScriptLineNumber. That is why the blog posts recommends you create two separate functions: Get-CurrentLineNumber and Get-CurrentFileName. Then, when you invoke Get-CurrentLineNumber, which internally uses $MyInvocation.ScriptLineNumber, you will get the line number where you invoked Get-CurrentLineNumber, getting exactly what you asked for, the current line number. Don’t simply use $MyInvocation.ScriptLineNumber in your script if you want the number of the line where you get that property, that won’t work.
If you modify your gist to invoke Get-CurrentLineNumber instead, and you define that function in your profile, in the module, or in a script, then you’ll get the line number you were looking for.
Thanks,
Kirk out.
Well done! Sorry I missed that on the first read. 😉
[…] https://poshoholic.com/2009/01/19/powershell-quick-tip-how-to-retrieve-the-current-line-number-and-fi… […]
This is so cool, I’m using it in every project I do from this point on.