Siempre que necesito hacer referencia a un módulo o script común, me gusta usar rutas relativas al archivo de script actual. De esa manera, mi script siempre puede encontrar otros scripts en la biblioteca.
Entonces, ¿cuál es la mejor forma estándar de determinar el directorio del script actual? Actualmente estoy haciendo:
$MyDir = [System.IO.Path]::GetDirectoryName($myInvocation.MyCommand.Definition)
Sé que en los módulos (.psm1) puede usar $PSScriptRoot
para obtener esta información, pero eso no se configura en scripts normales (es decir, archivos .ps1).
¿Cuál es la forma canónica de obtener la ubicación actual del archivo de script de PowerShell?
powershell
powershell-2.0
Aaron Jensen
fuente
fuente
Respuestas:
PowerShell 3+
PowerShell 2
Antes de PowerShell 3, no había una mejor manera que consultar la
MyInvocation.MyCommand.Definition
propiedad en busca de scripts generales. Tenía la siguiente línea en la parte superior de esencialmente cada script de PowerShell que tenía:fuente
Split-Path
sirve aquí?Split-Path
se usa con el-Parent
parámetro para devolver el directorio actual sin el nombre del script que se está ejecutando actualmente.$PSScriptRoot
es (Split-Path -Parent
aplicada a)$MyInvocation.MyCommand.Path
, no$MyInvocation.MyCommand.Definition
, aunque en el ámbito de nivel superior de un script se comportan igual (que es el único lugar sensible desde el que llamar para este propósito). Cuando se llama dentro de una función o bloque de script , el primero devuelve la cadena vacía, mientras que el segundo devuelve la definición del bloque de función / script del cuerpo de la función como una cadena (una parte del código fuente de PowerShell).Si está creando un módulo V2, puede usar una variable automática llamada
$PSScriptRoot
.Desde PS> Ayuda automatic_variable
fuente
$PSCommandPath Contains the full path and file name of the script that is being run. This variable is valid in all scripts.
Para PowerShell 3.0
La función es entonces:
fuente
Para PowerShell 3+
He puesto esta función en mi perfil. Funciona en ISE usando F8/ Ejecutar selección también.
fuente
Tal vez me falta algo aquí ... pero si quieres el directorio de trabajo actual, puedes usar esto:
(Get-Location).Path
para una cadena oGet-Location
para un objeto.A menos que se refiera a algo como esto, lo entiendo después de leer la pregunta nuevamente.
fuente
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
Guarde eso y ejecútelo desde un directorio diferente. Mostrará la ruta al guión.Muy similar a las respuestas ya publicadas, pero las tuberías parecen más como PowerShell:
fuente
Yo uso la variable automática
$ExecutionContext
. Funcionará desde PowerShell 2 y versiones posteriores.fuente
Me llevó un tiempo desarrollar algo que tomara la respuesta aceptada y la convirtiera en una función robusta.
No estoy seguro acerca de los demás, pero trabajo en un entorno con máquinas en PowerShell versión 2 y 3, por lo que necesitaba manejar ambos. La siguiente función ofrece un retroceso elegante:
También significa que la función se refiere al alcance del Script en lugar del alcance de los padres como lo describe Michael Sorens en una de sus publicaciones de blog .
fuente
Necesitaba saber el nombre del script y desde dónde se está ejecutando.
El prefijo "$ global:" a la estructura MyInvocation devuelve la ruta completa y el nombre del script cuando se llama desde el script principal y la línea principal de un archivo de biblioteca .PSM1 importado. También funciona desde una función en una biblioteca importada.
Después de mucho jugar, decidí usar $ global: MyInvocation.InvocationName. Funciona de manera confiable con el lanzamiento de CMD, Run With Powershell e ISE. Tanto los lanzamientos locales como UNC devuelven la ruta correcta.
fuente
ParameterArgumentValidationErrorNullNotAllowed
excepción.Siempre uso este pequeño fragmento que funciona para PowerShell e ISE de la misma manera:
fuente
Descubrí que las soluciones más antiguas publicadas aquí no me funcionaron en PowerShell V5. Se me ocurrió esto:
fuente
También puede considerar
split-path -parent $psISE.CurrentFile.Fullpath
si alguno de los otros métodos falla. En particular, si ejecuta un archivo para cargar un montón de funciones y luego ejecuta esas funciones dentro del shell ISE (o si seleccionó la ejecución), parece que laGet-Script-Directory
función como la anterior no funciona.fuente
$PSCommandPath
funcionará en el ISE siempre que guarde primero el script y ejecute todo el archivo. De lo contrario, en realidad no estás ejecutando un script; solo estás "pegando" comandos en el shell.Utilizando las piezas de todas estas respuestas y los comentarios, preparé esto para cualquiera que vea esta pregunta en el futuro. Cubre todas las situaciones enumeradas en las otras respuestas.
fuente
fuente