是否可以将自定义函数与ValidateScript
一起使用,其中函数稍后在脚本中定义。
另外,在调用此函数时是否可以引用其他参数(即假设没有循环依赖)?
我理解为什么这可能是不可能的,但是因为它是有用的东西,我希望MS实现一些特殊的规则,允许在验证参数发生之前读取脚本并使函数定义可用。
e.g。
#Run-DemoScript.ps1
param (
[Parameter(Mandatory = $true)]
[string]$DbInstance
,
[Parameter(Mandatory = $true)]
[string]$DbCatalog
,
[Parameter(Mandatory = $true)]
#
# Is this possible; i.e.
# - Validate-Country is not defined until later in this script
# - DbInstance and DbCatalog parameters are defined alongside Country
[ValidateScript({Validate-Country -Country $_ -DbInstance $DbInstance -DbCatalog $DbCatalog})]
#
[string]$Country
)
#returns $true if the country is in the database's country table; otherwise false
function Validate-Country {
[CmdletBinding()]
param (
[Parameter(Mandatory = $true)]
[string]$DbInstance
,
[Parameter(Mandatory = $true)]
[string]$DbCatalog
,
[Parameter(Mandatory = $true)]
[string]$Country
)
process {
$Country = $Country -replace "'","''"
((Execute-SQLQuery -DbInstance $DbInstance -DbCatalog $DbCatalog -Query "select top 1 1 x from dbo.Country where Name = '$Country'") | Measure-Object | Select -ExpandProperty Count) -gt 0
}
}
function Execute-SQLQuery {
#...
}
"Script ran with Country $Country"
更新
似乎您可以将整个函数定义移动到ValidateScript
属性中,并且仍然可以在脚本中稍后访问该函数; e.g:
param(
[Parameter(Mandatory = $true)]
[ValidateScript({
function IsValid ($test) {
$test -eq 'test'
}
IsValid $_
})]
[string]$x
)
"Output: $x"
"Is Valid? $(IsValid $x)"
然而,这非常痛苦。它也不允许引用兄弟参数(例如下面的)
param(
[Parameter(Mandatory = $true)]
[string]$y
,
[Parameter(Mandatory = $true)]
[ValidateScript({
function IsValid ($a,$b) {
$a -eq $b
}
IsValid $_, $y
})]
[string]$x
)
"X: $x"
"Y: $Y"
"Is Valid? $(IsValid $x $y)"
答案 0 :(得分:1)
到目前为止,根据反馈,似乎在PowerShell v4中目前无法完成我想要的工作。
我最终使用一个简单的解决方法来实现这一目标。它增加了一点开销,但并不太痛苦。
ValidateScript
验证。RUN
,并将文件的参数完全复制为此函数的参数。只要在它被调用之前它出现在脚本中的哪个位置并不重要(参见步骤4)。ValidateScript
部分添加到此功能的定义中。RUN
函数传递所有参数(使用@PSBoundParameters
以简化/减少维护)。process
函数的RUN
块。@PSBoundParameters
中。有关详细信息,请参阅{{ 3}}。如果将默认逻辑与其他参数信息一起复制到函数定义中,则不会出现此问题。
#Run-DemoScript.ps1
param (
[Parameter(Mandatory = $true)]
[string]$DbInstance
,
[Parameter(Mandatory = $true)]
[string]$DbCatalog
,
[Parameter(Mandatory = $true)]
#[ValidateScript({Validate-Country -Country $_ -DbInstance $DbInstance -DbCatalog $DbCatalog})]
[string]$Country
)
#move all logic from main script into here
#copy parameters from file's param definition, only add in validation
function RUN {
param (
[Parameter(Mandatory = $true)]
[string]$DbInstance
,
[Parameter(Mandatory = $true)]
[string]$DbCatalog
,
[Parameter(Mandatory = $true)]
[ValidateScript({Validate-Country -Country $_ -DbInstance $DbInstance -DbCatalog $DbCatalog})]
[string]$Country
)
process {
"Script ran with Country $Country"
}
}
#returns $true if the country is in the database's country table; otherwise false
function Validate-Country {
[CmdletBinding()]
param (
[Parameter(Mandatory = $true)]
[string]$DbInstance
,
[Parameter(Mandatory = $true)]
[string]$DbCatalog
,
[Parameter(Mandatory = $true)]
[string]$Country
)
process {
$Country = $Country -replace "'","''"
((Execute-SQLQuery -DbInstance $DbInstance -DbCatalog $DbCatalog -Query "select top 1 1 x from dbo.Country where Name = '$Country'") | Measure-Object | Select -ExpandProperty Count) -gt 0
}
}
function Execute-SQLQuery {
#...
}
RUN @PSBoundParameters #remember to handle default parameters: https://stackoverflow.com/questions/2808973/parameters-with-default-value-not-in-psboundparameters
答案 1 :(得分:0)
如果你想保留一个脚本,你可以在脚本中使用所有功能。我的意思是这样的:
Function fun1 {
<code>
}
Function fun2 {
<code>
}
Function fun3 {
Param (
Validatescript({
fun1
})$Param1
)
<code>
}
#start executing code
fun3
这使您可以从单个文件运行脚本,但也可以将您的功能作为脚本验证的一部分。它漂亮吗?不,它有用吗?是。我过去曾多次这样做,并且效果很好。您需要记住的唯一事情是您的脚本使用变量进行范围设定。