为什么我的功能没有共同的参数?

时间:2017-03-04 03:01:24

标签: function powershell reflection parameters

我尝试编写一些需要检查函数元数据的代码,并根据命令的参数处理其他一些数据。在此过程中,我发现了一些我无法解释的真正奇怪的行为。

我在psm1脚本模块中有一个函数,它通过导入一个相邻的psd1模块清单来加载它,该清单将它声明为嵌套模块。我已明确声明了14个参数。当我Get-Command并检查Parameters时,我可以看到它有23个参数。 14是我的;其余的是common parameters

PS> (Get-Command Install-MyFunctionFromModule).Parameters.Count
23
PS> (Get-Command Install-MyFunctionFromModule).Parameters.keys
MyParameter1
MyParameter2
MyParameter3
MyParameter4
MyParameter5
MyParameter6
MyParameter7
MyParameter8
MyParameter9
MyParameter10
MyParameter11
MyParameter12
MyParameter13
MyParameter14
Verbose
Debug
ErrorAction
WarningAction
ErrorVariable
WarningVariable
OutVariable
OutBuffer
PipelineVariable

(我的功能名称​​ Install-开头。但我的参数并不以数字结尾。这些只是虚拟占位符,因为我没有&#39 ; t想要使用真实姓名。)

这是预期的。函数应该有共同的参数。

但是为了测试处理参数的代码,我尝试创建一个测试模块。这是它的样子:

testfun.psm1

$ErrorActionPreference = 'Stop'
Set-StrictMode -Version Latest

function test-noparams() {
    Write-Host 'None'
}

function test-differentnamedparams([string]$hello, [switch]$bye) {
    Write-Host "names that don't conflict with common params"
}

然后当我导入模块时,这两个函数都没有任何公共参数:

PS> Import-Module .\testfunc.psm1
PS> (Get-Command test-differentnamedparams).Parameters.Count
2
PS> (Get-Command test-differentnamedparams).Parameters | Format-Table -AutoSize

Key   Value
---   -----
hello System.Management.Automation.ParameterMetadata
bye   System.Management.Automation.ParameterMetadata

PS> (Get-Command test-noparams).Parameters.Count
0

我尝试了一些事情,看看它们是否有所作为:

  • 使用Export-ModuleMember
  • 明确导出功能
  • 使用将脚本模块导入为NestedModule
  • 的清单
  • 使用脚本并通过. .\testfunc.ps1而不是模块
  • 包含该脚本
  • 直接在shell中定义函数

他们都没有改变任何事情。

什么决定一个函数是否有共同的参数?什么可能导致他们不去?

1 个答案:

答案 0 :(得分:2)

只有advanced functions or scripts支持common parameters

使脚本/函数成为高级函数的 显式方法是使用 (replace-sym 'x true '(and x (not x))) ;;=> (and true (not true)) 属性修饰其param(...)

但是,正如jpmc26自己发现的那样,隐式使用每个参数[CmdletBinding()]属性 会使脚本或函数成为高级。< / p>

  • 但请注意,每个参数属性其他而不是[Parameter()] - 例如[Parameter()][AllowNull()] - 本身制作脚本/功能和高级功能。

轻松发现给定脚本/功能是否先进(支持常见参数)的方法是将其名称传递给[Alias()]

Get-Help
# Define a NON-advanced function - no [CmdletBinding()] or [Parameter()] attributes.
PS> function foo { param([string] $bar) 'hi' }; Get-Help foo

NAME
    foo

SYNTAX
    foo [[-bar] <string>]  


ALIASES
    None


REMARKS
    None
# Define an ADVANCED function EXPLICITLY - note the [CmdletBinding()] attribute
# BEFORE the param(...) block.
PS> function foo { [CmdletBinding()] param([string] $bar) 'hi' }; Get-Help foo

NAME
    foo

SYNTAX
    foo [[-bar] <string>]  [<CommonParameters>]


ALIASES
    None


REMARKS
    None

可选阅读:陷阱:名称与常见参数的冲突

从PSv5.1开始:

jpmc26还发现,如果您不小心声明了一个名称与公共参数名称冲突的参数,那么在定义该函数时不会出现错误,但只是稍后当你调用它时,包括将其传递给# Define an ADVANCED function IMPLICITLY - note the [Parameter(Mandatory)] attribute # FOR PARAMETER $bar. PS> function foo { param([Parameter(Mandatory)] [string] $bar) 'hi' }; Get-Help foo NAME foo SYNTAX foo [[-bar] <string>] [<CommonParameters>] ALIASES None REMARKS None

Get-Help