Cela devrait être une tâche simple, mais j'ai déjà vu plusieurs tentatives pour obtenir le chemin d'accès au répertoire où se trouve la cmdlet exécutée avec un succès mitigé. Par exemple, lorsque j'exécute c:\temp\myscripts\mycmdlet.ps1
qui a un fichier de paramètres à c:\temp\myscripts\settings.xml
, j'aimerais pouvoir stocker c:\temp\myscripts
dans une variable de mycmdlet.ps1
.
C'est une solution qui fonctionne (bien qu'un peu lourde):
$invocation = (Get-Variable MyInvocation).Value
$directorypath = Split-Path $invocation.MyCommand.Path
$settingspath = $directorypath + '\settings.xml'
Un autre a suggéré cette solution qui ne fonctionne que sur notre environnement de test:
$settingspath = '.\settings.xml'
J'aime beaucoup cette dernière approche et préfère le fait de devoir analyser le chemin du fichier en tant que paramètre à chaque fois, mais je ne peux pas le faire fonctionner dans mon environnement de développement. Quelqu'un a-t-il une suggestion à faire? Cela a-t-il quelque chose à voir avec la configuration de PowerShell?
Le moyen fiable de faire ceci est juste comme vous avez montré $MyInvocation.MyCommand.Path
.
L’utilisation des chemins relatifs sera basée sur $ pwd, dans PowerShell, le répertoire en cours d’une application ou le répertoire de travail en cours d’une API .NET.
Oui ça devrait marcher. Mais si vous avez besoin de voir le chemin absolu, c’est tout ce dont vous avez besoin:
(Get-Item -Path ".\").FullName
La méthode la plus simple semble être d'utiliser la variable prédéfinie suivante:
$PSScriptRoot
about_Automatic_Variables
et about_Scripts
les deux indiquent:
Dans PowerShell 2.0, cette variable est valide uniquement dans les modules de script (.psm1). À compter de PowerShell 3.0, il est valide dans tous les scripts.
Je l'utilise comme ça:
$MyFileName = "data.txt"
$filebase = Join-Path $PSScriptRoot $MyFileName
Vous pouvez aussi utiliser:
(Resolve-Path .\).Path
La partie entre parenthèses renvoie un PathInfo
object.
(Disponible depuis PowerShell 2.0.)
Le chemin est souvent nul. Cette fonction est plus sûre.
function Get-ScriptDirectory
{
$Invocation = (Get-Variable MyInvocation -Scope 1).Value;
if($Invocation.PSScriptRoot)
{
$Invocation.PSScriptRoot;
}
Elseif($Invocation.MyCommand.Path)
{
Split-Path $Invocation.MyCommand.Path
}
else
{
$Invocation.InvocationName.Substring(0,$Invocation.InvocationName.LastIndexOf("\"));
}
}
Essayez:
(Get-Location).path
ou:
($pwd).path
Get-Location
renverra l'emplacement actuel:
$Currentlocation=Get-Location
J'aime la solution one line :)
$scriptDir = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent
Essaye ça:
$WorkingDir = Convert-Path .
Dans Powershell 3 et supérieur, vous pouvez simplement utiliser
$PSScriptRoot
Vous penseriez que l'utilisation de '. \' Comme chemin signifie qu'il s'agit du chemin d'appel. Mais pas tout le temps. Exemple, si vous l'utilisez dans un travail ScriptBlock. Dans ce cas, il pourrait pointer sur% profile%\Documents.
Pour ce qui vaut la peine d’être une seule ligne de solution, voici une solution qui fonctionne pour moi.
$currFolderName = (Get-Location).Path.Substring((Get-Location).Path.LastIndexOf("\")+1)
le 1 à la fin est d'ignorer le /.
grâce aux publications ci-dessus à l'aide de la cmdlet Get-Location
Pour développer la réponse de @Cradle: vous pouvez également écrire une fonction multi-purpose qui vous donnera le même résultat, comme le dit la question du PO:
Function Get-AbsolutePath {
[CmdletBinding()]
Param(
[parameter(
Mandatory=$false,
ValueFromPipeline=$true
)]
[String]$relativePath=".\"
)
if (Test-Path -Path $relativePath) {
return (Get-Item -Path $relativePath).FullName -replace "\\$", ""
} else {
Write-Error -Message "'$relativePath' is not a valid path" -ErrorId 1 -ErrorAction Stop
}
}