PowerShell command optimization

Hello, for a project we need to be able to close an alarm with specific names, for this task we are using a powershell script that has the following comands:

Connect-ManagementServer

$c1 = New-AlarmCondition -Target Name -Operator Equals -Value “Alarm_Name”

$c2 = New-AlarmCondition -Target State -Operator NotEquals -Value 11

Get-AlarmLine -Conditions $c1, $c2 | Update-AlarmLine -Updates @{ StateName = ‘Closed’; StateInt = ‘11’ }

This script works perfectly, but due to the size of the system, searching in all the alarms and not only in the open ones makes closing the alarm a task that needs 5 to 6 seconds to get done.

We would like to reduce this time as much as possible. Is there a way to search only the open alarms? Should I bee doing the search in another way?

Hope anyone can help with this issue and thank you in advance!

Hi @Valentín Otte​,

It looks like you have a good handle on it - you’re already adding a condition to only look for alarms that aren’t closed. To improve the speed of the query a bit, maybe you can limit the scope by time as well? If you can keep the timestamp of the last alarm processed by the script in a file next to the script, you could limit your alarm line retrieval to only those alarms modified since the last time the script ran.

This works on the relatively small demo system I tested it against. On the first run, it’ll go back 30 years, but after the first run, a bookmark.ts file will be saved next to the script with the modified timestamp of the last alarm processed. On the next execution, it will only pull alarms modified after that timestamp.

You might also consider testing how much time the query takes vs the multiple calls to Update-AlarmLine. It could be that the bulk of time is spent updating individual alarms depending on how many are being closed on each execution. I’m not aware of a bulk alarm update API call to speed up the updates if that’s where the time is going though.

#Requires -Module MilestonePSTools
 
if (-not (Get-VmsManagementServer -ErrorAction SilentlyContinue)) {
    Connect-ManagementServer -ShowDialog -AcceptEula -Force -DisableAutoLogin
}
 
$lastModified = [datetime]::now.AddYears(-30)
if (Test-Path .\bookmark.ts) {
    # We'll place the datetime "ticks" value for the last alarm we processed in bookmark.ts
    # Instead of the alarm timestamp, we'll use the modified time, so if an alarm is re-opened, it can be re-processed.
    $lastModified = [datetime]::SpecifyKind([datetime]::new((Get-Content .\bookmark.ts)), [datetimekind]::Utc)
} 
 
$c0 = New-AlarmCondition -Target Modified -Operator GreaterThan -Value $lastModified
$c1 = New-AlarmCondition -Target Name     -Operator Equals      -Value "Alarm_Name" 
$c2 = New-AlarmCondition -Target State    -Operator NotEquals   -Value 11
 
$s0 = New-AlarmOrder     -Target Modified -Order Ascending
 
Write-Host "Retrieving non-closed alarms modified since $lastModified"
$processedAlarms = 0
$sw = [diagnostics.stopwatch]::StartNew()
Get-AlarmLine -Conditions $c0, $c1, $c2 -SortOrders $s0 | ForEach-Object {
    $_ | Update-AlarmLine -Updates @{ StateName = 'Closed'; StateInt = '11' }
    $lastModified = $_.Modified
    $processedAlarms++
}
$sw.Stop()
 
Write-Host "Processed $processedAlarms non-closed alarms modified up until $lastModified in $($sw.Elapsed.TotalSeconds.ToString('n3')) seconds"
$lastModified.Ticks | Set-Content .\bookmark.ts