Friday Fun: una consola PowerShell aleatoria
#requires -version 3.0
Function Set-RandomConsole {
<#
.Synopsis
Set the console foreground and background colors to random values.
.Description
This command will create a random foreground/background color combination for your PowerShell console. Use -Reset to restore settings to the first time you ran the command.
The command only works properly in the PowerShell console, NOT the PowerShell ISE.
.Parameter Reset
Reset console colors to original settings using the values in global variables $savedfg and $savedbg. You must run the command at least once to populate these variables.
.Example
PS C:\> set-randomconsole
Change console colors to a random setting. If this is the first time the command is run, current settings will be saved to global variables $savedfg and $savedbg.
.Example
PS C:\> set-randomconsole -reset
Console colors will be restored to original settings using the values in global variables $savedfg and $savedbg.
.Notes
Last Updated: July 8, 2014
Version : 0.9
****************************************************************
* DO NOT USE IN A PRODUCTION ENVIRONMENT UNTIL YOU HAVE TESTED *
* THOROUGHLY IN A LAB ENVIRONMENT. USE AT YOUR OWN RISK. IF *
* YOU DO NOT UNDERSTAND WHAT THIS SCRIPT DOES OR HOW IT WORKS, *
* DO NOT USE IT OUTSIDE OF A SECURE, TEST SETTING. *
****************************************************************
.Inputs
NONE
.Outputs
NONE
#>
[cmdletbinding(SupportsShouldProcess)]
Param(
[switch]$Reset
)
Write-Verbose "Starting $($MyInvocation.Mycommand)"
#Skip if running in the PowerShell ISE
if ($host.Name -match "ISE") {
Write-Warning "This command only works in the PowerShell console."
#bail out
Return
}
#Save current colors if not already saved
if (-Not $global:savedbg) {
#saved to a global variable
Write-Verbose "Saving current background"
$global:savedbg = $host.ui.RawUI.backgroundColor
}
if (-Not $global:savedfg) {
#saved to a global variable
Write-Verbose "Saving current foreground"
$global:savedfg = $host.ui.RawUI.ForegroundColor
}
if ($reset) {
Write-Verbose "Resetting console"
$bg = $global:savedbg
$fg = $global:savedfg
}
else {
Write-Verbose "Generating random colors"
#set background to a random color
$bg = Get-Random ([enum]::GetNames([consolecolor]))
#set foreground to a random color other than what is set as foreground
$fg = Get-Random ([enum]::GetNames([consolecolor])) | Where {$_ -ne $bg}
}
Try {
Write-Verbose "Applying colors"
Write-Verbose "Background = $bg"
Write-Verbose "Foreground = $fg"
#my code for -WhatiIf
$msg = "Background = $bg / Foreground = $fg"
if ($PSCmdlet.ShouldProcess( $msg )) {
$host.ui.rawui.backgroundcolor= $bg
$host.ui.rawui.foregroundcolor = $fg
#clear the host to apply the settings
#comment this out if trying to trace using the verbose output
Clear-Host
} #whatif
}
Catch {
Write-Warning "Failed to set console colors. Most likely you tried to reset without first changing anything."
}
Write-Verbose "Ending $($MyInvocation.Mycommand)"
} #end function
#define an optional alias
Set-Alias -Name src -Value Set-RandomConsoleLa función no funcionará correctamente en PowerShell ISE, por lo que incluí un código al principio para ver si se está ejecutando en ISE. Si es así, el comando muestra una advertencia y se retira. Este es un escenario en el que usar Return es completamente aceptable ya que quiero salir del proceso sin hacer nada. Podría haber usado un comando como este: Devolver "Este comando solo funciona en la consola PowerShell". pero eso habría escrito un objeto de cadena en la tubería y no quiero que nada vaya a la tubería. Además, prefiero usar Write-Warning para mensajes como este.
Cuando ejecuta el comando, prueba la existencia de algunas variables, $savedfg y $savedbg, que están definidas en el ámbito global. Notarás el uso del prefijo global:. Si no están definidas, entonces se supone que esta es la primera vez que se ejecuta el comando y las variables se definirán con los valores actuales de $host.ui.rawui.foregroundcolor y $host.ui.rawui.backgroundcolor. valores. Más adelante, si usa -Reset, el comando usará estos valores para restaurar su configuración original.
De lo contrario, el comando obtiene un color aleatorio para la enumeración System.ConsoleColor para el fondo y luego otro color aleatorio para el primer plano, que es diferente al color de fondo seleccionado aleatoriamente.
Cuando mires el código, verás que estoy especificando en el atributo cmdletbinding que la función admite ShouldProcess. Eso también podría escribirse [cmdletbinding(SupportsShouldProcess=$True)] pero me parece redundante. De todos modos, el comando para realizar el cambio, $host.ui.rawui.backgroundcolor= $bg, por sí solo no sabe nada sobre ShouldProcess y -WhatIf. Pero puedo agregar mi propio código usando una declaración If.
$msg = "Background = $bg / Foreground = $fg"
if ($PSCmdlet.ShouldProcess( $msg )) {
$host.ui.rawui.backgroundcolor= $bg
$host.ui.rawui.foregroundcolor = $fg
#clear the host to apply the settings
#comment this out if trying to trace using the verbose output
Clear-Host
} #whatif
El valor del método ShouldProcess() es el texto que ve como parte del mensaje "...realizando operación en el objetivo...". El texto es el objetivo.
Todo lo que hice fue definir una variable, $msg, para que la línea de código sea más fácil de leer. Como puedes ver, no es tan difícil agregar tu propio soporte para -WhatIf. Y ahora, si te aburres un poco, mézclalo para obtener una nueva perspectiva. Incluso he incluido un alias, src, en caso de que tengas que escribir en una consola donde no puedes ver lo que estás escribiendo.
Que tengas un estupendo fin de semana.

