Powershell 是否可以控制脚本的顺序';s参数绑定?

Powershell 是否可以控制脚本的顺序';s参数绑定?,powershell,Powershell,我无法确定以下是否可行。看起来不是,但我想我会问社区 假设我对脚本参数进行了简单的处理,如下所示: [CmdletBinding()] Param( [parameter(Position=0)] [string] version, [parameter(Position=1)] [ValidateScript( { SomeModule/Search(version, $_); $true # FIND THIS VERSION IN SOURCE. **VERSION MU

我无法确定以下是否可行。看起来不是,但我想我会问社区

假设我对脚本参数进行了简单的处理,如下所示:

[CmdletBinding()]
Param(
  [parameter(Position=0)]
  [string] version,

  [parameter(Position=1)]
  [ValidateScript( { SomeModule/Search(version, $_); $true # FIND THIS VERSION IN SOURCE. **VERSION MUST HAVE BEEN SET BY NOW** } )]
  [string] source,
)
现在我们可以说“version”表示组件的版本,“source”表示要搜索该组件的某个源(位置)(可以是多个源)。我最早可以调用search(source,version)的是ValidateScript{},这很好。如果搜索(…)中发生错误,它将不会继续处理其他参数。它还消除了代码后面的一组if(…){}语句,否则检查是否传递了参数并对其运行某些操作时需要这些语句。但是,提供值的顺序很重要:

这很好。以正确的顺序提供值

MyScript.ps1 -version 12345ABC -source 'filesystem' 
这很好。以正确的顺序提供值。位置绑定已生效

MyScript.ps1 12345ABC 'filesystem'
这是行不通的。值以错误的顺序提供(从脚本的逻辑角度来看)

当使用参数名时,我不想对需要特定顺序的客户机设置限制


作为一种解决方法,我可以重新安排$ARGS,但在[CmdletBinding]之前我不能有任何代码。我可以有一个新脚本,它可以更改$ARGS中的顺序,然后调用MyScript.ps1。虽然这不是一个好的解决方案。我使用的是PS 4.0。

命名参数可以是任何顺序,因为它们不受
位置的约束

在脚本中,这两个可以互换,因为它们是命名参数

MyScript.ps1 -version 12345ABC -source 'filesystem'

MyScript.ps1 -source 'filesystem' -version 12345ABC
位置参数没有显式命名,并且需要按照参数中的
Position
定义的正确顺序命名

MyScript.ps1 12345ABC 'filesystem'

命名参数可以是任意顺序,因为它们不受
位置的约束

在脚本中,这两个可以互换,因为它们是命名参数

MyScript.ps1 -version 12345ABC -source 'filesystem'

MyScript.ps1 -source 'filesystem' -version 12345ABC
位置参数没有显式命名,并且需要按照参数中的
Position
定义的正确顺序命名

MyScript.ps1 12345ABC 'filesystem'

我怀疑问题在于您试图在另一个验证脚本中使用一个参数,而PowerShell似乎是在调用时进行验证解析,而不是实际执行。如果将$source的验证移到函数体中,则可能不会有任何进一步的问题。我还没有尝试过这一点,但我会在有机会时尝试,并将在那时发表评论以确认。

我怀疑问题在于您试图在另一个验证脚本中使用一个参数,而PowerShell似乎在执行调用时验证解析,而不是实际执行。如果将$source的验证移到函数体中,则可能不会有任何进一步的问题。我还没有尝试过这一点,但我会在有机会时尝试,并将在那时进行评论以确认。

如果我没有记错,您可以完全忽略位置声明,如果您没有在命令行上指定参数名称(-name),powershell将按位置顺序处理它们

[CmdletBinding()]
Param(
  [string] version,
  [ValidateScript( { SomeModule/Search(version, $_); $true # FIND THIS VERSION IN SOURCE. **VERSION MUST HAVE BEEN SET BY NOW** } )]
  [string] source,
)
此时,应采取以下措施:

MyScript.ps1 12345ABC 'filesystem' 
MyScript.ps1 -source 'filesystem' -version 12345AB
这也应该起作用:

MyScript.ps1 12345ABC 'filesystem' 
MyScript.ps1 -source 'filesystem' -version 12345AB

如果我没记错的话,您可以完全忽略位置声明,如果不在命令行上指定参数名称(-name),powershell将按位置顺序处理它们

[CmdletBinding()]
Param(
  [string] version,
  [ValidateScript( { SomeModule/Search(version, $_); $true # FIND THIS VERSION IN SOURCE. **VERSION MUST HAVE BEEN SET BY NOW** } )]
  [string] source,
)
此时,应采取以下措施:

MyScript.ps1 12345ABC 'filesystem' 
MyScript.ps1 -source 'filesystem' -version 12345AB
这也应该起作用:

MyScript.ps1 12345ABC 'filesystem' 
MyScript.ps1 -source 'filesystem' -version 12345AB

我想这样称呼它:-源“文件系统”-版本12345ABC,但有PS进程-版本优先。所以如果我从其他评论中理解。。。您的问题实际上是关于
ValidateScript
,如果您没有在文件系统之前指定版本,脚本将无法工作?是的,就是这样。因为ValidateScript for source要求将版本设置为ReadyLook,就像您发现powershell在处理参数时所做的一件奇怪的事情一样。据我所知,这是无法避免的。ValidateScript实际上只用于验证单个参数。您最好将测试放入函数中并首先调用它。类似这样的东西
if(testsourceandfilesystem$version$filesystem){throw“Failed Validation”}
我想这样称呼它:-source'filesystem'-version 12345ABC,但有PS process-version优先。因此,如果我从其他注释中理解。。。您的问题实际上是关于
ValidateScript
,如果您没有在文件系统之前指定版本,脚本将无法工作?是的,就是这样。因为ValidateScript for source要求将版本设置为ReadyLook,就像您发现powershell在处理参数时所做的一件奇怪的事情一样。据我所知,这是无法避免的。ValidateScript实际上只用于验证单个参数。您最好将测试放入函数中并首先调用它。类似于这样的
if(Test SourceAndFilesystem$version$filesystem){throw“Failed Validation”}
(我假设OP实际上已经尝试过这个方法,并且发现它像问题中描述的那样工作[或者不工作]。如果实际上没有尝试过,请在以后提问之前尝试。)(我假设OP实际上已经尝试过了,并且发现它如问题中所述有效[或无效]。如果实际上没有尝试过,请在以后提问之前尝试。)