# cmdlet MyCmdlet.ps1
Param(
[Parameter(Mandatory=$true)]
[string]$Variable1,
[string]$Variable2
)
Begin {
Function Function-Name {
Param (
[Parameter(Mandatory=$true)]
[string]$Variable1,
[Parameter(Mandatory=$false)]
[string]$Variable2,
[Parameter(Mandatory=$false)]
[ValidateScript({[string]::IsNullOrWhiteSpace($Variable2)})]
[switch]$Choice
)
# function-body
}
}
Process {
Function-name -Variable1 "SomeString" -Choice
}
此cmdlet的调用方式如下:
.\MyCmdlet.ps1 -variable1 "string1" -variable2 "string2"
它返回:
无法验证参数' choice'的参数。 " [string] :: IsNullOrWhiteSpace($ Variable2)"参数的验证脚本,其值为#34; True"没有返回True的结果。
似乎cmdlet的-Variable2
的值被隐式传递给函数,因为相同的变量名称,即使在cmdlet内部的函数调用期间没有特别提及它。
注意:我需要变量具有相同的名称,以便将来可以看到它们的相似功能。我在cmdlet中使用Begin
,Process
,End
,因此我可以将其转换为函数并放入其他脚本中。
我该如何处理?
答案 0 :(得分:2)
到ValidationScript
运行时,尚未创建局部变量$Variable2
,因此您从父作用域中的$Variable2
获取值。
改为使用$PSBoundParameters
:
Function Function-Name {
Param (
[Parameter(Mandatory=$true)]
[string]$Variable1,
[Parameter(Mandatory=$false)]
[string]$Variable2,
[Parameter(Mandatory=$false)]
[ValidateScript({[string]::IsNullOrWhiteSpace($PSBoundParameters['Variable2'])})]
[switch]$Choice
)
}
答案 1 :(得分:0)
如果你的目的是创建一个既可以直接调用(作为脚本)又可以点源调用的脚本(这样你就可以从其他PowerShell脚本中调用它中的函数),你可以这样做:
# Invoke-Something.ps1
[CmdletBinding()]
Param(
[Parameter(Mandatory=$false)]
[string]$Variable1,
[Parameter(Mandatory=$false, ParameterSetName='bar')]
[string]$Variable2,
[Parameter(Mandatory=$true, ParameterSetName='foo')]
[switch]$Choice
)
function Invoke-Something {
[CmdletBinding()]
Param (
[Parameter(Mandatory=$true)]
[string]$Variable1,
[Parameter(Mandatory=$false, ParameterSetName='bar')]
[string]$Variable2,
[Parameter(Mandatory=$true, ParameterSetName='foo')]
[switch]$Choice
)
Write-Host 'invocation: function'
}
if ($MyInvocation.Line.Split()[0] -ne '.') {
Write-Host 'invocation: directly'
Invoke-Something @PSBoundParameters
} else {
Write-Host 'invocation: dot-source'
}
使用上述方法,您可以直接调用脚本:
PS> Invoke-Something.ps1 -Variable1 'some' -Variable2 'other' invocation: directly invocation: function
或点源它并调用函数:
PS> . Invoke-Something.ps1 invocation: dot-source PS> Invoke-Something -Variable1 'some' -Variable2 'other' invocation: function
为此,您必须使脚本的所有参数都是可选的。
此简化版本不会在脚本级别定义参数并将@args
传递给调用的函数:
# Invoke-Something.ps1
function Invoke-Something {
[CmdletBinding()]
Param (
[Parameter(Mandatory=$true)]
[string]$Variable1,
[Parameter(Mandatory=$false, ParameterSetName='bar')]
[string]$Variable2,
[Parameter(Mandatory=$true, ParameterSetName='foo')]
[switch]$Choice
)
Write-Host 'invocation: function'
}
if ($MyInvocation.Line.Split()[0] -ne '.') {
Write-Host 'invocation: directly'
Invoke-Something @args
} else {
Write-Host 'invocation: dot-source'
}