Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

powershell - Invoke a second script with arguments from a script

I have a script that reads a configuration file that results in a set of name value pairs that I would like to pass as arguments to a function in a second PowerShell script.

I do not know what parameters will be placed in this configuration file at design time, so right at the point where I need to invoke this second PowerShell script, I basically just have one variable that has the path to this second script, and a second variable that is an array of arguments to pass to the script identified in the path variable.

So the variable containing the path to the second script ($scriptPath), might have a value like:

"c:hepathohesecondscript.ps1"

The variable containing the arguments ($argumentList) might look something like:

-ConfigFilename "doohickey.txt" -RootDirectory "c:somekindofpath" -Max 11

How do I get from this state of affairs to the execution of script.ps1 with all of the arguments from $argumentList?

I'd like any write-host commands from this second script to be visible to the console from which this first script is invoked.

I have tried dot-sourcing, Invoke-Command, Invoke-Expression, and Start-Job, but I haven't found an approach that doesn't produce errors.

For example, I thought the easiest first route was to try Start-Job called as follows:

Start-Job -FilePath $scriptPath -ArgumentList $argumentList

...but this fails with this error:

System.Management.Automation.ValidationMetadataException:
Attribute cannot be added because it would cause the variable
ConfigFilename with value -ConfigFilename to become invalid.

...in this case, "ConfigFilename" is the first parameter in the param list defined by the second script, and my invocation is apparently trying to set its value to "-ConfigFilename", which is obviously intended to identify the parameter by name, not set its value.

What am I missing?

EDIT:

Ok, here is a mock-up of the to-be-called script, in a file named 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

...and here is a mock-up of the calling script, in a file named 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

When I run invoker.ps1, this is the error I'm currently getting on the first call to Invoke-Expression:

Invoke-Expression : You must provide a value expression on
the right-hand side of the '-' operator.

The second call works just fine, but one significant difference is that the first version is using arguments whose paths have spaces in them, and the second does not. Am I mishandling the presence of spaces in these paths?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Aha. This turned out to be a simple problem of there being spaces in the path to the script.

Changing the Invoke-Expression line to:

Invoke-Expression "& `"$scriptPath`" $argumentList"

...was enough to get it to kick off. Thanks to Neolisk for your help and feedback!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...