Author Posts

August 29, 2016 at 5:13 pm

I have numerous scripts in our environment and to try to minimize the differentiation, I have created a handful of less than a dozen or so random functions that are used by multiple files. One of those functions would be called by the main script as one of the last lines and simply sends an email that the script has completed. I recently decided I'd like to start adding a little footer to the end of the script containing some things like script host running on, execution time, user context, and the main script's filepath. However, when I include $Myinvocation.ScriptName or $PSCommandPath or whatever, they all reference the "library" script file containing the function rather than the originating "parent" script filename.

Does anyone know if there is a way to determine the originating script name when executing in a function of an included script/file?

The only workaround I've come up with is to add a parameter to the function and have every call pass it's own scriptpathname every time it calls the function. But this is less than ideal. Any suggestions would be appreciated.

August 29, 2016 at 5:44 pm

Thank you for the reply. However, that works well to get the path/folder of the executing script, but it doesn't actually seem to get the parent script filename itself. When I tested this, the only thing I got was "D:\Scripts\" and there doesn't appear to be a sub-property that gives the filename specifically.

Anything similar that will give just the originating script filename? In conjunction with what you shared, I could build the full filepath.

Thank you.

August 29, 2016 at 5:53 pm

Just put the message in the script itself?

August 29, 2016 at 6:13 pm

Yeah, that is one option. Just, as I said, less than ideal since that would mean having to modify probably northward of 100 scripts. So was hoping there was some invocation stack.

Honestly, the more I thought about it, what'd be perfect here would be if there was a "parent" property in the InvocationInfo object that points to the InvocationInfo object of the script that called the current execution point. This could work recursively back until you get to like a console host or powershell.exe or somesuch. Then one could pseudo-create a stack trace on a given point in the code.

August 29, 2016 at 6:15 pm

Welp, talked myself into a solution. Get-PSCallStack appears to essentially allow me to do basically what I just described.

Now, I have not tested this in all possible execution scenarios, but for basic tasks and calling as script from the console, if one has some library script file, with some SendEmailUponCompletionOfScript type function, if I add the lines:

$callStack = Get-PSCallStack

if ($callStack[-1].Command -eq "") 
    { $topLevelScript = $callStack[-2].ScriptName }
else { $topLevelScript = $callStack[-1].ScriptName }

Then I get the original Script filepathname, apparently regardless of the depth of execution stack at which that function is actually called. This should work well for my particular purposes. If others have better code that takes into account a wider variety of execution methods, please share.

Thanks.

  • This reply was modified 2 years, 1 month ago by  tocano.
  • This reply was modified 2 years, 1 month ago by  tocano. Reason: adding code

August 29, 2016 at 8:02 pm

Apparently I'm past the Edit window on that post, so cannot make a small change. The conditional line should have "[ScriptBlock]" in quotes (except with angle brackets). It got stripped out by the HTML parser upon submission. So should be:

$callStack = Get-PSCallStack

if ($callStack[-1].Command -eq "[ScriptBlock]") # (use angle brackets in this string instead of square brackets)
    { $topLevelScript = $callStack[-2].ScriptName }
else { $topLevelScript = $callStack[-1].ScriptName }

Thanks.

August 29, 2016 at 8:41 pm

I can't make sense of what you are doing. You just run scripts at random and you don't know their names and locations?

August 29, 2016 at 8:51 pm

In addition to manually executed scripts, we have a whole slew of various scripts that run either as scheduled tasks or as triggered by different events in our environment. Some correct issues themselves, some just report that it found some issue and requires manual investigation. Still others just report for archiving purposes. We frequently have these scripts email notices, errors, complications and "I don't know what to do here" situations to our group. Sometimes the action required involves one of our team modifying the script itself so that it catches a newly discovered case, or adding a correction step once we learn how to automatically fix some situation, or whatever. So having the filepath of the script that triggered the notice in the body of the email it sends out is helpful to us.

Make sense?