Vigilar las acciones de una secuencia de comandos es fundamental para la supervisión y la depuración. Un script se puede monitorear de muchas maneras diferentes, pero generalmente depende de cómo se vaya a ejecutar. Si un script se invoca interactivamente, es decir, directamente desde la consola por medio de técnicas como Write-Verbose, Write-Information o Write-Host, es útil porque cada comando es capaz de mostrar mensajes mientras se ejecuta el script. Pero, ¿qué ocurre si una secuencia de comandos está siendo invocada por una tarea programada o algún otro proceso que no implique un ser humano pegado a una pantalla mientras se ejecuta? En este caso, necesitaremos incorporar otro nivel de monitoreo. Una manera excelente de supervisar un script que no se ejecuta de forma interactiva es usando un archivo de registro o log file.
Ciérrele la puerta a los intrusos indeseados de forma gratuita. Obtenga WhatsUp PortScanner GRATIS.
Hay maneras diversas de escribir texto en un archivo de texto en PowerShell, y el método utilizado depende completamente de la persona que escribe los scripts. Sin embargo, antes de que aprenda a crear su propia función de registro, hay algunas cosas que debe tener en cuenta.
- Todas las líneas de registro deben ser contenido estructurado. No se pueden tener mensajes de texto sueltos por doquier.
- El tiempo debe ser registrado para cada entrada de registro.
- Se recomienda establecer prioridades u otras "etiquetas" para rápidamente filtrar la información en el archivo.
Veamos cómo podemos construir una función de PowerShell para poder incorporarla en cualquiera de nuestros scripts. Debido a que esta función deberá estar disponible para varios scripts diferentes, crearemos un script de PS1 para almacenar nuestra función. El nombre de la función será Write-Log.
Write-Log.ps1
function Write-Log {
[CmdletBinding()]
param()
}
Lea: Usando Los Servicios De Windows En Powershell
La función de registro escribirá una sola línea de registro cada vez que sea llamada. Cada línea en el registro tendrá dos atributos que cambiarán según lo que quiera registrar; mensajes (message) y gravedad (severity), así que los agregaré como parámetros a nuestra función.
function Write-Log {
[CmdletBinding()]
param(
[Parameter()]
[ValidateNotNullOrEmpty()]
[string]$Message,
[Parameter()]
[ValidateNotNullOrEmpty()]
[ValidateSet('Information','Warning','Error')]
[string]$Severity = 'Information'
)
}
Fíjese que he elegido limitar el parámetro Severity a tres opciones. Al limitar las opciones, podremos confiar en que este campo siempre estará en una de las tres. Una vez que tenga los parámetros construidos, usaré CSV para crear un archivo de registro estructurado. Esto asegurará que pueda extraer rápidamente el archivo de registro en un programa de hoja de cálculo y revisar los datos, si es necesario. Observe que también he agregado el tiempo. Este no es un parámetro porque siempre nos mostrara el momento en que se ejecutó la función.
function Write-Log {
[CmdletBinding()]
param(
[Parameter()]
[ValidateNotNullOrEmpty()]
[string]$Message,
[Parameter()]
[ValidateNotNullOrEmpty()]
[ValidateSet('Information','Warning','Error')]
[string]$Severity = 'Information'
)
[pscustomobject]@{
Time = (Get-Date -f g)
Message = $Message
Severity = $Severity
} | Export-Csv -Path "$env:Temp\LogFile.csv" -Append -NoTypeInformation
}
Eso es todo lo que hay que hacerle a la función Write-Log. Ahora podemos agregar la función a cualquier script que queramos, siempre y cuando lo implementemos con dot-source. Si el script Write-Log.ps1 estaba en la misma carpeta que el script que llamamos; podríamos realizar el dot-source de esta manera:
Script.ps1
. "$PSScriptRoot\Write-Log.ps1
Una vez que el script conozca la función, puede llamarla tantas veces como lo requiera.
$foo = $false
if ($foo) {
Write-Log -Message 'Foo was $true' -Severity Information
} else {
Write-Log -Message 'Foo was $false' -Severity Error
}
La información luego será registrada en el archivo de registro que se verá así:
PS> Import-Csv "$env:Temp\LogFile.csv"
Time Message Severity
---- ------- --------
5/13/2017 2:19 PM Foo was $false Error