使用Register-EnginerEvent -Forward 和New-Event我試圖將物件事件從遠程服務器轉發到主機服務器,但它似乎不起作用。
為了證明這個理論,嘗試了下面的簡單代碼,它確實有效:
$TargetServer = 'localhost'
Register-EngineEvent -SourceIdentifier TimerEventOccured -Action {
Write-Host "$(Get-Date -format "dd-MM-yyyy hh:mm:ss tt") - $($event.MessageData) received..." -ForegroundColor Green
} | Out-Null
$TimerScriptBlock = {
Register-EngineEvent -SourceIdentifier TimerEventOccured -Forward | Out-Null
$Count = 1
while($Count -lt 3) {
New-Event -SourceIdentifier TimerEventOccured -MessageData 'Timertriggered'
Start-Sleep -Seconds 5
$Count = 1
}
}
$RemoteTimerScriptBlockJob = Invoke-Command -ComputerName $TargetServer -ScriptBlock $TimerScriptBlock -AsJob
while($RemoteTimerScriptBlockJob.State -in @('NotStarted','Running')) {
Write-Host "$(Get-Date -format "dd-MM-yyyy hh:mm:ss tt") - remote timer job still running"
Start-Sleep -Seconds 5
}
Write-Host "$(Get-Date -format "dd-MM-yyyy hh:mm:ss tt") - remote timer job complete"
...在下面添加我想要實作的Register-ObjectEvent 的地方沒有。
$TargetServer = 'localhost'
Register-EngineEvent -SourceIdentifier TimerEventOccured -Action {
Write-Host "$(Get-Date -format "dd-MM-yyyy hh:mm:ss tt") - $($event.MessageData) received..." -ForegroundColor Green
} | Out-Null
$TimerScriptBlock = {
Register-EngineEvent -SourceIdentifier TimerEventOccured -Forward | Out-Null
$timer = New-Object timers.timer
$timer.Enabled = $true
$timer.Interval = 3000
Register-ObjectEvent -InputObject $timer -EventName elapsed –SourceIdentifier thetimer -Action $action {
New-Event -SourceIdentifier TimerEventOccured -MessageData 'Timertriggered'
}
$timer.start()
Start-Sleep -Seconds 15 #just wait long enough for timer events to trigger a few times
}
$RemoteTimerScriptBlockJob = Invoke-Command -ComputerName $TargetServer -ScriptBlock $TimerScriptBlock -AsJob
while($RemoteTimerScriptBlockJob.State -in @('NotStarted','Running')) {
Write-Host "$(Get-Date -format "dd-MM-yyyy hh:mm:ss tt") - remote timer job still running"
Start-Sleep -Seconds 5
}
Write-Host "$(Get-Date -format "dd-MM-yyyy hh:mm:ss tt") - remote timer job complete"
能否請你幫忙?謝謝。
更新:
請注意,我可以直接將計時器事件轉發到源服務器,而不需要引擎事件作為中介。但是上面的定時器事件在這里只是用來說明這一點。我正在處理的真正作業是監視 Windows 事件日志中的某些事件 ID(在此處共享變得非常復雜)。
So, if I were to use -forward directly on the Eventlog listener Object then it will create a lot of traffic from target servers to host session (i.e. every event written will be dispatched as opposed to the only ones I am after). I want to be able to process the triggered event first on the remote server itself (to match the input eventIDs) and then forward the filtered event through engine event, which is where I am stuck.
uj5u.com熱心網友回復:
簡而言之:Register-ObjectEvent在您的情況下不是問題 - 這是您使用單個 Start-Sleep呼叫之后立即退出的事實,這會導致大多數事件丟失。
使用 掛起 PowerShell 自己的前臺執行緒時Start-Sleep,也會掛起其事件處理。
具體來說,這在您的情況下如下所示:
在
Start-Sleep運行時,事件會排隊- 其直接副作用是您的事件沒有及時處理。當
Start-Sleep結束并且前臺執行緒重新獲得控制權時,事件佇列開始得到處理,但由于腳本塊立即結束,所以在遠程腳本塊的整體執行結束之前,只有一個不可預測的排隊事件子集得到處理。看起來,PowerShell 并不能確保在退出之前處理排隊的事件。
因此,如果您將單個Start-Sleep -Seconds 15呼叫拆分為多個呼叫,讓 PowerShell 有時間處理其間的事件,您的代碼應該可以作業:
1..3 | ForEach-Object { Start-Sleep -Seconds 5 }
同樣,請注意,如果事件之后仍然碰巧排隊,則無法保證它們將在退出之前得到處理。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/444141.html
標籤:powershell
上一篇:嘗試從PowerShell獲取blob串列時出現空白
下一篇:從powershell生成pdf
