¿Cuál es la mejor manera de determinar la ubicación del script actual de PowerShell?
powershell-v2.0 (11)
Me tomó un tiempo desarrollar algo que tomó la respuesta aceptada y lo convirtió en una función robusta.
No estoy seguro de los demás, pero trabajo en un entorno con máquinas tanto en PowerShell versión 2 y 3, por lo que necesitaba manejar ambas. La siguiente función ofrece un respaldo elegante:
Function Get-PSScriptRoot
{
$ScriptRoot = ""
Try
{
$ScriptRoot = Get-Variable -Name PSScriptRoot -ValueOnly -ErrorAction Stop
}
Catch
{
$ScriptRoot = Split-Path $script:MyInvocation.MyCommand.Path
}
Write-Output $ScriptRoot
}
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 su blog
Cuando necesito hacer referencia a un módulo o script común, me gusta usar rutas relacionadas con el 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 comandos de PowerShell?
Muy similar a las respuestas ya publicadas, pero la tubería parece más parecida a una PS.
$PSCommandPath | Split-Path -Parent
Necesitaba saber el nombre del script y desde dónde se ejecuta.
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 dentro de una función en una biblioteca importada.
Después de mucho juguetear, decidí usar $ global: MyInvocation.InvocationName. Funciona de manera confiable con el lanzamiento de CMD, Run With Powershell y el ISE. Los lanzamientos locales y UNC devuelven la ruta correcta.
Para 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 función es entonces:
function Get-ScriptDirectory {
Split-Path -Parent $PSCommandPath
}
Para Powershell 3+
function Get-ScriptDirectory {
if ($psise) {Split-Path $psise.CurrentFile.FullPath}
else {$global:PSScriptRoot}
}
He puesto esta función en mi perfil. Funciona en ISE usando F8 / Ejecutar selección también.
Si está creando un Módulo V2, puede usar una variable automática llamada $PSScriptRoot
.
Desde PS> Ayuda 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.
Tal vez me esté faltando algo aquí ... pero si desea el directorio de trabajo actual, puede usar esto: (Get-Location).Path
para una cadena, o Get-Location
para un objeto.
A menos que te refieras a algo como esto, que entiendo después de leer la pregunta otra vez.
function Get-Script-Directory
{
$scriptInvocation = (Get-Variable MyInvocation -Scope 1).Value
return Split-Path $scriptInvocation.MyCommand.Path
}
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 grupo de funciones y luego ejecuta esas funciones con -en el shell ISE (o si ejecuta-seleccionado), parece que la función Get-Script-Directory
como la anterior no funciona.
Utilizo la variable automática $ ExecutionContext, funciona desde PowerShell 2 y versiones posteriores.
$ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath(''./')
$ ExecutionContext Contiene un objeto EngineIntrinsics que representa el contexto de ejecución del host de Windows PowerShell. Puede usar esta variable para encontrar los objetos de ejecución que están disponibles para los cmdlets.
PowerShell 3+
# This is an automatic variable set to the current file''s/module''s directory
$PSScriptRoot
PowerShell 2
Antes de PowerShell 3, no había una mejor manera de consultar la propiedad MyInvocation.MyCommand.Definition
para los scripts generales. Tenía la siguiente línea en la parte superior de cada script de powershell que tenía:
$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
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