【发布时间】:2024-01-19 10:45:02
【问题描述】:
我有一个脚本,它读取一个配置文件,该文件生成一组名称值对,我想将它们作为参数传递给第二个 PowerShell 脚本中的函数。
我不知道在设计时会在这个配置文件中放置什么参数,所以在我需要调用第二个 PowerShell 脚本的时候,我基本上只有一个变量,它具有第二个脚本的路径,第二个变量是一个参数数组,传递给路径变量中标识的脚本。
因此,包含第二个脚本 ($scriptPath) 路径的变量可能具有如下值:
"c:\the\path\to\the\second\script.ps1"
包含参数的变量 ($argumentList) 可能类似于:
-ConfigFilename "doohickey.txt" -RootDirectory "c:\some\kind\of\path" -Max 11
如何使用 $argumentList 中的所有参数执行 script.ps1?
我希望第二个脚本中的任何写入主机命令对调用第一个脚本的控制台可见。
我尝试过点源、Invoke-Command、Invoke-Expression 和 Start-Job,但我没有找到不会产生错误的方法。
例如,我认为最简单的第一条路线是尝试如下调用的 Start-Job:
Start-Job -FilePath $scriptPath -ArgumentList $argumentList
...但是失败并出现以下错误:
System.Management.Automation.ValidationMetadataException:
Attribute cannot be added because it would cause the variable
ConfigFilename with value -ConfigFilename to become invalid.
...在这种情况下,“ConfigFilename”是第二个脚本定义的参数列表中的第一个参数,我的调用显然试图将其值设置为“-ConfigFilename”,这显然是为了识别按名称参数,而不是设置其值。
我错过了什么?
编辑:
好的,这是一个被调用脚本的模型,在一个名为 invokee.ps1 的文件中
Param(
[parameter(Mandatory=$true)]
[alias("rc")]
[string]
[ValidateScript( {Test-Path $_ -PathType Leaf} )]
$ConfigurationFilename,
[alias("e")]
[switch]
$Evaluate,
[array]
[Parameter(ValueFromRemainingArguments=$true)]
$remaining)
function sayHelloWorld()
{
Write-Host "Hello, everybody, the config file is <$ConfigurationFilename>."
if ($ExitOnErrors)
{
Write-Host "I should mention that I was told to evaluate things."
}
Write-Host "I currently live here: $gScriptDirectory"
Write-Host "My remaining arguments are: $remaining"
Set-Content .\hello.world.txt "It worked"
}
$gScriptPath = $MyInvocation.MyCommand.Path
$gScriptDirectory = (Split-Path $gScriptPath -Parent)
sayHelloWorld
...这里是调用脚本的模型,在一个名为 invoker.ps1 的文件中:
function pokeTheInvokee()
{
$scriptPath = (Join-Path -Path "." -ChildPath "invokee.ps1")
$scriptPath = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($scriptPath)
$configPath = (Join-Path -Path "." -ChildPath "invoker.ps1")
$configPath = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($configPath)
$argumentList = @()
$argumentList += ("-ConfigurationFilename", "`"$configPath`"")
$argumentList += , "-Evaluate"
Write-Host "Attempting to invoke-expression with: `"$scriptPath`" $argumentList"
Invoke-Expression "`"$scriptPath`" $argumentList"
Invoke-Expression ".\invokee.ps1 -ConfigurationFilename `".\invoker.ps1`" -Evaluate
Write-Host "Invokee invoked."
}
pokeTheInvokee
当我运行invoker.ps1 时,这是我在第一次调用Invoke-Expression 时遇到的错误:
Invoke-Expression : You must provide a value expression on
the right-hand side of the '-' operator.
第二个调用工作得很好,但一个显着的区别是第一个版本使用的参数的路径中有空格,而第二个没有。我是否错误地处理了这些路径中存在的空格?
【问题讨论】:
-
如果您为每个脚本提供源代码也会有所帮助。例如,创建 POC(概念证明)项目来说明您的问题。然后我们可以测试并使用它,也许有人会找到解决方案或解决方法。
-
是的 - 我正在尝试制作一个迷你版来说明。很快就会发布...
标签: powershell parameter-passing command-line-arguments invoke-command start-job