Frage

Diese Frage hat bereits eine Antwort hier:

Ich möchte in der Lage sein zu sagen, welchen Weg meine Ausführung des Skripts ausgeführt wurde.
Dies wird oft nicht $pwd.

Muss ich anrufen andere scripts, die in einem Ordner der Struktur relativ zu meinem Skript und während ich hart code die Pfade, die sowohl geschmacklos und ein bisschen ein Schmerz im Nacken, wenn Sie versuchen, zu fördern, aus "dev", "test" nach "Produktion".

War es hilfreich?

Lösung

Die allgegenwärtige Skript Zitat von Jeffrey Snover das PowerShell-team (in Skyler Antwort) und die Variationen geschrieben von Keith Cedirc, und EBGreen, alle leiden unter einem gravierenden Nachteil--ob der code berichtet, was Sie erwarten, hängt davon ab, wo Sie es nennen!

Mein code unten überwindet dieses problem, indem Sie einfach die Referenzierung Skript Umfang statt Eltern Umfang:

function Get-ScriptDirectory
{
    Split-Path $script:MyInvocation.MyCommand.Path
}

Um das problem zu veranschaulichen, habe ich ein test-Fahrzeug, evalutes die target-expression in vier verschiedene Arten.(Die Klammern sind die Schlüssel zu die folgende Ergebnis-Tabelle.)

  1. inline-code - [inline]
  2. inline-Funktion, D. H.Funktion im Hauptprogramm [inline-Funktion]
  3. Dot-sourced " - Funktion, D. H.die gleiche Funktion, in einem gesonderten .die ps1-Datei [dot source]
  4. Modul-Funktion, D. H.die gleiche Funktion, in einem gesonderten .psm1-Datei [Modul]

Die letzten beiden Spalten zeigen das Ergebnis der Verwendung von Skript-Umfang (d.h.$script:) oder mit übergeordneten Bereich (mit -scope 1).Ein Ergebnis von "Skript" bedeutet, dass der Aufruf korrekt berichtet den Speicherort des Skripts.Das "Modul" Ergebnis bedeutet, dass der Aufruf gemeldet die Position des Moduls mit der Funktion eher als das Skript, das die Funktion aufgerufen;dies weist auf einen Nachteil der beiden Funktionen Sie können die Funktion in ein Modul ein.

Einstellung der Modul-Problem beiseite die Bemerkenswerte Beobachtung aus der Tabelle ist, dass mit den übergeordneten Bereich Vorgehen versagt jedoch, die meisten der Zeit (in der Tat, doppelt so oft, wie es gelingt).

table of input combinations

Schließlich, hier ist das test-Fahrzeug:

function DoubleNested()
{
    "=== DOUBLE NESTED ==="
    NestCall
}

function NestCall()
{
    "=== NESTED ==="
    "top level:"
    Split-Path $script:MyInvocation.MyCommand.Path
    #$foo = (Get-Variable MyInvocation -Scope 1).Value
    #Split-Path $foo.MyCommand.Path
    "immediate func call"
    Get-ScriptDirectory1
    "dot-source call"
    Get-ScriptDirectory2
    "module call"
    Get-ScriptDirectory3
}

function Get-ScriptDirectory1
{
    Split-Path $script:MyInvocation.MyCommand.Path
    # $Invocation = (Get-Variable MyInvocation -Scope 1).Value
    # Split-Path $Invocation.MyCommand.Path
}

. .\ScriptDirFinder.ps1
Import-Module ScriptDirFinder -force

"top level:"
Split-Path $script:MyInvocation.MyCommand.Path
#$foo = (Get-Variable MyInvocation -Scope 1).Value
#Split-Path $foo.MyCommand.Path

"immediate func call"
Get-ScriptDirectory1
"dot-source call"
Get-ScriptDirectory2
"module call"
Get-ScriptDirectory3

NestCall
DoubleNested

Inhalt ScriptDirFinder.ps1:

function Get-ScriptDirectory2
{
    Split-Path $script:MyInvocation.MyCommand.Path
#   $Invocation = (Get-Variable MyInvocation -Scope 1).Value
#   Split-Path $Invocation.MyCommand.Path
}

Inhalt ScriptDirFinder.psm1:

function Get-ScriptDirectory3
{
    Split-Path $script:MyInvocation.MyCommand.Path
#   $Invocation = (Get-Variable MyInvocation -Scope 1).Value
#   Split-Path $Invocation.MyCommand.Path
}

Ich bin nicht vertraut mit dem, was war eingeführt in PowerShell 2, aber es könnte sehr gut sein, dass Skriptbereich nicht in der PowerShell-1, bei der Zeit-Jeffrey Snover veröffentlichten seinem Beispiel.

Ich war überrascht als wenn ich seine code-Beispiel vermehrt weit und breit auf der web scheiterte es sofort, wenn ich es versuchte!Aber das war, weil ich es anders, als Snover Beispiel (ich nannte es nicht am script, aber auch von innerhalb einer anderen Funktion (meine "nested zweimal" - Beispiel).)

2011.09.12 Update

Lesen Sie dazu auch mit anderen Tipps und tricks-Module in meinem gerade veröffentlichten Artikel auf Simple-Talk.com:Weiter Unten die Kaninchen Loch:PowerShell-Module und Kapselung.

Andere Tipps

Sie hat Ihre Frage für Powershell-version 1.0, jedoch, wenn Sie Zugriff auf Powershell version 3.0, die Sie wissen müssen $PSCommandPathund$PSScriptRootdas macht es den Pfad des Skripts ein wenig leichter.Bitte beziehen sich auf die "ANDERE SCRIPT FEATURES" - Abschnitt auf dieser Seite weitere Informationen.

Wir haben mit code wie diesen in den meisten unserer Skripte für mehrere Jahre ohne Probleme:

#--------------------------------------------------------------------
# Dot source support scripts
#--------------------------------------------------------------------
$ScriptPath = $MyInvocation.MyCommand.Path
$ScriptDir  = Split-Path -Parent $ScriptPath
. $ScriptDir\BuildVars.ps1
. $ScriptDir\LibraryBuildUtils.ps1
. $ScriptDir\BuildReportUtils.ps1

Ich lief in das gleiche Problem vor kurzem.Der folgende Artikel hat mir geholfen, das problem zu lösen: http://blogs.msdn.com/powershell/archive/2007/06/19/get-scriptdirectory.aspx

Wenn Sie nicht daran interessiert, wie es funktioniert, hier der code, den Sie benötigen pro Artikel:

function Get-ScriptDirectory
{
$Invocation = (Get-Variable MyInvocation -Scope 1).Value
Split-Path $Invocation.MyCommand.Path
}

Und dann bekommen Sie den Pfad, indem Sie einfach tun:

$path = Get-ScriptDirectory

Ich glaube, Sie finden den Pfad zu Ihrem Skript verwenden

$MyInvocation.MyCommand.Path

Hoffe, es hilft !

Cédric

Dies ist eine dieser Seltsamkeiten, die (meiner Meinung nach zumindest) in PS.Ich bin sicher, es ist ein absolut guter Grund für ihn, aber es scheint immer noch seltsam für mich.Also:

Wenn Sie in einem Skript, aber nicht in einer Funktion, dann $myInvocation.InvocationName geben Sie den vollständigen Pfad, einschließlich der Skript-name.Wenn Sie in einem Skript und innerhalb einer Funktion dann ist $myInvocation.Skriptname geben Sie die gleiche Sache.

Danke msorens!Das hat mir wirklich geholfen mit meinem benutzerdefinierten Modul.In den Fall, jemand ist daran interessiert, Ihre eigenen, hier ist, wie es bei mir aufgebaut ist.

MyModule (folder)
 - MyModule.psd1 (help New-ModuleManifest)
 - MyScriptFile.ps1 (ps1 files are easy to test)

Sie verweisen MyScriptFile.ps1 in MyModule.psd1.Die Referenzierung der .ps1 im NestedModules-array werden dann die Funktionen in den Modul-session-Status, statt den globalen Sitzungszustand.(Wie Schreibe ich einen Modul-Manifest)

NestedModules = @('.\MyScriptFile.ps1','.\MyOtherScriptFile.ps1')

Inhalt MyScriptFile.ps1

function Get-ScriptDirectory {
    Split-Path $script:MyInvocation.MyCommand.Path
}

try {
    Export-ModuleMember -Function "*-*"
}
catch{}

Der try/catch-blendet die Fehler aus Export-ModuleMember beim laufen MyScriptFile.ps1

Kopieren Sie die MyModule directory auf einem der Pfade finden Sie hier $env:PSModulePath

PS C:\>Import-Module MyModule
PS C:\>Get-Command -Module MyModule

CommandType     Name                                               ModuleName                                                                                                                                                
-----------     ----                                               ----------                                                                                                                                                
Function        Get-ScriptDirectory                                MyModule  
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top