현재 PowerShell 실행 파일을 얻으려면 어떻게해야합니까?


92

참고 : PowerShell 1.0
현재 실행중인 PowerShell 파일 이름을 얻고 싶습니다. 즉, 다음과 같이 세션을 시작하면 :

powershell.exe .\myfile.ps1

문자열 ". \ myfile.ps1" (또는 이와 유사한 것) 을 얻고 싶습니다 . 편집 : "myfile.ps1" 이 바람직합니다.
어떤 아이디어?


감사합니다. 현재 답변은 거의 동일하지만 전체 경로가 아닌 파일 이름 만 필요하므로 허용되는 답변은 @ Keith 's입니다. 하지만 두 답변 모두 +1. 이제 $ MyInvocation에 대해 알고 있습니다. :-)
Ron Klein

포함 된 스크립트에서 상위 스크립트를 가져 오는 것은 어떻습니까?
Florin Sabau 2013

답변:


67

여기에 PowerShell 5 용으로 업데이트 된 다양한 답변을 요약하려고했습니다.

  • PowerShell 3 이상 만 사용하는 경우 $PSCommandPath

  • 이전 버전과의 호환성을 원하면 shim을 삽입하십시오.

    if ($PSCommandPath -eq $null) { function GetPSCommandPath() { return $MyInvocation.PSCommandPath; } $PSCommandPath = GetPSCommandPath; }

    $PSCommandPath이미 존재하지 않는 경우 추가 됩니다.

    shim 코드는 어디에서나 (최상위 수준 또는 함수 내부) 실행할 수 있지만 $PSCommandPath변수에는 일반적인 범위 지정 규칙이 적용됩니다 (예 : 함수에 shim을 넣는 경우 변수의 범위는 해당 함수로만 지정됨).

세부

다양한 답변에 사용되는 4 가지 방법이 있으므로 각각을 설명하기 위해이 스크립트를 작성했습니다 $PSCommandPath.

function PSCommandPath() { return $PSCommandPath; }
function ScriptName() { return $MyInvocation.ScriptName; }
function MyCommandName() { return $MyInvocation.MyCommand.Name; }
function MyCommandDefinition() {
    # Begin of MyCommandDefinition()
    # Note: ouput of this script shows the contents of this function, not the execution result
    return $MyInvocation.MyCommand.Definition;
    # End of MyCommandDefinition()
}
function MyInvocationPSCommandPath() { return $MyInvocation.PSCommandPath; }

Write-Host "";
Write-Host "PSVersion: $($PSVersionTable.PSVersion)";
Write-Host "";
Write-Host "`$PSCommandPath:";
Write-Host " *   Direct: $PSCommandPath";
Write-Host " * Function: $(ScriptName)";
Write-Host "";
Write-Host "`$MyInvocation.ScriptName:";
Write-Host " *   Direct: $($MyInvocation.ScriptName)";
Write-Host " * Function: $(ScriptName)";
Write-Host "";
Write-Host "`$MyInvocation.MyCommand.Name:";
Write-Host " *   Direct: $($MyInvocation.MyCommand.Name)";
Write-Host " * Function: $(MyCommandName)";
Write-Host "";
Write-Host "`$MyInvocation.MyCommand.Definition:";
Write-Host " *   Direct: $($MyInvocation.MyCommand.Definition)";
Write-Host " * Function: $(MyCommandDefinition)";
Write-Host "";
Write-Host "`$MyInvocation.PSCommandPath:";
Write-Host " *   Direct: $($MyInvocation.PSCommandPath)";
Write-Host " * Function: $(MyInvocationPSCommandPath)";
Write-Host "";

산출:

PS C:\> .\Test\test.ps1

PSVersion: 5.1.19035.1

$PSCommandPath:
 *   Direct: C:\Test\test.ps1
 * Function: C:\Test\test.ps1

$MyInvocation.ScriptName:
 *   Direct:
 * Function: C:\Test\test.ps1

$MyInvocation.MyCommand.Name:
 *   Direct: test.ps1
 * Function: MyCommandName

$MyInvocation.MyCommand.Definition:
 *   Direct: C:\Test\test.ps1
 * Function:
    # Begin of MyCommandDefinition()
    # Note this is the contents of the MyCommandDefinition() function, not the execution results
    return $MyInvocation.MyCommand.Definition;
    # End of MyCommandDefinition()


$MyInvocation.PSCommandPath:
 *   Direct:
 * Function: C:\Test\test.ps1

노트:

  • 에서 실행 C:\되지만 실제 스크립트는 C:\Test\test.ps1.
  • 전달 된 호출 경로 ( .\Test\test.ps1)를 알려주는 메서드가 없습니다.
  • $PSCommandPath 유일한 신뢰할 수있는 방법이지만 PowerShell 3에서 도입되었습니다.
  • 3 이전 버전의 경우 함수 내부 및 외부에서 단일 메서드가 작동하지 않습니다.

7
오늘 (2017)을 읽는 사람이라면이 게시물을 정답으로 읽어야합니다! 한
콜린 차핀

2
@CollinChaffin : 동의했으며 현재 (2017) 현재 지원되는 최소 항목은 Windows 7이므로 $PSCommandPath레거시 (WindowsXP)가 필요하지 않은 경우 사용하지 않을 이유 가 없습니다.
tukan

첫 번째 코드 예제는 동일한 함수 (function PSCommandPath ) 와 잘못된 함수에 대한 참조가 있습니다 ( Write-Host " * Direct: $PSCommandPath"; Write-Host " * Function: $(ScriptName)";-아니면 뭔가 분명한 것을 간과하고 있습니까?
Mike L' Angelo

@ MikeL'Angelo 당신이 맞아요! 3 년 동안 눈에 띄지 않았습니다. 수정되었습니다. 감사합니다. 결과와 결론은 동일합니다.
gregmac

81

대부분의 경우 현재 답변이 맞지만 정답을 제공하지 못하는 특정 상황이 있습니다. 스크립트 함수 내에서 사용하는 경우 :

$MyInvocation.MyCommand.Name 

스크립트 이름 대신 함수 이름을 반환합니다.

function test {
    $MyInvocation.MyCommand.Name
}

스크립트 이름에 관계없이 " test "를 제공합니다 . 스크립트 이름을 얻기위한 올바른 명령은 항상

$MyInvocation.ScriptName

실행중인 스크립트의 전체 경로를 반환합니다. 이 코드가 도움이 될 것보다 스크립트 파일 이름 만 필요한 경우 :

split-path $MyInvocation.PSCommandPath -Leaf

6
최상위 수준에서 Scriptname은 posh v4로 정의되지 않습니다. 나는 다른 답변에 따라 전체 경로 또는 이름에 대해 최상위 $ MyInvocation.MyCommand.Definition을 사용하고 싶습니다.
AnneTheAgile

30
$MyInvocation.ScriptName나를 위해 빈 문자열 반환, PS v3.0.
JohnC 2015-04-20

4
@JohnC $MyInvocation.ScriptName는 함수 내부에서만 작동합니다. 아래 내 대답을 참조하십시오 .
gregmac

72

전체 경로가 아닌 파일 이름 만 원하면 다음을 사용하십시오.

$ScriptName = $MyInvocation.MyCommand.Name

32

다음을 시도하십시오

$path =  $MyInvocation.MyCommand.Definition 

이것은 입력 된 실제 경로를 제공하지 않을 수 있지만 파일에 대한 유효한 경로를 제공합니다.


1
@Hamish 질문은 파일에서 호출되는 경우 구체적으로 말합니다.
JaredPar

참고 : 전체 경로와 파일 이름 (Powershell 2.0)을 제공합니다.
Ralph Willgoss 2010 년

정확히이 명령을 찾고있었습니다. 감사합니다, JaredPar! :)
sqlfool 2013

분할 경로를 사용하여 디렉터리를 가져 오시겠습니까? $path = Split-Path $MyInvocation.MyCommand.Definition -Parent
Underverse

7

스크립트가 실행되는 현재 디렉토리를 찾고 있다면 다음을 시도해 볼 수 있습니다.

$fullPathIncFileName = $MyInvocation.MyCommand.Definition
$currentScriptName = $MyInvocation.MyCommand.Name
$currentExecutingPath = $fullPathIncFileName.Replace($currentScriptName, "")

Write-Host $currentExecutingPath

1
에서 제대로 작동하지 C:\ilike.ps123\ke.ps1않습니까?
fridojet 2012-06-06

@fridojet-확실하지 않습니다. 테스트 할 PS 터미널 근처가 아닙니다. 왜 그것을 시도하고 보지 않습니까?
Ryk 2012

아니요, 수사학적인 질문 일뿐입니다 ;-)-이 Replace()방법 이 바늘의 모든 발생 (마지막 발생뿐만 아니라)을 대체 하기 때문에 논리적 일 것 입니다. 그러나 문자열에서 빼기와 같은 작업을 수행하는 것은 좋은 생각입니다.
fridojet 2012-06-07

... String.TrimEnd()( $currentExecutingPath = $fullPathIncFileName.TrimEnd($currentScriptName)) 은 (는 )? -올바르게 작동합니다 : "Ich bin Hamster".TrimEnd("ster")반품 Ich bin Ham"Ich bin Hamsterchen".TrimEnd("ster")반품 Ich bin Hamsterchen(대신 Ich bin Hamchen)- 좋습니다 !
fridojet 2012-06-07

$currentScriptPath = $MyInvocation.MyCommand.Definition; $currentScriptName = $MyInvocation.MyCommand.Name; $currentScriptDir = $currentScriptPath.Substring(0,$currentScriptPath.IndexOf($currentScriptName));
YP

7

주의 : $PSScriptRoot$PSCommandPath자동 변수 와 달리 자동 변수의 PSScriptRootPSCommandPath속성 $MyInvocation에는 현재 스크립트가 아닌 호출자 또는 호출 스크립트에 대한 정보가 포함됩니다.

예 :

PS C:\Users\S_ms\OneDrive\Documents> C:\Users\SP_ms\OneDrive\Documents\DPM ...
=!C:\Users\S_ms\OneDrive\Documents\DPM.ps1

... DPM.ps1포함하는 곳

Write-Host ("="+($MyInvocation.PSCommandPath)+"!"+$PSCommandPath)

4

변수 $ MyInvocation.MyCommand.Path의 범위를 설정하여 더 나은 방법이 있다고 주장합니다.

예> $ 스크립트 : MyInvocation.MyCommand.Name

이 메서드는 모든 호출 상황에서 작동합니다.

예 : Somescript.ps1

function printme () {
    "In function:"
    ( "MyInvocation.ScriptName: " + [string]($MyInvocation.ScriptName) )
    ( "script:MyInvocation.MyCommand.Name: " + [string]($script:MyInvocation.MyCommand.Name) )
    ( "MyInvocation.MyCommand.Name: " + [string]($MyInvocation.MyCommand.Name) )
}
"Main:"
( "MyInvocation.ScriptName: " + [string]($MyInvocation.ScriptName) )
( "script:MyInvocation.MyCommand.Name: " + [string]($script:MyInvocation.MyCommand.Name) )
( "MyInvocation.MyCommand.Name: " + [string]($MyInvocation.MyCommand.Name) )
" "
printme
exit

산출:

PS> powershell C:\temp\test.ps1
Main:
MyInvocation.ScriptName:
script:MyInvocation.MyCommand.Name: test.ps1
MyInvocation.MyCommand.Name: test.ps1

In function:
MyInvocation.ScriptName: C:\temp\test.ps1
script:MyInvocation.MyCommand.Name: test.ps1
MyInvocation.MyCommand.Name: printme

위의 수락 된 답변이 Main에서 호출 될 때 값을 반환하지 않는 방법에 유의하십시오. 또한 질문이 스크립트 이름 만 요청한 경우 위의 수락 된 답변은 전체 경로를 반환합니다. 범위 변수는 모든 위치에서 작동합니다.

또한 전체 경로를 원하면 다음을 호출하면됩니다.

$script:MyInvocation.MyCommand.Path

3

이전 응답에서 언급했듯이 "$ MyInvocation"을 사용하면 범위 지정 문제가 발생하며 반드시 일관된 데이터를 제공하지는 않습니다 (반환 값 대 직접 액세스 값). 스크립트 경로, 이름, 매개 변수, 명령 줄 등과 같은 스크립트 정보를 가져 오는 "가장 깔끔한"(가장 일관된) 방법은 범위 (메인 또는 후속 / 중첩 함수 호출)에 관계없이 "Get- "MyInvocation"의 변수 "...

# Get the MyInvocation variable at script level
# Can be done anywhere within a script
$ScriptInvocation = (Get-Variable MyInvocation -Scope Script).Value

# Get the full path to the script
$ScriptPath = $ScriptInvocation.MyCommand.Path

# Get the directory of the script
$ScriptDirectory = Split-Path $ScriptPath

# Get the script name
# Yes, could get via Split-Path, but this is "simpler" since this is the default return value
$ScriptName = $ScriptInvocation.MyCommand.Name

# Get the invocation path (relative to $PWD)
# @GregMac, this addresses your second point
$InvocationPath = ScriptInvocation.InvocationName

따라서 $ PSCommandPath와 동일한 정보를 얻을 수 있지만 거래에서 훨씬 더 많은 정보를 얻을 수 있습니다. 확실하지는 않지만 "Get-Variable"은 PS3까지 사용할 수 없었기 때문에 정말 오래된 (업데이트되지 않은) 시스템에는 많은 도움이되지 않는 것 같습니다.

호출 함수의 이름 등을 얻기 위해 역 추적 할 수 있으므로 "-Scope"를 사용할 때 흥미로운 측면도 있습니다. 0 = 현재, 1 = 상위 등

이것이 다소 도움이되기를 바랍니다.

Ref, https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/get-variable


1

PS 2와 PS 4에서 다음 스크립트를 사용하여 몇 가지 테스트를 수행 한 결과 동일한 결과가 나왔습니다. 이것이 사람들에게 도움이되기를 바랍니다.

$PSVersionTable.PSVersion
function PSscript {
  $PSscript = Get-Item $MyInvocation.ScriptName
  Return $PSscript
}
""
$PSscript = PSscript
$PSscript.FullName
$PSscript.Name
$PSscript.BaseName
$PSscript.Extension
$PSscript.DirectoryName

""
$PSscript = Get-Item $MyInvocation.InvocationName
$PSscript.FullName
$PSscript.Name
$PSscript.BaseName
$PSscript.Extension
$PSscript.DirectoryName

결과-

Major  Minor  Build  Revision
-----  -----  -----  --------
4      0      -1     -1      

C:\PSscripts\Untitled1.ps1
Untitled1.ps1
Untitled1
.ps1
C:\PSscripts

C:\PSscripts\Untitled1.ps1
Untitled1.ps1
Untitled1
.ps1
C:\PSscripts

1

이것은 대부분의 powershell 버전에서 작동합니다.

(& { $MyInvocation.ScriptName; })

이것은 예약 된 작업에 대해 작동 할 수 있습니다.

Get-ScheduledJob |? Name -Match 'JOBNAMETAG' |% Command
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.