727 Stimmen

Wie lässt sich der Speicherort des aktuellen PowerShell-Skripts am besten ermitteln?

Wenn ich auf ein gemeinsames Modul oder Skript verweisen muss, verwende ich gerne Pfade relativ zur aktuellen Skriptdatei. Auf diese Weise kann mein Skript immer andere Skripte in der Bibliothek finden.

Was ist also die beste Standardmethode, um das Verzeichnis des aktuellen Skripts zu bestimmen? Derzeit mache ich das:

$MyDir = [System.IO.Path]::GetDirectoryName($myInvocation.MyCommand.Definition)

Ich weiß, dass Sie in Modulen (.psm1) Folgendes verwenden können $PSScriptRoot um diese Informationen zu erhalten, aber das wird in normalen Skripten (d.h. .ps1-Dateien) nicht gesetzt.

Wie kann ich den Speicherort der aktuellen PowerShell-Skriptdatei abrufen?

16voto

Viggos Punkte 329

Ich benutze die automatische Variable $ExecutionContext . Es funktioniert ab PowerShell 2 und höher.

 $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath('.\')

$Ausführungskontext Enthält ein EngineIntrinsics-Objekt, das die Ausführungskontext des Windows PowerShell-Hosts darstellt. Sie können dieser Variablen können Sie die Ausführungsobjekte suchen, die die für Cmdlets verfügbar sind.

13voto

CPAR Punkte 131

Sehr ähnlich zu den bereits geposteten Antworten, aber das Piping scheint mehr PowerShell-ähnlich zu sein:

$PSCommandPath | Split-Path -Parent

12voto

Bruno Punkte 5652

Ich habe eine Weile gebraucht, um etwas zu entwickeln, das die akzeptierte Antwort in eine robuste Funktion umwandelt.

Ich bin mir nicht sicher, wie es bei anderen ist, aber ich arbeite in einer Umgebung mit Computern, die sowohl mit PowerShell Version 2 als auch mit PowerShell Version 3 arbeiten, daher musste ich beide Versionen beherrschen. Die folgende Funktion bietet einen eleganten 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
}

Es bedeutet auch, dass sich die Funktion auf den Skriptbereich und nicht auf den übergeordneten Bereich bezieht, wie von Michael Sorens dargelegt in einem seiner Blogbeiträge .

10voto

Randy Punkte 919

Unter Verwendung von Teilen aus all diesen Antworten und den Kommentaren habe ich dies für jeden zusammengestellt, der diese Frage in Zukunft stellt. Sie deckt alle Situationen ab, die in den anderen Antworten aufgeführt sind, und ich habe eine weitere hinzugefügt, die ich als Ausfallsicherung gefunden habe.

function Get-ScriptPath()
{
    # If using PowerShell ISE
    if ($psISE)
    {
        $ScriptPath = Split-Path -Parent -Path $psISE.CurrentFile.FullPath
    }
    # If using PowerShell 3.0 or greater
    elseif($PSVersionTable.PSVersion.Major -gt 3)
    {
        $ScriptPath = $PSScriptRoot
    }
    # If using PowerShell 2.0 or lower
    else
    {
        $ScriptPath = split-path -parent $MyInvocation.MyCommand.Path
    }

    # If still not found
    # I found this can happen if running an exe created using PS2EXE module
    if(-not $ScriptPath) {
        $ScriptPath = [System.AppDomain]::CurrentDomain.BaseDirectory.TrimEnd('\')
    }

    # Return result
    return $ScriptPath
}

9voto

Carsten Punkte 963

Ich verwende immer dieses kleine Snippet, das für PowerShell und ISE auf die gleiche Weise:

# 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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X