I've to collect certain events for sharing it by mail; I'm missing something because the script, take a lot of time for only 2 servers and, the result is absurd!
Server1 events count:
$Etype = @( "Warning", "Error" )
$Source = "Cisco Systems Inc. ICM"
$StartDate = ((Get-Date).AddDays(-2))
$EndDate = Get-Date
(Get-EventLog -LogName Application -After $StartDate -Before $EndDate -EntryType $Etype -Source $Source).Count
}
$rEVT
2576
Server2 events count:
$rEVT2 = Invoke-Command -ComputerName $Srv2 -scriptblock {
$Etype = @( "Warning", "Error" )
$Source = "Cisco Systems Inc. ICM"
$StartDate = ((Get-Date).AddDays(-2))
$EndDate = Get-Date
(Get-EventLog -LogName Application -After $StartDate -Before $EndDate -EntryType $Etype -Source $Source).Count
}
$rEVT2
3853
My script:
$HostsTable = @()
foreach ( $Srv in $MyList ) {
$rEVT_ALL = Invoke-Command -ComputerName $Srv -scriptblock {
$Etype = @( "Warning", "Error" )
$Source = "Cisco Systems Inc. ICM"
$StartDate = ((Get-Date).AddDays(-2))
$EndDate = Get-Date
Get-EventLog -LogName Application -After $StartDate -Before $EndDate -EntryType $Etype -Source $Source | Select-Object -Property TimeGenerated, EntryType, Category, Message
}| ForEach-Object {
[PSCustomObject]@{
HN = $Srv
TimeCreated = [DateTime]$_.TimeGenerated
Category = $_.Category
Level = $_.EntryType
Message = $_.Message
}
$HostsTable += $rEVT_ALL
}
}
Mesaure command:
(Get-History)[-1].EndExecutionTime - (Get-History)[-1].StartExecutionTime
Days : 0
Hours : 0
Minutes : 18 <--------
Seconds : 35
Milliseconds : 898
Ticks : 11158982764
TotalDays : 0,0129154893101852
TotalHours : 0,309971743444444
TotalMinutes : 18,5983046066667
TotalSeconds : 1115,8982764
TotalMilliseconds : 1115898,2764
Result:
$HostsTable.count
10011624 <------ :D
$HostsTable | select -First 1
HN : SRV1 <--------
TimeCreated : 18/06/2024 19:10:56
Category : Message Delivery
Level : Error
Message : Client: clgr, state transfer operation aborted.
$HostsTable | select -Last 1
HN : SRV1 <--------
TimeCreated : 16/06/2024 19:55:43
Category : Call Router
Level : Error
Message : PG has reported that peripheral: CC_VRU_1 (ID: 5001) is not operational.
After, I've to export-excel, but at the moment something goes wrong...
Please, help me! Roberto
You're currently re-adding all the results from the previous iteration of the foreach
loop to $HostsTable
for every new event returned by the query against the next server.
Move this assignment statement $HostsTable += $rEVT_ALL
outside the pipeline:
foreach ($srv in $MyList) {
$rEVT_ALL = Invoke-Command -ComputerName $Srv -scriptblock {
$Etype = @( "Warning", "Error" )
$Source = "Cisco Systems Inc. ICM"
$StartDate = ((Get-Date).AddDays(-2))
$EndDate = Get-Date
Get-EventLog -LogName Application -After $StartDate -Before $EndDate -EntryType $Etype -Source $Source | Select-Object -Property TimeGenerated, EntryType, Category, Message
} | ForEach-Object {
[PSCustomObject]@{
HN = $Srv
TimeCreated = [DateTime]$_.TimeGenerated
Category = $_.Category
Level = $_.EntryType
Message = $_.Message
}
}
# wait to update `$hostsTable` until after the query returns
$HostsTable += $rEVT_ALL
}
This will ensure you save a reference to each event only once, and will improve execution time and memory footprint significantly.
You could also simplify your code further by passing the server list directly to Invoke-Command
and then use Select-Object
for the property selection/renaming, like so:
$HostsTable = Invoke-Command -ComputerName $MyList -scriptblock {
$Etype = @( "Warning", "Error" )
$Source = "Cisco Systems Inc. ICM"
$StartDate = ((Get-Date).AddDays(-2))
$EndDate = Get-Date
Get-EventLog -LogName Application -After $StartDate -Before $EndDate -EntryType $Etype -Source $Source | Select-Object -Property TimeGenerated, EntryType, Category, Message
} | Select-Object -Property @{Name='HN';Expression={$_.PSComputerName}},TimeCreated,Category,@{Name='Level';Expression={$_.EntryType}},Message
This will also make it faster overall, since the $HostsTable
array doesn't have to be resized multiple times, and you won't be blocking when a remote server is slow to respond.
One last trick to make the code a little more readable - splat your arguments, in turn reducing the amount of horizontal scrolling required when looking at the code:
$winEventQueryArgs = @{
LogName = 'Application'
Entrytype = @(
'Warning'
'Error'
)
Source = "Cisco Systems Inc. ICM"
After = (Get-Date).AddDays(-2)
Before = Get-Date
}
Get-EventLog @winEventQueryArgs | Select-Object -Property TimeGenerated, EntryType, Category, Message