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 行已更新以处理数组。
我还发现使用Start-Process 上的-Wait 开关会导致在安装完成后写入所有日志输出。这可以通过以下方式解决:
$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