Quelle est la meilleure façon de déterminer l'emplacement du script PowerShell actuel?
chaque fois que j'ai besoin de faire référence à un module ou un script commun, j'aime utiliser des chemins relatifs au fichier de script courant, de cette façon, mon script peut toujours trouver d'Autres scripts dans la bibliothèque.
alors, quelle est la meilleure façon standard de déterminer le répertoire du script actuel? Actuellement, je fais:
$MyDir = [System.IO.Path]::GetDirectoryName($myInvocation.MyCommand.Definition)
je sais en modules.psm1) vous pouvez utiliser $PSScriptRoot
pour obtenir cette information, mais cela n'est pas défini dans les scripts réguliers (i.e. .ps1).
Quelle est la façon canonique d'obtenir l'emplacement actuel du fichier de script PowerShell?
11 réponses
# This is an automatic variable set to the current file's/module's directory
$PSScriptRoot
PowerShell 2
avant PowerShell 3, Il n'y avait pas de meilleur moyen que de
MyInvocation.MyCommand.Definition
propriété pour les scripts généraux. J'ai eu l'
la ligne suivante au sommet de chaque script powershell que j'ai eu:
$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
si vous créez un Module V2, vous pouvez utiliser une variable automatique appelée
$PSScriptRoot
.
de 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.
Pour 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.
la fonction est alors:
function Get-ScriptDirectory {
Split-Path -Parent $PSCommandPath
}
peut-être que je rate quelque chose ici... mais si vous voulez le répertoire de travail actuel, vous pouvez simplement utiliser ceci: (Get-Location).Path
pour une chaîne de caractères, ou Get-Location
pour un objet.
sauf si vous faites référence à quelque chose comme ça, ce que je comprends après avoir relu la question.
function Get-Script-Directory
{
$scriptInvocation = (Get-Variable MyInvocation -Scope 1).Value
return Split-Path $scriptInvocation.MyCommand.Path
}
j'utilise le variable automatique $ExecutionContext, il travaille à partir de PowerShell 2 et plus tard.
$ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath('.\')
$ExecutionContext Contient un objet Motorintrinsics qui représente contexte d'exécution de L'hôte PowerShell de Windows. Vous pouvez utilisez cette variable pour trouver les objets d'exécution qui sont disponible pour les applets de commande.
j'avais besoin de savoir le nom du script et d'où il est exécuté.
préfixe "$global: "à la structure MyInvocation renvoie le nom complet du chemin et du script lorsqu'il est appelé à partir du script principal et de la ligne principale d'un importé .PSM1 fichier de bibliothèque. Il fonctionne également à partir d'une fonction dans une bibliothèque importée.
après avoir beaucoup tripoté, j'ai décidé d'utiliser $global:MyInvocation.InvocationName. Il fonctionne de manière fiable avec CMD lancer, exécuter Avec Powershell, et L'ISE. Les lancements locaux et UNC renvoient le bon chemin.
m'a pris un certain temps pour développer quelque chose qui a pris la réponse acceptée et l'a transformée en une fonction robuste.
pas sûr pour les autres, mais je travaille dans un environnement avec des machines sur les versions 2 et 3 de PowerShell, donc j'ai eu besoin de gérer les deux. La fonction suivante offre un repli gracieux:
Function Get-PSScriptRoot
{
$ScriptRoot = ""
Try
{
$ScriptRoot = Get-Variable -Name PSScriptRoot -ValueOnly -ErrorAction Stop
}
Catch
{
$ScriptRoot = Split-Path $script:MyInvocation.MyCommand.Path
}
Write-Output $ScriptRoot
}
cela signifie également que la fonction se réfère à la portée du Script plutôt que la portée du parent comme souligné par Michael Sorens dans son blog
très similaire aux réponses déjà publiées, mais la tuyauterie semble PLUS PS-like.
$PSCommandPath | Split-Path -Parent
Pour Powershell 3+
function Get-ScriptDirectory {
if ($psise) {Split-Path $psise.CurrentFile.FullPath}
else {$global:PSScriptRoot}
}
j'ai placé cette fonction dans mon profil. Fonctionne dans ISE en utilisant la sélection F8/Run aussi.
vous pourriez aussi considérer split-path -parent $psISE.CurrentFile.Fullpath
si l'une des autres méthodes échoue. En particulier, si vous exécutez un fichier pour charger un tas de fonctions et ensuite exécuter ces fonctions avec-dans le shell ISE (ou si vous exécutez-selected), il semble que la fonction Get-Script-Directory
comme ci-dessus ne fonctionne pas.
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