Jaki jest najlepszy sposób na określenie lokalizacji bieżącego skryptu PowerShell?
Gdy muszę odwołać się do wspólnego modułu lub skryptu, lubię używać ścieżek względem bieżącego pliku skryptu. W ten sposób mój skrypt zawsze może znaleźć Inne skrypty w bibliotece.
Jaki jest najlepszy, standardowy sposób określania katalogu bieżącego skryptu? Aktualnie robię:
$MyDir = [System.IO.Path]::GetDirectoryName($myInvocation.MyCommand.Definition)
I know in modules (.psm1) możesz użyć $PSScriptRoot
, Aby uzyskać te informacje, ale nie jest to ustawiane w zwykłych skryptach (np. w plikach.ps1).
Co to jest kanoniczny sposób na uzyskanie lokalizacji aktualnego pliku skryptu PowerShell?
15 answers
PowerShell 3+
# This is an automatic variable set to the current file's/module's directory
$PSScriptRoot
PowerShell 2
[[3]}przed PowerShell 3 nie było lepszego sposobu niż odpytywanieMyInvocation.MyCommand.Definition
właściwość dla skryptów ogólnych. Miałem następujący wiersz na górze zasadniczo każdego skryptu PowerShell miałem:
$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-10-21 23:01:32
Jeśli tworzysz moduł V2, możesz użyć zmiennej automatycznej o nazwie
$PSScriptRoot
.
From PS > Help automatic_variable
$PSScriptRoot Contains the directory from which the script module is being executed. This variable allows scripts to use the module path to access other resources.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-19 01:38:39
Dla PowerShell 3.0
$PSCommandPath
Contains the full path and file name of the script that is being run.
This variable is valid in all scripts.
Funkcja jest wtedy:
function Get-ScriptDirectory {
Split-Path -Parent $PSCommandPath
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-19 01:39:34
Dla PowerShell 3 +
function Get-ScriptDirectory {
if ($psise) {
Split-Path $psise.CurrentFile.FullPath
}
else {
$global:PSScriptRoot
}
}
Umieściłem tę funkcję w moim profilu. Działa również w ISE przy użyciu F8/Run Selection.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-10-21 18:28:00
Może coś mi tu umyka... ale jeśli chcesz mieć obecny katalog roboczy, możesz po prostu użyć tego: (Get-Location).Path
Dla ciągu znaków lub Get-Location
dla obiektu.
function Get-Script-Directory
{
$scriptInvocation = (Get-Variable MyInvocation -Scope 1).Value
return Split-Path $scriptInvocation.MyCommand.Path
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-10-21 23:00:39
Bardzo podobne do już zamieszczonych odpowiedzi, ale piping wydaje się bardziej podobny do PowerShella:
$PSCommandPath | Split-Path -Parent
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-10-21 18:28:26
Używam zmiennej automatycznej $ExecutionContext
.
Będzie działać z PowerShell 2 i Później.
$ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath('.\')
$ExecutionContext Zawiera obiekt Engintrinsics, który reprezentuje kontekst wykonania hosta Windows PowerShell. Możesz użyj tej zmiennej, aby znaleźć obiekty wykonawcze, które są dostępne dla cmdletów.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-01-29 09:10:00
Zajęło mi trochę czasu opracowanie czegoś, co przyjęło zaakceptowaną odpowiedź i przekształciło ją w solidną funkcję.
Nie jestem pewien co do innych, ale pracuję w środowisku z maszynami zarówno na PowerShell w wersji 2 jak i 3, więc musiałem obsługiwać oba. Następująca funkcja oferuje graceful fallback:
Function Get-PSScriptRoot
{
$ScriptRoot = ""
Try
{
$ScriptRoot = Get-Variable -Name PSScriptRoot -ValueOnly -ErrorAction Stop
}
Catch
{
$ScriptRoot = Split-Path $script:MyInvocation.MyCommand.Path
}
Write-Output $ScriptRoot
}
Oznacza to również, że funkcja odnosi się do zakresu skryptu, a nie do zakresu rodzica, jak opisał Michael Sorens w jednym z jego postów na blogu .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-10-21 18:30:03
Musiałem znać nazwę skryptu i skąd jest wykonywany.
Prefiks "$global: "do struktury MyInvocation zwraca pełną ścieżkę i nazwę skryptu, gdy jest wywoływany zarówno ze skryptu głównego, jak i z importowanej linii .Plik biblioteki PSM1. Działa również z poziomu funkcji zaimportowanej biblioteki.
Po długim grzebieniu, zdecydowałem się na użycie $global: MyInvocation.InvocationName. Działa niezawodnie z CMD launch, Uruchom z Powershell i ISE. Obie local and UNC launches return the correct path.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-12 22:21:24
Zawsze używam tego małego fragmentu, który działa na PowerShell i ISE w ten sam sposób:
# Set active path to script-location:
$path = $MyInvocation.MyCommand.Path
if (!$path) {
$path = $psISE.CurrentFile.Fullpath
}
if ($path) {
$path = Split-Path $path -Parent
}
Set-Location $path
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-10-21 18:07:03
Odkryłem, że starsze rozwiązania opublikowane tutaj nie działają dla mnie na PowerShell V5. Wymyśliłem to:
try {
$scriptPath = $PSScriptRoot
if (!$scriptPath)
{
if ($psISE)
{
$scriptPath = Split-Path -Parent -Path $psISE.CurrentFile.FullPath
}
else {
Write-Host -ForegroundColor Red "Cannot resolve script file's path"
exit 1
}
}
}
catch {
Write-Host -ForegroundColor Red "Caught Exception: $($Error[0].Exception.Message)"
exit 2
}
Write-Host "Path: $scriptPath"
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-10-21 18:26:32
Wykorzystując fragmenty z tych wszystkich odpowiedzi i komentarzy, składam to razem dla każdego, kto widzi to pytanie w przyszłości. Obejmuje wszystkie sytuacje wymienione w pozostałych odpowiedziach
# If using ISE
if ($psISE) {
$ScriptPath = Split-Path -Parent $psISE.CurrentFile.FullPath
# If Using PowerShell 3 or greater
} elseif($PSVersionTable.PSVersion.Major -gt 3) {
$ScriptPath = $PSScriptRoot
# If using PowerShell 2 or lower
} else {
$ScriptPath = split-path -parent $MyInvocation.MyCommand.Path
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-01-09 16:24:17
Możesz również rozważyć split-path -parent $psISE.CurrentFile.Fullpath
, jeśli którakolwiek z innych metod zawodzi. W szczególności, jeśli uruchomisz plik, aby załadować kilka funkcji, a następnie wykonasz te funkcje z-w powłoce ISE (lub jeśli uruchomisz-zaznaczone), wygląda na to, że funkcja Get-Script-Directory
Jak powyżej nie działa.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-29 21:44:53
Jeśli chcesz załadować moduły ze ścieżki w stosunku do miejsca uruchomienia skryptu, na przykład z podfolderu "lib", musisz użyć jednej z następujących opcji:
$PSScriptRoot
który działa, gdy jest wywoływany jako skrypt, na przykład za pomocą polecenia PowerShell
$psISE.CurrentFile.FullPath
który działa, gdy biegasz wewnątrz ISE
Ale jeśli nie jesteś w żadnej z nich i po prostu piszesz w PowerShell shell, możesz użyć:
pwd.Path
Można przypisać jedną z trzech do zmiennej o nazwie $base
w zależności od environment you ' re running under, like so:
$base=$(if ($psISE) {Split-Path -Path $psISE.CurrentFile.FullPath} else {$(if ($global:PSScriptRoot.Length -gt 0) {$global:PSScriptRoot} else {$global:pwd.Path})})
Następnie w skryptach możesz go używać w następujący sposób:
Import-Module $base\lib\someConstants.psm1
Import-Module $base\lib\myCoolPsModule1.psm1
#etc.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-07-09 22:39:31
function func1()
{
$inv = (Get-Variable MyInvocation -Scope 1).Value
#$inv.MyCommand | Format-List *
$Path1 = Split-Path $inv.scriptname
Write-Host $Path1
}
function Main()
{
func1
}
Main
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-28 07:47:34