Búsqueda de sitios web

Capturar mediante programación la salida detallada en una variable de PowerShell


El otro día estaba jugando con los cmdlets en el módulo DFSR y me di cuenta de que ninguno de ellos podía (hasta donde yo sabía) darme un recuento confiable del número de elementos en el Backlog de DFSR.

Mi plan era iniciar una replicación de dos carpetas y luego hacer que un script monitoreara el trabajo pendiente para generar mensajes de estado que me mantuvieran informado del progreso.

Busqué una manera de lograr esto mirando los comandos en el módulo DFSR que tienen el verbo Obtener

PS C:> Obtener-Comando -Módulo DFSR -Verbo Obtener

CommandType     Name                                               ModuleName
-----------     ----                                               ----------
Cmdlet          Get-DfsrBacklog                                    DFSR
Cmdlet          Get-DfsrCloneState                                 DFSR
Cmdlet          Get-DfsrConnection                                 DFSR
Cmdlet          Get-DfsrConnectionSchedule                         DFSR
Cmdlet          Get-DfsReplicatedFolder                            DFSR
Cmdlet          Get-DfsReplicationGroup                            DFSR
Cmdlet          Get-DfsrFileHash                                   DFSR
Cmdlet          Get-DfsrGroupSchedule                              DFSR
Cmdlet          Get-DfsrIdRecord                                   DFSR
Cmdlet          Get-DfsrMember                                     DFSR
Cmdlet          Get-DfsrMembership                                 DFSR
Cmdlet          Get-DfsrPreservedFiles                             DFSR
Cmdlet          Get-DfsrServiceConfiguration                       DFSR
Cmdlet          Get-DfsrState                                      DFSR

El Get-DfsrBacklog parece exactamente lo que estoy buscando. Sólo para asegurarme de haber echado un vistazo a la ayuda de ese cmdlet.

y me sorprendí un poco al darme cuenta de que devolvería los primeros 100 objetos en mi trabajo pendiente de replicación.

Eso es genial y todo, pero ¿qué pasa si quiero el recuento total? ¿Hay cientos o millones de elementos atrasados? No hay forma (que pude encontrar) de devolver el número total de objetos en el trabajo pendiente, PERO si se usa el modificador -Verbose, el comando escribirá un mensaje en la secuencia detallada indicando algo similar a:

La carpeta replicada tiene una acumulación de archivos. Carpeta replicada: “ReplFolder”. Contar: 46314

o

No hay trabajos pendientes para la carpeta replicada denominada "ReplFolder"

¡Y ahí está amigos! Cualquiera puede ejecutar el comando y leer el mensaje detallado. Cualquiera menos mi guión, al que no le importa en absoluto la transmisión detallada. ¿O no?

Aquí es donde resulta útil una pequeña característica excelente de PowerShell llamada redirección. Esta característica ya se introdujo en la versión 2.0 de Powershell, pero en aquel entonces se limitaba a redirigir solo dos flujos, el resultado de éxito (el resultado común al que normalmente me refiero como canalización) y los flujos de errores. En la versión 3.0 de Powershell se volvió aún más poderoso y ahora podemos dirigir cualquiera de los cinco flujos de salida (Éxito, Error, Advertencia, Detallado y Depuración) al flujo de salida exitoso o a un archivo de nuestra elección usando el operador de redirección '>' . La sintaxis es sencilla: primero ingrese el número del flujo de salida que debe redirigirse de la siguiente tabla, seguido del operador > y el destino de la redirección.

<td valign="top" width="137">
  All output
</td>
<td valign="top" width="137">
  Success output
</td>
<td valign="top" width="137">
  Errors
</td>
<td valign="top" width="137">
  Warning messages
</td>
<td valign="top" width="137">
  Verbose output
</td>
<td valign="top" width="137">
  Debug messages
</td>
*
1
2
3
4
5

Para probar esto, escribí una función que enviará texto a diferentes secuencias.

function Write-ToStreams
{
    [cmdletbinding()]
    Param()
    Begin
    {
        $VerbosePreference = 'Continue'
        $DebugPreference = 'Continue'
    }
    Process
    {
        Write-Host "This is written to host" -ForegroundColor Green
        Write-Output "This is written to Success output"
        Write-Error "This is an error"
        Write-Warning "This is a warning message"
        Write-Verbose "This is verbose output"
        Write-Debug "This is a debug message"
    }
}

Lo que me da el siguiente resultado:

Ahora, si quiero redirigir mi salida detallada, finalizaré mi comando con el número del flujo de salida detallado, "4", seguido del operador de redirección ">" y el objetivo de mi redirección.

La otra opción es redirigir un flujo de salida al flujo de salida exitoso usando &1 como objetivo de esta manera:

¡Que se ve exactamente igual que la primera vez que ejecutamos el comando! Pero esta vez el mensaje detallado se escribe en el flujo de salida.

Para probar esto, almacenemos la salida en una variable:

Y esta es la respuesta a mi problema con el recuento de archivos en el Backlog de DFSR. Solo tengo que separar la salida predeterminada de la salida detallada.

Entonces, comencemos de nuevo ejecutando la función Write-ToStreams y almacenando la salida en una variable sin redirección:

$Salida=Escritura en secuencias

Esto enviaría mensajes a todas las transmisiones excepto a la salida Success, que sería captada por mi variable $Output. Para captar las otras transmisiones utilizo otra característica llamada subexpresión. Una subexpresión es como una variable programada, por ejemplo, al escribir $ (Get-Date -f $FormatString), el código entre paréntesis se ejecuta y el resultado se devolverá como si proviniera de una variable. Al incluir el ejemplo anterior en una subexpresión, tenemos la oportunidad de redirigir la salida detallada y capturarla en otra variable como esta:

$VerboseMessage=$ ($Salida=Write-ToStreams) 4>&1

Lo cual podría repetirse para cualquiera de las tres secuencias restantes: Error, Advertencia y Depuración. Algo muy importante a tener en cuenta aquí es el texto verde creado por Write-Host. Este texto no se puede redirigir ni capturar en absoluto, lo que hace que Write-Host sea algo que solo debe usarse si la intención es escribir algo en la pantalla y nunca para la salida real. Utilice cualquiera de las otras secuencias para la salida.

Para volver a mi problema con el recuento de elementos en el trabajo pendiente de dfsr, escribí un script que devolverá el número de elementos en el trabajo pendiente para cada carpeta replicada utilizando esta técnica y está disponible en Technet Gallery.

Para obtener más información sobre la redirección, consulte el artículo de ayuda about_Redirection.

Artículos relacionados