batch-file powershell cmd unc

batch file - La ejecución de Get-ChildItem en la ruta UNC funciona en Powershell pero no en Powershell en un archivo por lotes



batch-file cmd (3)

He encontrado este problema al ejecutar scripts que hacen referencia a las rutas UNC, pero el error solo ocurre cuando la raíz del script se establece en una ubicación que no es del sistema de archivos. por ejemplo, PS SQLSEVER /

Entonces, lo siguiente falla con el mismo error:

cd env: $foo = @{Name = "Foo"} $foo.Path = "//remote-server/foothing" $bar = @{Name = "Bar"} $bar.Path = "//remote-server/barthing" @( $foo, $bar ) | ForEach-Object { $item = Get-ChildItem $_.Path # Do things with item Write-Host $item }

Así que mi resolución fue asegurar que el indicador de PS se devolviera a una ubicación del sistema de archivos antes de ejecutar este código. p.ej

cd env: $foo = @{Name = "Foo"} $foo.Path = "//remote-server/foothing" $bar = @{Name = "Bar"} $bar.Path = "//remote-server/barthing" cd c: #THIS IS THE CRITICAL LINE @( $foo, $bar ) | ForEach-Object { $item = Get-ChildItem $_.Path # Do things with item Write-Host $item }

Espero que esto ayude, estaría muy contento con la recompensa, ya que esta es mi primera respuesta al desbordamiento de pila. PD: Olvidé agregar: la raíz del mensaje de comando del PS puede configurarse mediante módulos cargados automáticamente en la configuración de su máquina. Verificaría con Get-Location para ver si realmente está ejecutando desde una ubicación que no es FileSystem.

Estoy escribiendo un archivo de proceso por lotes que ejecuta un script de Powershell que en un momento enlaza elementos con rutas UNC como atributos y usa Get-ChildItem en esas rutas. En una versión mínima, esto es lo que está sucediendo en mis scripts:

Master.bat

powershell -ExecutionPolicy ByPass -File "Slave.ps1"

Slave.ps1

$foo = @{Name = "Foo"} $foo.Path = "//remote-server/foothing" $bar = @{Name = "Bar"} $bar.Path = "//remote-server/barthing" @( $foo, $bar ) | ForEach-Object { $item = Get-ChildItem $_.Path # Do things with item }

El problema que me encuentro es que cuando ejecuto Master.bat , falla en Get-ChildItem con un error en la línea de

get-childitem : Cannot find path ''//remote-server/foothing'' because it does not exist.

Sin embargo, parece funcionar perfectamente bien si ejecuto el archivo Slave.ps1 directamente usando Powershell. ¿Por qué podría estar pasando esto solo cuando se ejecuta el archivo Master.bat ?

Cosas que he intentado

  • Anteponer las rutas UNC con FileSystem:: con proveedores http://powershell.org/wp/2014/02/20/powershell-gotcha-unc-paths-and-providers/
  • Asegurándose de que no haya caracteres extraños en los caminos reales
  • Usar el parámetro -literalPath lugar del parámetro plain -path para Get-ChildItem
  • Ejecución de Get-ChildItem //remote-server/foothing en PowerShell y sucesión para verificar la conexión con el servidor remoto

Leí en otro lado sobre los comandos Push-Location y Pop-Location para contrarrestar este tipo de problema. Aterricé sobre tu pregunta mientras, de forma manual, paso a paso, probaba una nueva rutina donde el script tenía push / pop, pero lo olvidé para hacerlos en mi ventana PS. Después de verificar la respuesta de @Rory noté que estaba en PS SQLServer: / en vez de PS C: / prompt.

Entonces, una forma de usar esto en su script "esclavo" sería:

$foo = @{Name = "Foo"} $foo.Path = "//remote-server/foothing" $bar = @{Name = "Bar"} $bar.Path = "//remote-server/barthing" @( $foo, $bar ) | ForEach-Object { $item = Get-ChildItem $_.Path Push-Location # Do things with item Pop-Location }

Se pensó en agregar el Push / Pop antes y después del # Do things porque parece que son esas cosas las que cambian la ubicación.


La respuesta de Rory proporciona una solución efectiva, pero hay una solución que no requiere cambiar primero la ubicación actual a una ubicación de proveedor de FileSystem :

Prefijo sus rutas de acceso UNC con FileSystem:: para garantizar que se reconozcan correctamente, independientemente de la ubicación actual:

$foo = @{Name = "Foo"} $foo.Path = "FileSystem:://remote-server/foothing" $bar = @{Name = "Bar"} $bar.Path = "FileSystem:://remote-server/barthing"

Información de fondo opcional

Esta excelente publicación de blog explica el problema subyacente (énfasis agregado):

PowerShell no reconoce [rutas UNC] como "rooteadas" porque no están en un PSDrive; como tal, cualquier proveedor asociado con la ubicación actual de PowerShell tratará de manejarlos .

Agregar prefijo FileSystem:: identifica inequívocamente la ruta como una ruta de proveedor de FileSystem, independientemente del proveedor subyacente a la ubicación actual.