PowerShell模块中Get命令的作用域 总结

PowerShell模块中Get命令的作用域 总结,powershell,module,scope,Powershell,Module,Scope,我想测试一个函数是否存在。我写了一个函数来为我做这件事,但当我把它放在模块中时,它在模块的作用域中运行,而我希望它在调用它的会话的作用域中运行 说明: 如果将其复制并粘贴到PowerShell提示符中,它将按预期工作 function Test-Function($functionName) { $values = @(get-command -all | where {$_.Name -eq "$functionName" -and $_.CommandType -eq "Functi

我想测试一个函数是否存在。我写了一个函数来为我做这件事,但当我把它放在模块中时,它在模块的作用域中运行,而我希望它在调用它的会话的作用域中运行

说明: 如果将其复制并粘贴到PowerShell提示符中,它将按预期工作

function Test-Function($functionName) {
    $values = @(get-command -all | where {$_.Name -eq "$functionName" -and $_.CommandType -eq "Function"})
    return $values.Count -gt 0
}
此时,您可以运行诸如
test function Get ChildItem
$false
,因为这是一个cmdlet)或
test function test function
$true
,因为这是一个函数)

但是,如果你要经常使用这个函数呢

从模块调用Get命令 如果您将其保存在.psm1文件中,并添加对
Export ModuleMember
的调用以公开该函数,它将工作。。。有时候

import Test.psm1

Test-Function Test-Function
# Returns $true

function blah() { echo "whatever" }

Test-Function blah
# Returns $false
就我所知,这是一个范围问题——模块有自己的范围,它看不到我在它之外创建的其他函数

权变措施 基本上,我想保存这个函数以备以后使用,并在几个脚本文件中使用它——对我来说,它听起来像是一个模块的候选者。但是,除非有一个聪明的解决方案来解决这个范围界定问题,否则我会被一些蹩脚的解决方法所困扰:

  • 不要把它放在一个模块中,把它放在一个.ps1文件中,然后点源代码

    这就是我们现在所做的,它确实有效,如果没有其他解决办法,它可能是最不丑陋的事情

  • 根本不要把它放在模块中,强迫任何想使用它的人重新实现

    我想只有几行,所以这行行得通。问题是它已经在我们的部署脚本中的一些地方出现了,如果我能把它变成一个函数就太好了

  • 用作用域或脚本块做一些奇怪的事情

    比如,把这个放在模块中:

    $testFuncBlock = {
        param($functionName)
        $values = @(get-command -all | where {$_.Name -eq "$functionName" -and $_.CommandType -eq "Function"})
        return $values.Count -gt 0
    }
    Export-ModuleMember -variable testFuncBlock
    
    并将其称为脚本块:

    . $testFuncBlock Function-Name
    
    很明显,那是很丑陋的

  • 有更好的解决办法吗?
    我就想到这些。是否有什么东西可以让我将其保存在模块中,并在以后不使用脚本块的情况下引用它?

    Get命令
    根据PowerShell的版本有不同的行为。请参阅参数文档中特定于版本的注释

    相反,我建议使用
    功能:
    驱动器:

    function Test-Function ($Name) {
        Test-Path -Path "function:${Name}"
    }
    

    对我有用<代码>测试函数blah返回
    True
    <代码>测试函数bleh返回
    False
    。我正在使用Powershell 3。