J'ai un script PowerShell qui effectue certaines tâches en utilisant le répertoire actuel du script. Ainsi, lorsque vous vous trouvez dans ce répertoire, exécuter .\script.ps1
fonctionne correctement.
Maintenant, je veux appeler ce script depuis un autre répertoire sans changer le répertoire de référence du script. Donc, je veux appeler ..\..\dir\script.ps1
et je veux toujours que ce script se comporte comme il a été appelé depuis son répertoire.
Comment puis-je le faire ou comment modifier un script pour qu'il puisse être exécuté à partir de n'importe quel répertoire?
Voulez-vous dire que vous voulez le propre chemin du script afin que vous puissiez référencer un fichier à côté du script? Essaye ça:
$scriptpath = $MyInvocation.MyCommand.Path
$dir = Split-Path $scriptpath
Write-Host "My directory is $dir"
Vous pouvez obtenir beaucoup d’informations sur $ MyInvocation et ses propriétés.
Si vous souhaitez référencer un fichier dans le répertoire de travail en cours, vous pouvez utiliser Resolve-Path ou Get-ChildItem:
$filepath = Resolve-Path "somefile.txt"
EDIT (basé sur le commentaire de l'OP):
# temporarily change to the correct folder
Push-Location $folder
# do stuff, call ant, etc
# now back to previous directory
Pop-Location
Il y a probablement d'autres moyens de réaliser quelque chose de similaire en utilisant Invoke-Command.
Si vous appelez des applications natives, vous devez vous soucier de [Environment]::CurrentDirectory
et non du répertoire actuel de PowerShell $PWD
. Pour diverses raisons, PowerShell ne définit pas le répertoire de travail actuel du processus lors de la définition de l'emplacement ou de l'emplacement de transfert. Vous devez donc vous assurer de le faire si vous exécutez des applications (ou des cmdlets) qui supposent qu'il soit défini.
Dans un script, vous pouvez faire ceci:
$CWD = [Environment]::CurrentDirectory
Push-Location $MyInvocation.MyCommand.Path
[Environment]::CurrentDirectory = $PWD
## Your script code calling a native executable
Pop-Location
# Consider whether you really want to set it back:
# What if another runspace has set it in-between calls?
[Environment]::CurrentDirectory = $CWD
Il n'y a pas d'alternative infaillible à cela. Beaucoup d'entre nous ont mis une ligne dans notre fonction Invite pour définir [Environment] :: CurrentDirectory ... mais cela ne vous aide pas lorsque vous modifiez l'emplacement à l'intérieur un script.
Deux remarques sur la raison pour laquelle cela n'est pas défini automatiquement par PowerShell:
$PWD
, mais il n'y a qu'un seul processus et un seul environnement.$PWD
n'est pas toujours un CurrentDirectory légal (vous pouvez par exemple insérer un CD dans le fournisseur de registre).Si vous souhaitez le placer dans votre invite (qui ne s'exécutera que dans l'espace d'exécution principal, à thread unique), vous devez utiliser:
[Environment]::CurrentDirectory = Get-Location -PSProvider FileSystem
Il y a des réponses avec un grand nombre de votes, mais quand j'ai lu votre question, je pensais que vous vouliez connaître le répertoire dans lequel se trouve le script, et non celui où il est exécuté. Vous pouvez obtenir les informations avec les variables automatiques de PowerShell
$PSScriptRoot - the directory where the script exists, not the target directory the script is running in
$PSCommandPath - the full path of the script
Par exemple, j'ai le script $ profile qui trouve le fichier solution Visual Studio et le démarre. Je voulais stocker le chemin complet une fois qu'un fichier de solution est démarré. Mais je voulais enregistrer le fichier où le script original existe. J'ai donc utilisé $ PsScriptRoot.
J'ai souvent utilisé le code suivant pour importer un module situé dans le même répertoire que le script en cours d'exécution. Il obtiendra d’abord le répertoire à partir duquel Powershell est lancé
$ currentPath = Split-Path ((Get-Variable MonInvocation -Scope 0) .Value) .MyCommand.Path
module d'importation "$ currentPath\sqlps.ps1"
Cela fonctionnerait bien.
Push-Location $PSScriptRoot
Write-Host CurrentDirectory $CurDir
Eh bien, je cherchais une solution pour cela pendant un moment, sans aucun script en provenance de CLI. Voici comment je le fais xD:
Naviguez jusqu'au dossier à partir duquel vous voulez exécuter le script (l'important est que vous ayez terminé les onglets)
..\..\dir
Maintenant, entourez location de guillemets doubles, et à l'intérieur, ajoutez cd
afin de pouvoir appeler une autre instance de powershell.
"cd ..\..\dir"
Ajouter une autre commande pour exécuter le script séparé par ;
, avec un séparateur de commande dans Powershell
"cd ..\..\dir\; script.ps1"
Enfin, lancez-le avec une autre instance de powershell
start powershell "cd..\..\dir\; script.ps1"
Cela ouvrira une nouvelle fenêtre Powershell, allez à ..\..\dir
, exécutez script.ps1
et fermez la fenêtre.
Notez que ";" Séparez simplement les commandes, comme si vous les tapiez une par une, si la première échoue, la seconde sera exécutée, puis après, et ensuite après ... Si vous voulez garder la nouvelle fenêtre powershell ouverte, ajoutez -noexit dans la commande passée. Notez que je navigue d’abord dans le dossier souhaité pour pouvoir utiliser les complétions d’onglet (vous ne pouviez pas utiliser de guillemets).
start powershell "-noexit cd..\..\dir\; script.ps1"
Utilisez des guillemets doubles ""
pour pouvoir passer des répertoires avec des espaces dans les noms, par exemple,
start powershell "-noexit cd '..\..\my dir'; script.ps1"