Get Parent Script Name/Path

This topic contains 8 replies, has 2 voices, and was last updated by Profile photo of tocano tocano 3 months, 1 week ago.

  • Author
    Posts
  • #52380
    Profile photo of tocano
    tocano
    Participant

    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.

  • #52382
    Profile photo of Dan Potter
    Dan Potter
    Participant

    $pwd.path

    • #52384
      Profile photo of tocano
      tocano
      Participant

      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.

  • #52390
    Profile photo of Dan Potter
    Dan Potter
    Participant

    Just put the message in the script itself?

    • #52394
      Profile photo of tocano
      tocano
      Participant

      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.

    • #52396
      Profile photo of tocano
      tocano
      Participant

      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 3 months, 1 week ago by Profile photo of tocano tocano.
      • This reply was modified 3 months, 1 week ago by Profile photo of tocano tocano. Reason: adding code
    • #52410
      Profile photo of tocano
      tocano
      Participant

      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.

  • #52419
    Profile photo of Dan Potter
    Dan Potter
    Participant

    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?

  • #52422
    Profile photo of tocano
    tocano
    Participant

    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?

You must be logged in to reply to this topic.