Búsqueda de sitios web

Viernes divertido con un mensaje de PowerShell multiplataforma


Este año está resultando ser multiplataforma para mí. Continuando con esta línea de discusión hoy tengo algo divertido y sencillo. Una función de aviso de PowerShell que funcionará en varias plataformas y proporcionará información significativa de una manera que creo que es elegante. Quizás no necesites la función, pero quizás quieras ver cómo creo una función de PowerShell que tiene en cuenta la compatibilidad multiplataforma.

La meta

El objetivo del diseño era crear un mensaje que mostrara el nombre de usuario y la ubicación actual en un cuadro de color. El color de la línea del cuadro indicaría si el usuario estaba ejecutando una sesión elevada de PowerShell. El mensaje luego mostrará la fecha y hora actuales y la versión de PowerShell. Pero realmente deberías pensar en la función como una prueba de concepto o una plantilla. Puede sustituir cualquier información que sea relevante para usted. Sin embargo, debes tener en cuenta la compatibilidad multiplataforma.

Desarrollar una función multiplataforma

Sabía que quería mostrar el nombre de usuario actual como parte del mensaje. Hay varias técnicas que podrías utilizar. Decidí probar si $env:Username está definido. Esta variable NO está definida en plataformas que no sean Windows. En Linux, debería haber una variable ambiental LOGNAME. Si por alguna razón no puedo encontrar ninguno de estos valores, usaré un valor predeterminado de último recurso.

if ($env:userdomain -AND $env:username) {
        $me = "$($env:userdomain)\$($env:username)"
    }
elseif ($env:LOGNAME) {
        $me = $env:LOGNAME
    }
else {
        $me = "PSUser"
    }

Debo señalar que mis pruebas en Linux han sido limitadas y no he probado nada en una Mac porque no tengo acceso a una. Utilizo este valor en el texto que pretendo mostrar dentro de un cuadro.

$text = "[$me] $($executionContext.SessionState.Path.CurrentLocation)"

Podría agregar información adicional en esta cadena de texto. Estoy agregando la ubicación actual. Puedes agregar el nombre de host, una dirección IP, espacio libre o lo que necesites. Tenga en cuenta que debe escribir código para derivar los valores según la versión de PowerShell y la plataforma.

Por ejemplo, si el usuario (yo) está ejecutando una sesión elevada de PowerShell, quiero que el color del cuadro sea rojo. De lo contrario debería ser verde. En plataformas Windows puedo usar la clase .NET System.Security.Principal.WindowsPrincipal. Sin embargo, esa clase no está disponible en PowerShell Core en plataformas que no sean Windows. Utilicé una construcción If/ElseIf/Else para probar algunas variables nuevas en PowerShell Core o Windows PowerShell.

if ($IsLinux) {
        if ($(id -g) -eq 0 ) {
            #running as SU
            $lineColor = "Red"
        }
        else {
            $lineColor = "Green"
        }
    }
    elseif ($isWindows -or $psEdition -eq 'desktop') {

        $IsAdmin = [System.Security.Principal.WindowsPrincipal]::new([System.Security.Principal.WindowsIdentity]::GetCurrent() ).IsInRole("Administrators")
        if ($IsAdmin) {
            $lineColor = "Red"
        }
        else {
            $lineColor = "Green"
        }
    }
    else {
        #for everything else not tested
        $lineColor = "Yellow"
    }

Observe que tengo una cláusula Else para manejar todas las demás situaciones. Dependiendo de su proyecto, es posible que desee generar una excepción. Pero como se trata de una función rápida, no quiero hacer eso.

La función de aviso de PowerShell

Puede encontrar la función completa en esencia en GitHub.

BoxPrompt.ps1:

#requires -version 5.1

<#
Create a lined box with user and location information. The line color will indicate if the user is running elevated.
The prompt will also display the current date and time and a PS prompt with the PowerShell version.

┌─────────────────────────┐
│ [BOVINE320\Jeff] D:\iso │
└─────────────────────────┘
[01/18/2019 09:30:53] PS v6.1.2>

This prompt should run cross platform, although Linux testing has been limited.

To use the prompt dot source the script file in your PowerShell profile script.

This may not display properly in the Visual Studio Code PowerShell integrated console
#>

Function prompt {

    if ($env:userdomain -AND $env:username) {
        $me = "$($env:userdomain)\$($env:username)"
    }
    elseif ($env:LOGNAME) {
        $me = $env:LOGNAME
    }
    else {
        $me = "PSUser"
    }
    $text = "[$me] $($executionContext.SessionState.Path.CurrentLocation)"

    if ($IsLinux) {
        if ($(id -g) -eq 0 ) {
            #running as SU
            $lineColor = "Red"
        }
        else {
            $lineColor = "Green"
        }
    }
    elseif ($isWindows -or $psEdition -eq 'desktop') {

        $IsAdmin = [System.Security.Principal.WindowsPrincipal]::new([System.Security.Principal.WindowsIdentity]::GetCurrent() ).IsInRole("Administrators")
        if ($IsAdmin) {
            $lineColor = "Red"
        }
        else {
            $lineColor = "Green"
        }
    }
    else {
        #for everything else not tested
        $lineColor = "Yellow"
    }

    $top = "┌$(("─" * $($text.length+2)))┐"
    Write-Host $top -ForegroundColor $lineColor
    Write-Host "│ " -ForegroundColor $lineColor -NoNewline
    Write-Host $text -NoNewline
    Write-Host " │" -ForegroundColor $lineColor
    $bottom = "└$(("─" * $($text.length+2)))┘"
    Write-Host $bottom -ForegroundColor $lineColor

    #parse out the PSVersionTable to most meaningful values
    $ver = $(([regex]"\d+\.\d+.\d+").match($psversiontable.psversion).value)

    Write-Host "[$(Get-Date)]" -ForegroundColor Yellow -NoNewline
    #the prompt function needs to write something to the pipeline
    " PS v$ver$('>' * ($nestedPromptLevel + 1)) "

}

Al igual que otras funciones de solicitud de PowerShell, es necesario crear un punto de origen del script.

. C:\scripts\boxprompt.ps1

Si desea utilizar esto todo el tiempo, coloque esta línea en la secuencia de comandos de su perfil de PowerShell.

A continuación se muestra un ejemplo del mensaje en una variedad de sesiones de PowerShell.

El resultado final es que tengo una función de solicitud de PowerShell simple que proporciona un poco más de información y se ejecuta en cualquier instancia de PowerShell. Y hay espacio para crecer porque puedo agregar otra información a la cadena de texto del cuadro si es necesario.

Espero que le des una vuelta a esto y me dejes saber lo que piensas. Ten un excelente fin de semana.

Artículos relacionados