【问题标题】:powershell use of where-object within script function not workingpowershell 在脚本函数中使用 where-object 不起作用
【发布时间】:2020-04-29 01:02:39
【问题描述】:

我正在尝试使用一个函数启用我的 powershell 配置文件脚本,该函数可以让我在当前的 powershell 终端会话中执行文字和通配符搜索以查找函数的存在。

在我的 powershell 配置文件脚本 [ $env:userprofile\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1 ] 中,我创建了以下函数。

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

使用注释掉的行 Get-ChildItem function:\ | Where-Object { $_.Name -like "$args" } 不起作用,即使我可以在命令行上使用它,例如Get-ChildItem function:\ | Where-Object { $_.Name -like "get-*" } 它按预期工作。使用未注释的行 Get-ChildItem function:\$args 在配置文件脚本函数和命令行中都有效,例如Get-ChildItem function:\get-*.

在网上和 stackoverflow 上搜索,我无法找到有关使用输出管道 | 到另一个 cmdlet 和/或在函数中使用 Where-Object cmdlet 来确定如何制作的任何细节这行得通。当已知相同的东西在命令行上工作时,关于如何使输出通过管道传输到 where-object 在脚本函数中工作的任何见解?

更新 除了提供的答案之外,solutin 还能够使用以下内容

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" } 
}

调试输出

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

【问题讨论】:

  • 我怀疑您遇到了范围问题。大多数时候,一个函数有它自己的作用域,而你的函数可能不知道$Args 在那个特定的作用域中拥有什么。 ///// 同样,$Args 是保留的 $var 名称之一[并且是一个数组]。除非您确定它在任何给定情况下都是正确的,否则您可能不会使用该确切名称。

标签: function powershell pipe


【解决方案1】:

每个脚本块都有自己的 $args 自动变量。

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

get-fnc get-*




# lots of empty lines

where-object 的 $args 是一个 $null 数组。

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

但是,您可以使用不使用脚本块的其他版本的 where-object:

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

get-fnc get-*

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

另请参阅:Why doesn't PowerShell Where-Object work when passing a variable?

我实际上不知道在 where-object 脚本块中设置 $args 的方法,但这是另一个脚本块和 $args 的示例。 $args 实际上是一个数组

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

hi
there

【讨论】:

  • 感谢您对 $args 范围问题在此处产生问题的详细见解。非常意外的是 $args 仅在函数范围内可用,但不会向下流入子脚本块,我认为它是函数内的堆栈框架。我发现如果我将 $args 分配给函数范围内的变量,该变量在函数的子脚本块中是有效的。
  • 似乎任何脚本块都有自己的 $args,包括作业和调用命令。
猜你喜欢
  • 2021-12-07
  • 2011-06-25
  • 1970-01-01
  • 2016-01-13
  • 2020-05-31
  • 2018-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多