스크립트의 인수를 사용하여 두 번째 스크립트를 호출합니다.
두 번째 PowerShell 스크립트의 함수에 인수로 전달하려는 이름 값 쌍 집합을 생성하는 구성 파일을 읽는 스크립트가 있습니다.
디자인 타임에이 구성 파일에 어떤 매개 변수가 배치 될지 모르겠습니다. 따라서이 두 번째 PowerShell 스크립트를 호출해야하는 시점에서 기본적으로이 두 번째 스크립트에 대한 경로가있는 변수 하나와 두 번째 path 변수에서 식별 된 스크립트에 전달할 인수 배열 인 변수입니다.
따라서 두 번째 스크립트 ($ scriptPath)에 대한 경로를 포함하는 변수는 다음과 같은 값을 가질 수 있습니다.
"c:\the\path\to\the\second\script.ps1"
인수 ($ argumentList)를 포함하는 변수는 다음과 같습니다.
-ConfigFilename "doohickey.txt" -RootDirectory "c:\some\kind\of\path" -Max 11
$ argumentList의 모든 인수를 사용하여이 상태에서 script.ps1을 실행하려면 어떻게해야합니까?
이 두 번째 스크립트의 쓰기 호스트 명령이이 첫 번째 스크립트가 호출 된 콘솔에 표시되기를 원합니다.
dot-sourcing, 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
... 다음은 invokee.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.
두 번째 호출은 잘 작동하지만 첫 번째 버전은 경로에 공백이있는 인수를 사용하고 두 번째 버전은 그렇지 않다는 점에서 중요한 차이점이 있습니다. 이 경로에 공백이 있는지 잘못 처리하고 있습니까?
아하. 이것은 스크립트 경로에 공백이 있다는 간단한 문제로 밝혀졌습니다.
Invoke-Expression 줄을 다음과 같이 변경합니다.
Invoke-Expression "& `"$scriptPath`" $argumentList"
... 시작하기에 충분했습니다. 도움과 피드백을 주신 Neolisk에게 감사드립니다!
Invoke-Expression
완벽하게 작동해야하며 올바르게 사용하고 있는지 확인하십시오. 귀하의 경우에는 다음과 같이 보일 것입니다.
Invoke-Expression "$scriptPath $argumentList"
I tested this approach with Get-Service and seems to be working as expected.
Much simpler actually:
Method 1:
Invoke-Expression $scriptPath $argumentList
Method 2:
& $scriptPath $argumentList
Method 3:
$scriptPath $argumentList
If you have spaces in your scriptPath
, don't forget to escape them `"$scriptPath`"
Here's an answer covering the more general question of calling another PS script from a PS script, as you may do if you were composing your scripts of many little, narrow-purpose scripts.
I found it was simply a case of using dot-sourcing. That is, you just do:
# This is Script-A.ps1
. ./Script-B.ps1 -SomeObject $variableFromScriptA -SomeOtherParam 1234;
I found all the Q/A very confusing and complicated and eventually landed upon the simple method above, which is really just like calling another script as if it was a function in the original script, which I seem to find more intuitive.
Dot-sourcing can "import" the other script in its entirety, using:
. ./Script-B.ps1
It's now as if the two files are merged.
Ultimately, what I was really missing is the notion that I should be building a module of reusable functions.
We can use splatting for this:
& $command @args
where @args
(automatic variable $args) is splatted into array of parameters.
Under PS, 5.1
I tried the accepted solution of using the Invoke-Expression cmdlet but it didn't work for me because my arguments had spaces on them. I tried to parse the arguments and escape the spaces but I couldn't properly make it work and also it was really a dirty work around in my opinion. So after some experimenting, my take on the problem is this:
function Invoke-Script
{
param
(
[Parameter(Mandatory = $true)]
[string]
$Script,
[Parameter(Mandatory = $false)]
[object[]]
$ArgumentList
)
$ScriptBlock = [Scriptblock]::Create((Get-Content $Script -Raw))
Invoke-Command -NoNewScope -ArgumentList $ArgumentList -ScriptBlock $ScriptBlock -Verbose
}
# example usage
Invoke-Script $scriptPath $argumentList
The only drawback of this solution is that you need to make sure that your script doesn't have a "Script" or "ArgumentList" parameter.
You can execute it same as SQL query. first, build your command/Expression and store in a variable and execute/invoke.
$command = ".\yourExternalScriptFile.ps1" + " -param1 '$paramValue'"
It is pretty forward, I don't think it needs explanations. So all set to execute your command now,
Invoke-Expression $command
I would recommend catching the exception here
ReferenceURL : https://stackoverflow.com/questions/12850487/invoke-a-second-script-with-arguments-from-a-script
'Nice programing' 카테고리의 다른 글
Eclipse Memory Analyser이지만 항상 내부 오류가 발생 했습니까? (0) | 2021.01.05 |
---|---|
PostgreSQL의 범위에서 날짜 목록 가져 오기 (0) | 2021.01.05 |
Vagrant 구성 설정을 로컬로 재정의 (개발자 별) (0) | 2021.01.05 |
키 스토어 란? (0) | 2021.01.05 |
Visual Studio Code에서 설정을 재설정하는 방법은 무엇입니까? (0) | 2021.01.05 |