Powershell:针对不同环境的两个参数定义?

问题描述

我有一个很长而且很大的PS5 powershell脚本,其中包含几个参数,这些参数在脚本文件开头的param()部分中定义。 这些参数是字符串和哈希表,包括主机名,IP地址,域等。

该脚本在我的环境中可以很好地运行,但是现在它也应该在所有参数都不同的第二个环境中运行。

因此,在不更改所有脚本命令的情况下,我想用不同的值定义第二个param节,并在脚本顶部提供一个“ switch”变量,例如:

param1(
... my params1 ...)

param2(
... my params2 ... )

string configToUse = "param1"

我偶然发现了powershell参数集,但是我想这不是我想要的。 另外,我过去也使用了一些节点定义文件(.psd1),但是我想将所有内容保存在一个文件中,该文件只需双击即可执行,而不必在命令行上传递-param1或-param2。

有人可以指出我正确的方向吗?

谢谢!

解决方法

仅使用param语法在-param "value"语句中启用参数传递给脚本,我会强烈建议将参数传递给脚本。这样,您就可以在脚本中添加静态值了!它更干净,更健壮,更透明,更易于维护,更便携,更易于记录。

如果您仍然想要双击功能(可能是为了方便起见),则可以例如制作一个批处理文件来调用您的脚本。只会是一行(@会阻止将该行打印到控制台):

@powershell -File "your-script.ps1" -Param1 "value 1"

然后,您可以为每个环境创建单独的批处理文件。

call-mysript-env-1.bat
call-mysript-env-2.bat

或者,您可以使用快捷方式完成相同的操作,该快捷方式以相同的方式使用参数调用脚本。

如果仅出于任何原因而确实真的不想这样做,则可以完全忽略param语句(您不使用它的功能)是为任何方式制作的)。毕竟,参数基本上只是常规变量。您可以这样做:

### start of parameters ###
$configToUse = "param1"

switch ($configToUse) {
   "param1" {
       $MyParam = "value 1"
   }
   "param2" {
       $MyParam = "value 2"
   }
}
#### end of parameters ###
# rest of your script ....
,

良好的设计实践通常会强调使函数(包括脚本)仅接受来自参数的数据。这样做可能有助于故障排除和维护。但是,将默认值分配给参数并不会直接违反该准则。这实际上取决于您的受众和/或您的用例。此外,您希望获得有条件的分配默认和/或条件参数值的疯狂程度。

虽然您的代码无疑会更加复杂,但是下面是一个示例,您可以了解如何有条件地将默认值分配给参数。

Function Test-ConditionalParameterValues
{
    Param(
        [Parameter( Mandatory = $false )]
        [String]$Environment = 
                {
                    If( $Host.Name -eq 'Visual Studio Code Host' ) { 'VSCode'  }
                    If( $Host.Name -eq 'ConsoleHost' ) { 'ConsoleHost'  }
                }.Invoke()
        ) # End Parameter Block...

Write-Host $Environment

} # End Function Test-ConditionalParameterValues

我必须警告,这可能会在视觉上造成混乱,并且有些不合常规。团队环境中的可读性和可维护性可能是一个问题。

注意:根据您的分配,您可能不需要脚本块语法。如果分配可能是另一个cmdlet或函数的输出,则通常完全不需要(...)包装。

此外,参数设计建议中有时会忽略可测试性。我有很多实现-Environment参数的函数。环境参数通常具有一个验证集属性,例如[ValidateSet( 'Prod','Dev' )。类似于Marsze's answer的一部分,内部代码根据参数分配不同的值。对我来说,一个常见的用例是定义一个SQL连接字符串。这使我可以测试任意内部更改,而不会冒生产损坏等风险。

可能看起来像这样:

Function Insert-SomeData
{
Param(
    [Parameter(Mandatory = $false)]
    [ValidateSet( 'Prod','Dev' )]
    [String]$Environment = 'Prod'
    ) # End Parameter Block...

Switch ($Environment)
{
    'Prod' { $ConnString = "Production Connection String" }
    'Dev'  { $ConnString = "Dev Connection String"        }
}

# Rest of code would follow

尽管您可能需要删除或更改[ValidateSet()]来实现以下目的,但这种方法使您可以方便地在短时间内使用多个参数调用多个环境,也可以在需要时灵活地手动操作指定的数据。所需的灵活性。

注意:在常规使用中,在不同环境中运行时,调用仍然会略有不同,但是您不必在调用本身中敲定哈希表等大型数据集。

我必须重申,您的受众群体/消费者对于您执行此类操作很重要。如果我计划将脚本发布到库中,则即使在运行时选择硬编码的连接字符串也不能很好地工作,但是像上面这样的方法在企业环境中用于特殊任务和自动化代码的效果很好。