PowerShell模块中的Get-Command范围

问题描述 投票:2回答:1

摘要

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

描述:

如果将其复制并粘贴到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-Command

如果将其保存在.psm1文件中并添加对Export-ModuleMember的调用以公开该函数,它将有效。

import Test.psm1

Test-Function Test-Function
# Returns $true

function blah() { echo "whatever" }

Test-Function blah
# Returns $false

据我所知,这是一个范围问题 - 模块有自己的范围,它无法看到我在其外部创建的其他函数。

解决方法

基本上,我想保存此功能以便以后在几个脚本文件中使用它 - 它听起来像是我的模块的候选者。但是,除非有这个范围问题的聪明解决方案,否则我会遇到一些糟糕的解决方法:

  1. 不要将它放在模块中,将其放在.ps1文件中并对其进行点源。 这就是我们现在所做的,它确实有效,如果没有其他解决方法,它可能是最难看的事情。
  2. 不要把它放在模块中,强迫任何想要使用它的人重新实现 我想,这只是几行,所以这会奏效。问题是它已经存在于我的部署脚本的几个地方了,如果我能把它变成一个功能那就太好了......
  3. 使用范围或脚本块或其他东西做一些奇怪的事情。 比如,把它放在模块中: $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 显然,这是赫拉丑陋的

有更好的解决方案吗?

这就是我所能想到的。有什么东西能让我在模块中保存它并在以后没有脚本块的情况下引用它吗?

powershell module scope
1个回答
2
投票

Get-Command具有不同的行为,具体取决于PowerShell的版本。查看参数文档中的版本特定说明。

Using the Get-Command Cmdlet

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

function Test-Function ($Name) {
    Test-Path -Path "function:${Name}"
}
© www.soinside.com 2019 - 2024. All rights reserved.