我尝试编写一些需要检查函数元数据的代码,并根据命令的参数处理其他一些数据。在此过程中,我发现了一些我无法解释的真正奇怪的行为。
我在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
而不是模块他们都没有改变任何事情。
什么决定一个函数是否有共同的参数?什么可能导致他们不去?
答案 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