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?

7voto

Bruce Gavin Punkte 349

Ich musste den Namen des Skripts kennen und wissen, von wo aus es ausgeführt wird.

Durch das Voranstellen von "$global:" an die MyInvocation-Struktur werden der vollständige Pfad und der Skriptname zurückgegeben, wenn der Aufruf sowohl aus dem Hauptskript als auch aus der Hauptzeile einer importierten PSM1-Bibliotheksdatei erfolgt. Es funktioniert auch innerhalb einer Funktion in einer importierten Bibliothek.

Nach langem Hin und Her habe ich mich für die Verwendung von $global:MyInvocation.InvocationName entschieden. Es funktioniert zuverlässig mit CMD-Start, Run With Powershell und der ISE. Sowohl lokale als auch UNC-Starts geben den richtigen Pfad zurück.

3voto

fastboxster Punkte 49

Sie könnten auch Folgendes in Betracht ziehen split-path -parent $psISE.CurrentFile.Fullpath wenn eine der anderen Methoden fehlschlägt. Insbesondere, wenn Sie eine Datei ausführen, um eine Reihe von Funktionen zu laden und diese Funktionen dann in der ISE-Shell ausführen (oder wenn Sie run-selected), scheint es, dass die Get-Script-Directory Funktion wie oben funktioniert nicht.

3voto

Quantium Punkte 1741

Ich habe festgestellt, dass die älteren Lösungen, die hier gepostet wurden, bei mir unter PowerShell V5 nicht funktionierten. Ich kam mit diesem:

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"

2voto

zumalifeguard Punkte 8227

Wenn Sie Module aus einem Pfad laden wollen, der relativ zu dem Ort ist, an dem das Skript ausgeführt wird, z. B. aus einem "lib"-Unterordner, müssen Sie eine der folgenden Möglichkeiten verwenden:

$PSScriptRoot das funktioniert, wenn es als Skript aufgerufen wird, z. B. über den PowerShell-Befehl $psISE.CurrentFile.FullPath das funktioniert, wenn Sie innerhalb von ISE arbeiten

Aber wenn Sie weder das eine noch das andere tun und nur in einer PowerShell-Shell tippen, können Sie das verwenden:

pwd.Path

Sie können eine der drei Möglichkeiten einer Variablen namens $base abhängig von der Umgebung, in der Sie arbeiten, etwa so:

$base=$(if ($psISE) {Split-Path -Path $psISE.CurrentFile.FullPath} else {$(if ($global:PSScriptRoot.Length -gt 0) {$global:PSScriptRoot} else {$global:pwd.Path})})

In Ihren Skripten können Sie sie dann wie folgt verwenden:

Import-Module $base\lib\someConstants.psm1
Import-Module $base\lib\myCoolPsModule1.psm1
#etc.

-4voto

Ravi Punkte 1
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

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