PowerShell неправильно экспортирует вывод в CSV - PullRequest
1 голос
/ 26 июня 2019

Я пытаюсь запустить следующий код, но PowerShell неправильно экспортирует вывод и выдает следующую ошибку:

Истекло время выполнения. Время ожидания истекло до завершения операции или сервер не отвечает.

Вот код:

$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

Цель состоит в том, чтобы экспортировать текущий вывод в Excel, а также ДОБАВИТЬ оператор для серверов, у которых также нет вывода.

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

На основе этих вопросов и некоторых полезных ответов: Powershell - Отдельный вывод на основе сервера + экспорт в Excel .

1 Ответ

1 голос
/ 26 июня 2019

Это должно вывести то, что вам нужно:

$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

Объяснение:

Я добавил параметр -Querytimeout внутри вашей хеш-таблицы ($InvokeParams)со значением 60 секунд.Вы можете полностью удалить эту строку Querytimeout = 60, если у вас все в порядке с истечением времени ожидания ваших запросов через 30 секунд.Вы можете увеличить или уменьшить это значение, если знаете что-то более подходящее.По умолчанию, основанное на моем тестировании, кажется, 30 секунд.

Я реализовал try-catch блоки и добавил обязательный параметр -Erroraction Stop в Invoke-SqlCmd.Если время ожидания запроса истекло, блок catch будет активирован и выведет свойство Server со значением Servername produced an error.Не стесняйтесь редактировать это по своему усмотрению.Ключевым здесь является оператор Continue, поскольку он позволяет перехватить исключение и перейти к следующему элементу в $Servers.Без Continue ваш скрипт просто перестал бы обрабатывать.

Я добавил if-else операторов, чтобы проверить, выводил ли ваш скрипт SQL какие-либо результаты.Если есть результаты, вы возвращаете результат, ожидаемый исходный код.Если есть ошибки, он выводит свойство Server с Servername has no errors.Опять же, не стесняйтесь редактировать то, что вы выберете.

Поскольку мы выводим результаты скрипта в CSV, мы должны вывести результаты в виде объектов с соответствующими именами свойств.Из-за природы команды Export-Csv вы не можете просто выводить строки произвольного текста с сообщениями.Они должны принадлежать свойству нашего пользовательского объекта."A String" | Export-Csv приводит к длине вашей строки, потому что длина - единственное свойство, которое читает команда.

...