참고 : PowerShell 1.0
현재 실행중인 PowerShell 파일 이름을 얻고 싶습니다. 즉, 다음과 같이 세션을 시작하면 :
powershell.exe .\myfile.ps1
문자열 ". \ myfile.ps1" (또는 이와 유사한 것) 을 얻고 싶습니다 . 편집 : "myfile.ps1" 이 바람직합니다.
어떤 아이디어?
참고 : PowerShell 1.0
현재 실행중인 PowerShell 파일 이름을 얻고 싶습니다. 즉, 다음과 같이 세션을 시작하면 :
powershell.exe .\myfile.ps1
문자열 ". \ myfile.ps1" (또는 이와 유사한 것) 을 얻고 싶습니다 . 편집 : "myfile.ps1" 이 바람직합니다.
어떤 아이디어?
답변:
여기에 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에서 도입되었습니다.$PSCommandPath레거시 (WindowsXP)가 필요하지 않은 경우 사용하지 않을 이유 가 없습니다.
function PSCommandPath ) 와 잘못된 함수에 대한 참조가 있습니다 ( Write-Host " * Direct: $PSCommandPath"; Write-Host " * Function: $(ScriptName)";-아니면 뭔가 분명한 것을 간과하고 있습니까?
대부분의 경우 현재 답변이 맞지만 정답을 제공하지 못하는 특정 상황이 있습니다. 스크립트 함수 내에서 사용하는 경우 :
$MyInvocation.MyCommand.Name
스크립트 이름 대신 함수 이름을 반환합니다.
function test {
$MyInvocation.MyCommand.Name
}
스크립트 이름에 관계없이 " test "를 제공합니다 . 스크립트 이름을 얻기위한 올바른 명령은 항상
$MyInvocation.ScriptName
실행중인 스크립트의 전체 경로를 반환합니다. 이 코드가 도움이 될 것보다 스크립트 파일 이름 만 필요한 경우 :
split-path $MyInvocation.PSCommandPath -Leaf
$MyInvocation.ScriptName나를 위해 빈 문자열 반환, PS v3.0.
다음을 시도하십시오
$path = $MyInvocation.MyCommand.Definition
이것은 입력 된 실제 경로를 제공하지 않을 수 있지만 파일에 대한 유효한 경로를 제공합니다.
$path = Split-Path $MyInvocation.MyCommand.Definition -Parent
스크립트가 실행되는 현재 디렉토리를 찾고 있다면 다음을 시도해 볼 수 있습니다.
$fullPathIncFileName = $MyInvocation.MyCommand.Definition
$currentScriptName = $MyInvocation.MyCommand.Name
$currentExecutingPath = $fullPathIncFileName.Replace($currentScriptName, "")
Write-Host $currentExecutingPath
C:\ilike.ps123\ke.ps1않습니까?
Replace()방법 이 바늘의 모든 발생 (마지막 발생뿐만 아니라)을 대체 하기 때문에 논리적 일 것 입니다. 그러나 문자열에서 빼기와 같은 작업을 수행하는 것은 좋은 생각입니다.
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)- 좋습니다 !
$currentScriptPath = $MyInvocation.MyCommand.Definition; $currentScriptName = $MyInvocation.MyCommand.Name; $currentScriptDir = $currentScriptPath.Substring(0,$currentScriptPath.IndexOf($currentScriptName));
주의 : $PSScriptRoot및 $PSCommandPath자동 변수 와 달리 자동 변수의
PSScriptRoot및 PSCommandPath속성 $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)
변수 $ 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
이전 응답에서 언급했듯이 "$ 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
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
이것은 대부분의 powershell 버전에서 작동합니다.
(& { $MyInvocation.ScriptName; })
이것은 예약 된 작업에 대해 작동 할 수 있습니다.
Get-ScheduledJob |? Name -Match 'JOBNAMETAG' |% Command