Actualización de la compatibilidad de PowerShell Core con Windows
Pensé en compartir una actualización rápida sobre mis experiencias al vivir en un mundo PowerShell Core. Una de las cosas en las que Microsoft está trabajando para facilitar esto es una forma de acceder a los módulos de Windows PowerShell que funcionarán en PowerShell Core. Lo hace a través de comandos en el módulo de compatibilidad de Windows. Sin embargo, me encontré con una molestia que quizás también veas y que pensé que debería compartir, junto con mi solución.
Comportamiento esperado
PowerShell Core se comporta prácticamente igual que en Windows PowerShell. En un sistema Windows, puede asignar un nuevo PSDrive y, si usa una letra, PowerShell define automáticamente una función simple que facilita el cambio a esa ruta.
Puedo crear un nuevo PSDrive y cambiarlo sin errores. Ahora importaré el módulo de compatibilidad de Windows.
Comportamiento problemático
Una de las formas en que funciona el módulo es proporcionar acceso a los comandos de Windows PowerShell a través de una sesión de compatibilidad remota. Puede que no siempre quede claro cuándo se crea dicha sesión, aunque puede crearla intencionalmente con Initialize-WinSession.
Estoy seguro de que la expectativa es que los comandos utilicen esta sesión de forma transparente. Pero hay un pequeño problema. Mira lo que sucede cuando intento cambiar a la unidad S: ahora.
PowerShell se queja pero en realidad cambia de ubicación. Al investigar el error, descubrí que el comando Set-Location se estaba ejecutando a través de la sesión de WinCompatibility, que no sabe nada sobre la unidad S:.
Descubrí que si creo la unidad en la sesión, el molesto error se resuelve.
Una solución programada
Con esto en mente, se me ocurrió una solución programada. Parte de mi perfil de PowerShell es crear varios accesos directos de PSDrive. Una vez que estén definidos, sigo adelante e importo WindowsCompatibilityModule.
Import-Module WindowsCompatibility
Add-WindowsPSModulePath
Initialize-WinSession
Sé que necesitaré la sesión de WinCompat. Luego llamo a esta función.
#requires -version 6.1
#requires -module WindowsCompatibility
Function Update-WinCompatibiltySession {
[cmdletbinding(SupportsShouldProcess)]
[alias("uwc")]
Param([switch]$Passthru)
Try {
$s = Get-PSSession -name "wincompat-localhost-$env:username" -ErrorAction Stop
$local = Get-PSDrive
foreach ($psdrive in $local) {
if ($PSCmdlet.ShouldProcess($pdrive.name, "Adding")) {
Invoke-Command {
Try {
Get-PSDrive -Name $using:psdrive.name -ErrorAction Stop | Out-Null
}
Catch {
$newParams = @{
name = $using:psdrive.name
PSProvider = $using:psdrive.provider
Root = $using:psdrive.root
}
#mapping the drive using the credential. This may not be necessary.
if ($using:psdrive.credential.username) {
$newParams.Add("Credential", $using:psdrive.credential)
}
$new = New-PSDrive @newParams
if ($using:Passthru) {
$new
}
}
} -session $s
}
} #Whatif
}
Catch {
Write-Warning "Did not detect a WinCompat remoting session. You might need to run Initialize-WinSession."
}
}
La función obtiene todos los PSDrive de mi sesión local y los agrega a la sesión remota si aún no existe. Y sí, me doy cuenta de que hay varias maneras en que podría haberlo logrado. Pero ahora mis errores han desaparecido.
Si agrego otra unidad más tarde, necesito volver a ejecutar la función.
Tengo un problema abierto sobre esto en GitHub, pero por ahora, este arreglo parece solucionar el problema.