Sempre que preciso fazer referência a um módulo ou script comum, gosto de usar caminhos relativos ao arquivo de script atual. Dessa forma, meu script sempre pode encontrar outros scripts na biblioteca.
Então, qual é a melhor maneira padrão de determinar o diretório do script atual? Atualmente, estou fazendo:
$MyDir = [System.IO.Path]::GetDirectoryName($myInvocation.MyCommand.Definition)
Eu sei nos módulos (.psm1) que você pode usar $PSScriptRoot
para obter essas informações, mas isso não é definido em scripts regulares (arquivos .ps1).
Qual é a maneira canônica de obter a localização atual do arquivo de script do PowerShell?
powershell
powershell-2.0
Aaron Jensen
fonte
fonte
Respostas:
PowerShell 3+
PowerShell 2
Antes do PowerShell 3, não havia uma maneira melhor do que consultar a
MyInvocation.MyCommand.Definition
propriedade para obter scripts gerais. Eu tinha a seguinte linha no topo de todos os scripts do PowerShell que eu tinha:fonte
Split-Path
usado aqui?Split-Path
é usado com o-Parent
parâmetro para retornar o diretório atual sem o nome do script atualmente em execução.$PSScriptRoot
-Split-Path -Parent
aplicada ( aplicada a)$MyInvocation.MyCommand.Path
, não$MyInvocation.MyCommand.Definition
, embora no escopo de nível superior de um script eles se comportem da mesma forma (que é o único local sensato para chamar para esse fim). Quando chamado dentro de uma função ou bloco de script , o primeiro retorna a string vazia, enquanto o último retorna a definição do corpo da função / bloco de script como uma string (uma parte do código-fonte do PowerShell).Se você estiver criando um módulo V2, poderá usar uma variável automática chamada
$PSScriptRoot
.No PS> Ajuda automatic_variable
fonte
$PSCommandPath Contains the full path and file name of the script that is being run. This variable is valid in all scripts.
Para o PowerShell 3.0
A função é então:
fonte
Para o PowerShell 3+
Eu coloquei essa função no meu perfil. Também funciona no ISE usando F8/ Run Selection.
fonte
Talvez esteja faltando alguma coisa aqui ... mas se você quiser o diretório de trabalho atual, você pode simplesmente usar isso:
(Get-Location).Path
para uma string ouGet-Location
para um objeto.A menos que você esteja se referindo a algo assim, o que eu entendo depois de ler a pergunta novamente.
fonte
function Get-Script-Directory { $scriptInvocation = (Get-Variable MyInvocation -Scope 1).Value return Split-Path $scriptInvocation.MyCommand.Path } $hello = "hello" Write-Host (Get-Script-Directory) Write-Host $hello
Salve isso e execute-o em um diretório diferente. Você mostrará o caminho para o script.Muito semelhante às respostas já postadas, mas a tubulação parece mais com o PowerShell:
fonte
Eu uso a variável automática
$ExecutionContext
. Ele funcionará no PowerShell 2 e posterior.fonte
Demorei um pouco para desenvolver algo que pegou a resposta aceita e a transformou em uma função robusta.
Não tenho certeza sobre os outros, mas trabalho em um ambiente com máquinas no PowerShell versão 2 e 3, portanto, precisava lidar com ambos. A função a seguir oferece um fallback elegante:
Isso também significa que a função se refere ao escopo do Script em vez do escopo dos pais, conforme descrito por Michael Sorens em uma de suas postagens no blog .
fonte
Eu precisava saber o nome do script e de onde ele está sendo executado.
Prefixar "$ global:" à estrutura MyInvocation retorna o caminho completo e o nome do script quando chamado do script principal e da linha principal de um arquivo de biblioteca .PSM1 importado. Também funciona de dentro de uma função em uma biblioteca importada.
Depois de muita discussão, decidi usar o $ global: MyInvocation.InvocationName. Funciona de forma confiável com o lançamento do CMD, Run With Powershell e o ISE. Lançamentos locais e UNC retornam o caminho correto.
fonte
ParameterArgumentValidationErrorNullNotAllowed
exceção.Eu sempre uso esse pequeno trecho que funciona para o PowerShell e o ISE da mesma maneira:
fonte
Descobri que as soluções mais antigas postadas aqui não funcionavam para mim no PowerShell V5. Eu vim com isso:
fonte
Você também pode considerar
split-path -parent $psISE.CurrentFile.Fullpath
se algum dos outros métodos falhar. Em particular, se você executar um arquivo para carregar um monte de funções e depois executá-las dentro do shell do ISE (ou se você executar selecionado), parece que aGet-Script-Directory
função como acima não funciona.fonte
$PSCommandPath
funcionará no ISE contanto que você salve o script primeiro e execute o arquivo inteiro. Caso contrário, você não está realmente executando um script; você está apenas "colando" comandos no shell.Usando trechos de todas essas respostas e comentários, montei isso para todos que virem essa pergunta no futuro. Abrange todas as situações listadas nas outras respostas
fonte
fonte