Powershell ISE 내의 다른 PS1 스크립트에서 PowerShell 스크립트 PS1 호출


138

Powershell ISE의 ​​두 번째 myScript2.ps1 스크립트 내에서 myScript1.ps1 스크립트에 대한 호출 실행을 원합니다.

MyScript2.ps1의 다음 코드는 Powershell 관리에서 제대로 작동하지만 PowerShell ISE에서는 작동하지 않습니다.

#Call myScript1 from myScript2
invoke-expression -Command .\myScript1.ps1

PowerShell ISE에서 MyScript2.ps1을 실행할 때 다음 오류가 발생합니다.

'. \ myScript1.ps1'이라는 용어는 cmdlet, 함수, 스크립트 파일 또는 작동 가능한 프로그램의 이름으로 인식되지 않습니다. 이름의 철자를 확인하거나 경로가 포함 된 경우 경로가 올바른지 확인한 후 다시 시도하십시오.

답변:


83

스크립트의 위치를 ​​찾으려면 Split-Path $MyInvocation.MyCommand.Path을 사용하십시오 (스크립트 컨텍스트에서이를 사용하십시오).

이 예제 스크립트로 다른 것을 사용하지 말아야 할 이유를 설명 할 수 있습니다.

## ScriptTest.ps1
Write-Host "InvocationName:" $MyInvocation.InvocationName
Write-Host "Path:" $MyInvocation.MyCommand.Path

결과는 다음과 같습니다.

PS C : \ Users \ JasonAr>. \ ScriptTest.ps1
호출 이름 :. \ ScriptTest.ps1
경로 : C : \ Users \ JasonAr \ ScriptTest.ps1

PS C : \ Users \ JasonAr>입니다. . \ ScriptTest.ps1
호출 이름 :.
경로 : C : \ Users \ JasonAr \ ScriptTest.ps1

PS C : \ Users \ JasonAr> & ". \ ScriptTest.ps1"
호출 이름 : &
경로 : C : \ Users \ JasonAr \ ScriptTest.ps1

PowerShell 3.0 이상 에서는 자동 변수를 사용할 수 있습니다 $PSScriptRoot.

## ScriptTest.ps1
Write-Host "Script:" $PSCommandPath
Write-Host "Path:" $PSScriptRoot
PS C : \ Users \ jarcher>. \ ScriptTest.ps1
스크립트 : C : \ Users \ jarcher \ ScriptTest.ps1
경로 : C : \ Users \ jarcher

최근 추가 사항 : abot 차이가 걱정되는 경우 (또는 실제로 "단단한"코드를 원할 경우) "Write-Host"대신 "Write-Output"을 사용하고 싶을 것입니다.
KlaymenDK

20
응답에서 Split-Path 사용 예를 보는 것이 좋습니다. 또한 다른 스크립트 안에서 스크립트를 호출하는 것을 보여줘야합니다.
Jeremy

37

MyScript1.ps1의 현재 경로는 myScript2.ps1과 다릅니다. MyScript2.ps1의 폴더 경로를 가져 와서 MyScript1.ps1에 연결 한 다음 실행할 수 있습니다. 두 스크립트는 모두 같은 위치에 있어야합니다.

## MyScript2.ps1 ##
$ScriptPath = Split-Path $MyInvocation.InvocationName
& "$ScriptPath\MyScript1.ps1"

$ MyInvocation 변수를 어떻게 초기화해야합니까?
Nicola Celiento

자동 변수는 아닙니다.
Shay Levy

작동하지만 호출 된 스크립트를 실제로 실행하기 전에 다음 오류가 발생합니다. Split-Path : 빈 문자열이므로 'Path'매개 변수에 인수를 바인딩 할 수 없습니다. 줄 : 4 char : 25 + $ ScriptPath = Split-Path <<<< $ MyInvocation.InvocationName + CategoryInfo : InvalidData : (:) [Split-Path], ParameterBindingValidationException + FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAllowed, Microsoft.PowerShell.Commands.SplitPathCommand
니콜라 셀리 엔 토

$ MyInvocation.InvocationName이라는 새 스크립트를 작성하고 스크립트를 실행하십시오. 스크립트의 경로를 알고 있습니까?
Shay Levy

@JasonMArcher-왜 대신? 내가 아는 한 둘 다 같은 결과를 낳습니까?
manojlds

36

myScript2.ps1에서 myScript1.ps1을 호출하고 있습니다.

두 스크립트가 모두 같은 위치에 있다고 가정하면 먼저 다음 명령을 사용하여 스크립트 위치를 가져옵니다.

$PSScriptRoot

그런 다음 호출하려는 스크립트 이름을 다음과 같이 추가하십시오.

& "$PSScriptRoot\myScript1.ps1"

이 작동합니다.


3
& "$PSScriptRoot\myScript1.ps1"충분하다
Weihui Guo

19

한 줄 솔루션 :

& ((Split-Path $MyInvocation.InvocationName) + "\MyScript1.ps1")

이것은 좋지만 & '.\MyScript1.ps'스크립트가 동일한 디렉토리에 상주하는 이유 는 무엇입니까?
JoePC

3
스크립트 디렉토리가 아닌 현재 디렉토리를 사용하고 있습니다. 물론 그들은 종종 동일하지만 ... 항상 그런 것은 아닙니다!
noelicus

9

이것은 다른 파일에 인수를 전달하기 위해 답변에 대한 추가 정보 일뿐입니다.

당신이 논쟁을 기대하는 곳

PrintName.ps1

Param(
    [Parameter( Mandatory = $true)]
    $printName = "Joe"    
)


Write-Host $printName

파일을 호출하는 방법

Param(
    [Parameter( Mandatory = $false)]
    $name = "Joe"    
)


& ((Split-Path $MyInvocation.InvocationName) + "\PrintName.ps1") -printName $name

입력을 제공하지 않으면 기본적으로 "Joe"로 설정되며 이는 PrintName.ps1 파일의 printName 인수에 인수로 전달되어 "Joe" 문자열을 출력 합니다.


4

이미 답변을 찾았을 수도 있지만 여기에 내가하는 일이 있습니다.

나는 보통이 줄을 설치 스크립트의 시작 부분에 놓습니다.

if(!$PSScriptRoot){ $PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent } #In case if $PSScriptRoot is empty (version of powershell V.2).  

다음 예제와 같이 $ PSScriptRoot 변수를 현재 스크립트 (경로)의 위치로 사용할 수 있습니다.

if(!$PSScriptRoot){ $PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent } #In case if $PSScriptRoot is empty (version of powershell V.2).  

Try {
If (Test-Path 'C:\Program Files (x86)') {
    $ChromeInstallArgs= "/i", "$PSScriptRoot\googlechromestandaloneenterprise64_v.57.0.2987.110.msi", "/q", "/norestart", "/L*v `"C:\Windows\Logs\Google_Chrome_57.0.2987.110_Install_x64.log`""
    Start-Process -FilePath msiexec -ArgumentList $ChromeInstallArgs -Wait -ErrorAction Stop
    $Result= [System.Environment]::ExitCode
} Else {
    $ChromeInstallArgs= "/i", "$PSScriptRoot\googlechromestandaloneenterprise_v.57.0.2987.110.msi", "/q", "/norestart", "/L*v `"C:\Windows\Logs\Google_Chrome_57.0.2987.110_Install_x86.log`""
    Start-Process -FilePath msiexec -ArgumentList $ChromeInstallArgs -Wait -ErrorAction Stop
    $Result= [System.Environment]::ExitCode
    }

} ### End Try block


Catch  {
    $Result = [System.Environment]::Exitcode
    [System.Environment]::Exit($Result)
   }
[System.Environment]::Exit($Result)

귀하의 경우 교체 할 수 있습니다

시작 프로세스 ... 라인

호출 식 $ PSScriptRoot \ ScriptName.ps1

Microsoft 사이트에서 $ MYINVOCATION 및 $ PSScriptRoot 자동 변수에 대한 자세한 내용을 확인할 수 있습니다 : https://msdn.microsoft.com/en-us/powershell/reference/5.1/microsoft.powershell.core/about/about_automatic_variables


4

호출자와 동일한 폴더 (또는 하위 폴더)에서 스크립트 파일을 쉽게 실행하려면 다음을 사용하십시오.

# Get full path to the script:
$ScriptRoute = [System.IO.Path]::GetFullPath([System.IO.Path]::Combine($PSScriptRoot, "Scriptname.ps1"))

# Execute script at location:
&"$ScriptRoute"

3

나는 이것에 문제가 있었다. 나는 $MyInvocation그것을 고치기 위해 영리한 것을 사용하지 않았습니다 . 스크립트 파일을 마우스 오른쪽 버튼으로 클릭 edit하고 ISE 내에서 두 번째 스크립트를 선택한 다음 ISE를 열면 일반 . \ script.ps1 구문을 사용하여 다른 스크립트를 호출 할 수 있습니다 . 내 생각에 ISE는 현재 폴더의 개념을 가지고 있으며 이와 같이 열면 현재 폴더가 스크립트가 들어있는 폴더로 설정됩니다. 정상적인 사용에서 하나의 스크립트를 다른 스크립트에서 호출하면 . \ script.ps1 만 사용 합니다 .IMO 스크립트를 ISE에서 올바르게 작동하도록 수정하는 것은 잘못입니다 ...


2

나는 비슷한 문제가 있었고 이것을 이렇게 해결했다.

내 작업 디렉토리는 동일한 루트에있는 일반 스크립트 폴더 및 서버 특정 스크립트 폴더입니다. 특정 스크립트 폴더 (특정 문제의 매개 변수로 일반 스크립트를 호출)를 호출해야합니다. 따라서 작업 디렉토리는 다음과 같습니다

\Nico\Scripts\Script1.ps1
             \Script2.ps1
      \Problem1\Solution1.ps1
               \ParameterForSolution1.config
      \Problem2\Solution2.ps1
               \ParameterForSolution2.config

Solutions1 및 Solutions2는 PS1 in Scripts 폴더를 호출하여 ParameterForSolution에 저장된 매개 변수를로드합니다. powershell ISE 에서이 명령을 실행합니다.

.\Nico\Problem1\Solution1.PS1

그리고 Solution1.PS1의 코드는 다음과 같습니다.

# This is the path where my script is running
$path = split-path -parent $MyInvocation.MyCommand.Definition

# Change to root dir
cd "$path\..\.."

$script = ".\Script\Script1.PS1"

$parametro = "Problem1\ParameterForSolution1.config"
# Another set of parameter Script1.PS1 can receive for debuggin porpuose
$parametro +=' -verbose'

Invoke-Expression "$script $parametro"

2

고려할 예를 제출했습니다. 이것이 내가 만드는 도구에서 컨트롤러 스크립트에서 일부 코드를 호출하는 방법입니다. 작업을 수행하는 스크립트도 매개 변수를 승인해야하므로이 예제는 전달하는 방법을 보여줍니다. 호출되는 스크립트가 컨트롤러 스크립트 (스크립트 호출)와 동일한 디렉토리에 있다고 가정합니다.

[CmdletBinding()]
param (
[Parameter(Mandatory = $true)]
[string[]]
$Computername,

[Parameter(Mandatory = $true)]
[DateTime]
$StartTime,

[Parameter(Mandatory = $true)]
[DateTime]
$EndTime
)

$ZAEventLogDataSplat = @{
    "Computername" = $Computername
    "StartTime"    = $StartTime
    "EndTime"      = $EndTime
}

& "$PSScriptRoot\Get-ZAEventLogData.ps1" @ZAEventLogDataSplat

위는 3 개의 매개 변수를 허용하는 컨트롤러 스크립트입니다. 이들은 param 블록에 정의되어 있습니다. 그런 다음 컨트롤러 스크립트는 Get-ZAEventLogData.ps1이라는 스크립트를 호출합니다. 예를 들어이 스크립트는 동일한 3 개의 매개 변수도 허용합니다. 제어기 스크립트가 작업을 수행하는 스크립트를 호출 할 때이를 호출하고 매개 변수를 전달해야합니다. 위는 내가 뿌려서 어떻게하는지 보여줍니다.


1

스크립트 내에서 PowerShell 기본 제공 스크립트를 어떻게 실행합니까?

다음과 같은 내장 스크립트를 어떻게 사용합니까

Get-Location
pwd
ls
dir
split-path
::etc...

그것들은 컴퓨터에 의해 실행되어 자동으로 스크립트 경로를 확인합니다.

마찬가지로 스크립트 블록에 스크립트 이름을 입력하여 사용자 지정 스크립트를 실행할 수 있습니다.

::sid.ps1 is a PS script I made to find the SID of any user
::it takes one argument, that argument would be the username
echo $(sid.ps1 jowers)


(returns something like)> S-X-X-XXXXXXXX-XXXXXXXXXX-XXX-XXXX


$(sid.ps1 jowers).Replace("S","X")

(returns same as above but with X instead of S)

powershell 명령 행으로 이동하여 다음을 입력하십시오.

> $profile

그러면 앱을 열 때마다 PowerShell 명령 줄에서 실행할 파일의 경로가 반환됩니다.

이렇게 보일 것입니다

C:\Users\jowers\OneDrive\Documents\WindowsPowerShell\Microsoft.PowerShellISE_profile.ps1

문서로 이동하여 WindowsPowerShell 디렉토리가 있는지 확인하십시오. 나는하지 않았다

> cd \Users\jowers\Documents
> mkdir WindowsPowerShell
> cd WindowsPowerShell
> type file > Microsoft.PowerShellISE_profile.ps1

이제 PowerShell 앱을 열 때마다 실행될 스크립트를 만들었습니다.

우리가 그렇게 한 이유는 모든 사용자 지정 스크립트가 들어있는 자체 폴더를 추가 할 수 있기 때문입니다. 해당 폴더를 생성하고 Mac / Linux에서 스크립트를 보유한 디렉토리의 이름을 "Bin"으로 지정하겠습니다.

> mkdir \Users\jowers\Bin

이제 $env:path앱을 열 때마다 해당 디렉토리가 변수에 추가되기를 원하므로 디렉토리로 이동 WindowsPowerShell하여

> start Microsoft.PowerShellISE_profile.ps1

그런 다음 이것을 추가하십시오

$env:path += ";\Users\jowers\Bin"

이제 "Bin"디렉토리에 스크립트를 저장하는 한 쉘은 자동으로 명령을 찾습니다.

powershell을 다시 시작하면 실행되는 첫 번째 스크립트 중 하나 여야합니다.

재로드 후 명령 행에서 이것을 실행하여 경로 변수에서 새 디렉토리를보십시오.

> $env:Path

이제 다음과 같이 명령 행 또는 다른 스크립트 내에서 스크립트를 호출 할 수 있습니다.

$(customScript.ps1 arg1 arg2 ...)

보시다시피 .ps1별칭을 만들 때까지 확장명으로 호출해야 합니다. 우리가 화 내고 싶다면


와, 고마워요, 여기에 많은 것이 있습니다. 그러나 이미 9 가지 다른 답변이 있습니다. 이것은 어떻게 다릅니 까? 어떤 추가 정보를 제공합니까?
Stephen Rauch

이렇게하면 내장 스크립트가 스크립트 내에서 사용되는 것과 같은 방식으로 다른 스크립트 내에서 사용자 지정 스크립트를 사용할 수 있습니다. 이 작업을 수행하고 당신이 당신의 경로에 넣어 디렉토리에 스크립트를 저장 당신은 명령 줄이나 다른 스크립트에서 사용할 때 한, 컴퓨터가 자동으로 사용자 정의 스크립트의 경로를 찾을 수
타일러 커티스 Jowers
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.