Как подключить файл журнала, который пишется из-за более ранней команды в сценарии PowerShell? - PullRequest
2 голосов
/ 18 августа 2011

Я пишу сценарий процедуры установки и настройки настольного приложения моей компании.Мы высылаем киоск и не можем все поместить в установщик ... двигаясь вперед!Я использую Start-Process для ожидания msiexec до завершения .

function Run-Installer
{
    param
    (
        [string] $msi = $(throw "Required parameter: 'msi'"),
    )

    if(-not(Test-Path $msi -Type Leaf))
    {
        throw "The installer could not be found: '$msi'"
    }

    $name = (Get-Item $msi).BaseName

    Write-Host "Installing $name"

    $p = 
    @(
        "/I `"$msi`"",                    # Install this MSI
        "/QN",                            # Quietly, without a UI
        "/L*V `"$ENV:TEMP\$name.log`""    # Verbose output to this log
    )

    Start-Process -FilePath "msiexec" -ArgumentList $p -Wait
}

Где я хочу получить фантазию:с выводом журнала из msiexec.Я хочу передать содержимое журнала на консоль во время работы установщика.Я предполагаю, что решение состоит из нескольких частей

  1. Запуск установщика в фоновом режиме, в ожидаемом режиме
  2. Хвост файла журнала, пока не выполнено какое-то условие (задание установщика завершено)
  3. Необязательно: Фильтрация вывода или запись в отладочный / подробный текст для удовольствия

1 Ответ

4 голосов
/ 18 августа 2011
function Start-FileTail {
    param($path)
    # Get unique source ID
    $sourceID = "FileTailLine-" + [guid]::NewGuid()

    $job = Start-Job -ArgumentList $path, $sourceID {
        param($path,$sid)

        Register-EngineEvent -SourceIdentifier $sid -Forward

        do{}until(Test-Path $path)

        $fs = New-Object IO.FileStream ($path, [IO.FileMode]::Open, 
                [IO.FileAccess]::Read, [IO.FileShare]::ReadWrite)
        $sr = New-Object IO.StreamReader ($fs)
        $lines = @()

        while(1) {
            $line = $sr.ReadLine()
            $lines += $line
            # Send after every 100 reads
            if($lines.Count -gt 100) {
                # Join lines into 1 string
                $text = @($lines| where {$_} ) -join "`n"
                # Only send if text was found
                if($text){New-Event -SourceIdentifier $sid -MessageData $text}
                $lines = @()
            }
        }
    }

    $event = Register-EngineEvent -SourceIdentifier $sourceID -Action {
        Write-Host $event.MessageData
    }
    New-Object Object|
        Add-Member -Name Job -Type NoteProperty -Value $job -PassThru|
        Add-Member -Name SourceIdentifier -Type NoteProperty -Value $sourceID -PassThru
}

function Stop-FileTail {
    param($TailInfo)
    Remove-Job $TailInfo.Job -Force
    Unregister-Event -SourceIdentifier $tail.SourceIdentifier
}

Вы можете удалить задание и отменить регистрацию события после завершения установки.

Изменить Write-Host на Write-Verbose для -Verbose поддержка

РЕДАКТИРОВАТЬ: Я проверил мой ответ при установке приложения и обнаружил, что это было довольно медленно при чтении файла журнала. Я обновил вызов Get-Content, чтобы использовать -ReadCount 100 для отправки данных в виде массивов строк. Строка Write-Host была обновлена ​​для обработки массивов.

Я также обнаружил, что при использовании переключателя -Wait на Start-Process все записи журнала были записаны после завершения установки. Это можно исправить с помощью:

$msi = Start-Process -FilePath "msiexec" -ArgumentList $p -PassThru
do{}until($msi.HasExited)

РЕДАКТИРОВАТЬ 2: Хм, я не получаю весь файл журнала, когда использую -Wait и -ReadCount вместе. Я вернул чтение файла журнала обратно в исходное состояние. Я еще не уверен, что делать со скоростью.

РЕДАКТИРОВАТЬ 3: Я обновил код, чтобы использовать StreamReader вместо Get-Content, и вставил код в функции. Затем вы бы назвали это как:

$path = "$ENV:TEMP\$name.log"
if(Test-Path $path){Remove-Item $path}

$msi = Start-Process -FilePath "msiexec" -ArgumentList $p -PassThru
$tail = Start-FileTail $p
do{}until($msi.HasExited)
sleep 1 # Allow time to finish reading log.
Stop-FileTail $tail
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...