1

I'm trying to enable my powershell profile script with a function that will let me do literal and wildcard searches for the presence of a function in my current powershell terminal session.

Within my powershell profile script [ $env:userprofile\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1 ] i've created the following function.

function Get-Fnc { 
    #Get-ChildItem function:\ | Where-Object { $_.Name -like "$args" }
    Get-ChildItem function:\$args
}

Using the commented out line Get-ChildItem function:\ | Where-Object { $_.Name -like "$args" } doesn't work even though i can use that on the command line, e.g. Get-ChildItem function:\ | Where-Object { $_.Name -like "get-*" } it works as expected. Using the uncommented line Get-ChildItem function:\$args works both in the profile script function and the command line, e.g. Get-ChildItem function:\get-*.

Searching on net and in stackoverflow i've not been able to find any details on gotchas around making use of output piping | to another cmdlet and/or use of the Where-Object cmdlet within functions to determine how to make it work. Any insights on how to make output piped to where-object work in a script function when the same thing is known to work on command line?

Update In addition to answer provided solutin was also able to use the following

function Get-Fnc { 
    $argsFncScope = $args # works because we make function scoped copy of args that flows down into Where-Object script block / stack frame
    Write-Host "function scoped args assigned variable argsFncScope = $argsFncScope and count = $($argsFncScope.Count) and type = $($argsFncScope.GetType().BaseType)"
    Get-ChildItem function:\ | Where-Object { $_.Name -like "$argsFncScope" } 
}

Debug Output

get-fnc *-env

[DBG]: PS C:\Users\myusrn\Documents\WindowsPowerShell> 
function scoped args assigned variable argsFncScope = *-env and count = 1 and type = array

[DBG]: PS C:\Users\myusrn\Documents\WindowsPowerShell>

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Function        Get-Env
1
  • 1
    i suspect you are seeing a scope problem. most of the time, a function has it's own scope and yours may not know what $Args holds in that particular scope. ///// also, $Args is one of the reserved $var names [and is an array]. you likely otta not use that exact name unless you are sure that it is correct in any given situation. Commented Apr 29, 2020 at 1:38

1 Answer 1

1

Each scriptblock has its own $args automatic variable.

function Get-Fnc { 
  Get-ChildItem function:\ | where-object { write-host $args; 
    $_.name -like "$args" } }

get-fnc get-*




# lots of empty lines

The $args for where-object is a $null array.

function Get-Fnc {   
  Get-ChildItem function:\ | where-object { $global:myargs = $args;
    $_.name -like "$args" } }

get-fnc get-*

$myargs

$myargs.count

0

$myargs.gettype()

IsPublic IsSerial Name     BaseType
-------- -------- ----     --------
True     True     Object[] System.Array

You can however use the other version of where-object that doesn't use a scriptblock:

function Get-Fnc { 
  Get-ChildItem function:\ | where-object name -like $args }

get-fnc get-*

CommandType Name    Version Source
----------- ----    ------- ------
Function    Get-Fnc

See also: Why doesn't PowerShell Where-Object work when passing a variable?

I actually don't know a way to set $args within the where-object scriptblock, but here's another example of a scriptblock and $args. $args is actually an array.

& { $args[0]; $args[1] } hi there

hi
there
Sign up to request clarification or add additional context in comments.

2 Comments

thanks for the detailed insights into the $args scope issue creating the problem here. Very unexpected that $args is only available at function scope but doesn't flow down into child script block, what i would think of as a stack frame, within the function. I found if i assigned $args to a variable at function scope that variable was valid within a child script block in the function.
It seems like any scriptblock has its own $args, including jobs and invoke-command.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.