Referring to current object from different scope

This topic contains 3 replies, has 3 voices, and was last updated by  Aurimas N. 3 weeks ago.

  • Author
    Posts
  • #75994

    Aurimas N.
    Participant

    Hi,
    I want to be able to capture $_ from another scope, something like this:

    function foo
    {
    $something = ((get-variable -name "_" -scope 1).value).exception.message
    write-host $something
    }
    

    how would I do this properly?

    I want to use it in these kind of situations:

    foo #write-host prints empty line
    try{
    throw
    }catch{
    foo #write-host prints $_.exception.message from this catch block
    }
    

    the goal is to avoid assigning $_ to some other variable or passing it as a parameter every time I want to call "foo" in a catch block.
    I've also tried using $Error[0], however it being global produces unwanted results when calling foo not in a catch block.
    I have also tried using $ExecutionContext.SessionState.PSVariable.Get("_") in "foo", but since I don't know how to refer to specific scope or how it works in general I was not able to produce desired results when testing.

  • #76021

    Rob Simmers
    Participant

    You should use a parameter in your "foo" function to collect the error message. There is also -ErrorVariable, but with what you posted you don't want to use anything globally, you want to pass what you need into the function:

    function Get-Error {
        param (
            $Error
        )
    
        "Do something with error: {0}" -f $_.Exception.Message
    }
    
    try {
        Get-ChildItem -Path C:\ -Reccccurse -ErrorAction Stop
    }
    catch {
        Get-Error -Error $_
    }
    
  • #76033

    Patrick Meinecke
    Participant

    I agree with Rob that passing it as an argument is much better in this situation, but to answer your question directly you could do this:

    function foo {
        (Get-PSCallstack)[1].GetFrameVariables().'_'.Value
    }
    

    This gets a CallStackFrame for the current and previous steps in the execution stack and retrieves the first one that isn't the current frame. It then gets the automatic variables for that frame using the GetFrameVariables method, and retrieves the value for $_.

    There aren't a whole lot of good reasons to do this though, it's significantly more readable to pass the variable you want as a parameter.

  • #76036

    Aurimas N.
    Participant

    Thanks for comments, I'll stick with the parameter.

You must be logged in to reply to this topic.