Estoy tratando de ejecutar el siguiente código, pero PowerShell no está exportando la salida correcta y obteniendo el siguiente error:

Se agotó el tiempo de espera de ejecución. El tiempo de espera transcurrido antes de la finalización de la operación o el servidor no responde.

Aquí está el código:

$SERVERS = gc "C:\Users\listOfServers.txt"

$out = foreach ($SERVER in $SERVERS) { 
    $InvokeParams = @{
        Server = $SERVER
        Database = 'test'
        Username = 'admin'
        Password = 'testpassword'
        InputFile = 'C:\business.sql'
    }
    Invoke-SqlCmd @InvokeParams |
        Select-Object -Property *, @{L='Server';E={$SERVER}}
}

$path = 'C:\Users\test1.csv'
$out | Export-Csv -Path $path 
Invoke-Item -Path $path

El objetivo es exportar la salida actual a Excel, también agregue una declaración para los servidores que tampoco tienen ninguna salida.

ValueDate: 4/30/2019 12:00:00 AM
PrevValueDate: 4/29/2019 12:00:00 AM
Count:2100
Server 1  

Server 2 : no errors **NEEDS TO BE ADDED  

ValueDate: 4/30/2019 12:00:00 AM
PrevValueDate: 4/29/2019 12:00:00 AM
Count:100
Server 3

Sobre la base de estas preguntas y algunas respuestas útiles: PowerShell - Salida separada basada en el servidor + exportar a Excel.

1
user 9191 26 jun. 2019 a las 16:39

1 respuesta

La mejor respuesta

Esto debe emitir lo que necesita:

$SERVERS = gc "C:\Users\listOfServers.txt"

$out = foreach ($SERVER in $SERVERS) { 
    $InvokeParams = @{
        Server = $SERVER
        Database = 'test'
        Username = 'admin'
        Password = 'testpassword'
        InputFile = 'C:\business.sql'
        QueryTimeout = 60
    }

    try {
        $queryResults = $null
        $queryResults = Invoke-SqlCmd @InvokeParams -Erroraction stop
        if ($queryResults) {
            $queryResults | Select-Object -Property *, @{L='Server';E={$SERVER}}
        }
        else {
            "" | Select-Object @{L='Server';E={"{0} has no errors" -f $SERVER}}
        }
    } 
    catch {
        "" | Select-Object @{L='Server';E={"{0} produced an Error" -f $SERVER}}
        Continue
    }
}
$path = 'C:\Users\test1.csv'
$out | Export-Csv -Path $path -NoTypeInformation

Explicación:

Añadido el parámetro -Querytimeout dentro de su tabla hash ({$InvokeParams) con un valor de 60 segundos. Puede eliminar la línea Querytimeout = 60 por completo si está de acuerdo con sus consultas que se extienden después de 30 segundos. Puede aumentar o disminuir ese valor si sabe de algo más apropiado. El valor predeterminado en función de mis pruebas parece ser de 30 segundos.

Implementé try-catch bloques y agregué el parámetro requerido -Erroraction Stop a su Invoke-SqlCmd. Si hay un tiempo de espera de consulta, el bloque de captura activará y emitirá la propiedad Server con un valor de Servername produced an error. Siéntase libre de editar esto, como elija. La declaración Continue es la clave aquí, ya que le permite obtener la excepción y luego continuar en el siguiente elemento en $Servers. Sin Continue, su guión simplemente dejaría de procesar.

Añadí if-else declaraciones para verificar si su script de SQL emitió cualquier resultado. Si hay resultados, devuelve la salida su código original esperado. Si hay errores, entonces emite la propiedad Server con Servername has no errors. Nuevamente, siéntase libre de editarlo, como lo desea.

Dado que estamos enviando los resultados del script a CSV, debemos generar resultados como objetos con los nombres de propiedades que coincidan. Debido a la naturaleza del comando Export-Csv, no puede simplemente generar cuerdas de texto gratuitas con mensajes. Necesitan pertenecer a una propiedad de nuestro objeto personalizado. "A String" | Export-Csv resultados en la longitud de su cadena porque la longitud es la única propiedad que el comando lee.

1
AdminOfThings 26 jun. 2019 a las 15:26