netcore1.0/Watch-LogFile.ps1
# Shim to use System.Threading.Timers because the friendlier System.Timers.Timers is not available in .NET Core 1.0 [System.Collections.ArrayList]$global:__timers = @() $references = @("C:\Windows\System32\DotNetCore\v1.0\System.Linq.dll", "C:\Windows\System32\DotNetCore\v1.0\System.Linq.Expressions.dll","C:\Windows\System32\WindowsPowerShell\v1.0\System.Management.Automation.ni.dll", "C:\Windows\System32\DotNetCore\v1.0\System.Reflection.dll") Add-Type -Path "$PSScriptRoot\RunspaceDelegateFactory.cs" -ReferencedAssemblies $references function New-Timer { param ( [System.Threading.TimerCallback]$callback, [int]$interval = 1000, [object]$state ) $runspacedDelegate = [RunspacedDelegateFactory]::NewRunspacedDelegate($callback, [Runspace]::DefaultRunspace) $timer = New-Object System.Threading.Timer($runspacedDelegate, $state, 0, $interval) return $timer } function Watch-LogFile { param ( [Parameter(Mandatory=$true)] [string] $LogPath, [int] $IntervalMs = 1000 ) $identifier = [Guid]::NewGuid().ToString() $tailJob = Start-Job -ScriptBlock { Get-Content -Path $args[0] -Tail 1 -Wait } -ArgumentList $LogPath $callback = [System.Threading.TimerCallback] { param($state) $results = Receive-Job $state.job if ($results -ne $null) { New-Event -SourceIdentifier $state.identifier -MessageData $results | out-null } } $state = @{"identifier"=$identifier; "job"=$tailJob;} $timer = New-Timer -callback $callback -interval $IntervalMs -state $state $__timers.Add($timer) | out-null Register-EngineEvent -SourceIdentifier $identifier -Action { $event.MessageData | Write-Host } | out-null return $tailJob } |