由于PowerShell脚本中的早期命令,如何拖尾正在写入的日志文件?

时间:2011-08-18 14:46:56

标签: powershell windows-installer

我正在编写公司桌面应用程序的安装和配置过程。我们发出一个kiosk并且无法将所有内容放入安装程序中......直接向前移动!我正在使用Start-Process等待msiexeccomplete

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. 可选:过滤输出或写入debug / verbose以获得乐趣

1 个答案:

答案 0 :(得分:4)

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支持<{1}}改为Write-Verbose

编辑:我在安装应用程序时测试了我的答案,发现在阅读日志文件时速度非常慢。我更新了-Verbose调用以使用Get-Content将数据作为行数组发送。 -ReadCount 100行已更新以处理数组。

我还发现在Write-Host上使用-Wait开关导致在安装完成后写入所有日志输出。这可以通过使用:

来解决
Start-Process

编辑2:嗯,当我一起使用$msi = Start-Process -FilePath "msiexec" -ArgumentList $p -PassThru do{}until($msi.HasExited) -Wait时,我没有得到所有日志文件。我将日志文件的读取恢复到原来的状态。我不知道该如何处理速度呢。

编辑3:我已更新代码以使用StreamReader而不是-ReadCount,并将代码放入函数中。然后你会把它称为:

Get-Content