Sunday, March 1, 2009

Where Did That Come From?


Where Did That Come From?

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.

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>"
        "[{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

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:
Visit the Windows PowerShell ScriptCenter at:

Published Sunday, March 01, 2009 5:37 PM by PowerShellTeam

Windows PowerShell Blog : Where Did That Come From?

No comments:

Blog Archive