Where Did That Come From?

Where Did That Come From?

  • Comments 5

Have you ever found yourself asking the question, "where did THAT come from?"?

In PowerShell we try to give you mechanisms you can use to answer questions like that.    We spend extra resources (memory, cpu cycles, etc) to do this because we focus in the performance of the PEOPLE using our software instead of the performance of the code.  When something goes pear-shaped, what matters is how quickly a person can figure out what is going on and fix it. 

We've talked quite  bit about this in the context of the rich error information we gather but in this blog I'm going to discuss another V1 feature and then tell you about ANOTHER one of my favorite V2isms. 

You know that variables are exposed as a drive and you can do things like:

PS> dir Variable:s*

Name                           Value
----                           -----
ShellId                        Microsoft.PowerShell

 

Bug have you have tried this:

PS> dir Variable:s* |ft Name,Description -auto

Name       Description
----       -----------
ShellId    The ShellID identifies the current shell.  This is used by #Requires.
StackTrace

 

Did you know about that?  There is a lot more to variables than meets the eye!  You can provide a description with a variable by using Set-Variable

PS> Set-Variable X 15 -Description "This is a test"
PS> Get-Variable x |fl *

Name        : x
Description : This is a test
Value       : 15
Visibility  : Public
Module      :
ModuleName  :
Options     : None
Attributes  : {}

 

That has existed since PowerShell V1 but what we never were able to answer is - where did that function come from? 

When I start PowerShell, I dot-source a number of scripts which define functions as part of my session.  Occasionally, I'll decide that I want a function to do something different.  But then the question is, what file was the function defined in?  There was never a good way to answer that question.  That all changes in PowerShell V2.

In V2, we have extended the SCRIPTBLOCK object to include the FILE where the script was defined.  One of the tricks you need to learn is that to get all the information about a Scriptblock, you need to use the -FORCE flag on the formatting commands.

[4376:0]PS> (dir function:prompt ).scriptblock |fl *

    if ($PSDebugContext)
    { "DBG>"
    }
    else
    {
        "[{0}:{1}]PS> " -f $PID, $NestedPromptLevel
    }

[4376:0]PS> (dir function:prompt ).scriptblock |fl * -force

IsFilter      : False
StartPosition : System.Management.Automation.PSToken
File          : D:\ps\profile.ps1
Attributes    : {}
Module        :

Now that you know it is there, you can just access it directly:

[4376:0]PS> (dir function:prompt ).scriptblock.file
D:\ps\profile.ps1

PSMDTAG:FAQ: How do I tell where a function was defined?
(dir function:X).ScriptBlock.File

 

 

 

Experiment! Enjoy! Engage!

Jeffrey Snover [MSFT]
Windows Management Partner Architect
Visit the Windows PowerShell Team blog at:    http://blogs.msdn.com/PowerShell
Visit the Windows PowerShell ScriptCenter at:  http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx

Leave a Comment
  • Please add 4 and 5 and type the answer here:
  • Post
  • All the time! But the way you laid it out makes total sense.

  • Very useful feature indeed. In fact, I have a couple functions in my PowerShell ISE profile that exploit this new functionality as well as module metadata.

    You might like Open-Function and Open-Module:

    http://einsteintech.spaces.live.com/blog/cns!89E05724AF67A39E!724.entry

  • Similar to how functions are defined, is there a way to get similar information about where aliases are defined?

  • @user- no you can't do this for Aliases - please file a suggestion on connect.

    jps

  • Thanks Jeffrey;

    Out of curiosity, why do I need to -force the file property to show up?

Page 1 of 1 (5 items)