question

Sara925 avatar image
0 Votes"
Sara925 asked MotoX80 answered

powershell timespan

I have a PS scrips as below, and I am trying to rewrite as, the script should detect the servers only if the below $SyncStatusNotMatch condition exists for 10 mins. Any ideas on how to achieve that ?

 Param(
     $MailList = ""
 )
    
    
    
 foreach ($Module in $Modules)
 {
     if (-not(get-module $module))
     {
         Import-Module $Module -ErrorAction Stop
     }
 }
    
 $SyncStatusNotMatch = @(
     "Enabled"
     "Success"
 ) -join "|"
    
 $CSVPath = "\\winrepo\winscripts\Get-SyncStatusAlert\SyncStatus.csv"
    
 If (-not(test-path $CSVPath))
 {
     Write-Verbose "$(Get-Date): CSV does not exist it is being created" -Verbose
     $Null = New-Item $CSVPath -ErrorAction Stop
 }
    
 Write-Verbose "$(Get-Date): Importing CSV for previous alerts" -Verbose
 if ($env:Winusername)
 {
     Write-verbose "$(Get-date): Creating Secret Server Login" -Verbose
     $SecurePassword = ConvertTo-SecureString $env:WinPassword -AsPlainText -Force -ErrorAction Stop
     $SSCred = New-Object System.Management.Automation.PSCredential ($env:WinUserName,$SecurePassword) -ErrorAction Stop
     $null = Get-SecretServerToken -OperatorCredentials $SSCred -ErrorAction Stop
 }
 $SyncStatus = Import-Csv $CSVPath -ErrorAction Stop
    
 Write-Verbose "$(Get-Date): Obtaining data from Netscalers" -Verbose
 $NSexsre = Get-sre
    
 Write-Verbose "$(Get-Date): Comparing existing alerts with new alerts" -Verbose
 $StillActives = foreach ($Status in $SyncStatus)
 {
     $StatusResult = $nsexsre |
         Where-Object hasyncstatus -notmatch $SyncStatusNotMatch |
         Where-Object hasyncstatus -eq $Status.hasyncstatus |
         Where-Object name -eq $Status.name
    
     if ($Null -ne $StatusResult)
     {
         [pscustomobject]@{
             Name         = $Status.name
             HAState      = $Status.HAState
             HASyncStatus = $Status.HASyncStatus
             AlertDate    = $Status.AlertDate
         }
     }
 }
    
 $SendAlert = @()
    
 if ($StillActives.count -gt 0)
 {
     Write-Verbose "$(Get-Date): Verifying if a previous alert has not been sent in 12 hours" -Verbose
     foreach ($StillActive in $StillActives)
     {
         if ((Get-Date ($StillActive.alertdate)) -lt ((get-date).AddHours(-12)))
         {
             $SendAlert += $StillActive
         }
     }
    
     $nsexsrefiltered = ($NSExsre |
         Where-Object hasyncstatus -NotMatch $SyncStatusNotMatch |
         Where-Object name -notmatch ($StillActives.name -join "|")
     )
 }
 else
 {
     $nsexsrefiltered = $NSExsre | Where-Object hasyncstatus -NotMatch $SyncStatusNotMatch
 }
    
 if ($Null -ne $nsexsrefiltered)
 {
     Write-Verbose "$(Get-Date): Adding new alerts to the list" -Verbose
     $UpdateList = foreach ($ns in $nsexsrefiltered)
     {
         [pscustomobject]@{
             Name         = $ns.Name
             HAState      = $ns.HAState
             HASyncStatus = $ns.HASyncStatus
             AlertDate    = (Get-Date)
         }
     }
 }
    
 if(($Null -eq $StillActives) -and ($null -eq $UpdateList))
 {
     $NoAlerts =
     [pscustomobject]@{
         Name         = $Null
         HAState      = $Null
         HASyncStatus = $Null
         AlertDate    = $Null
     }
     $NoAlerts | Export-Csv $CSVPath -NoTypeInformation
 }
 Else
 {
     if ($Null -ne $UpdateList)
     {
         $ActivesToExport = $StillActives + $UpdateList
         $ActivesToExport | Export-Csv $CSVPath -NoTypeInformation
     }
     else
     {
         $StillActives | Export-Csv $CSVPath -NoTypeInformation
     }
 }
    
 If ($Null -ne $UpdateList)
 {
     $SendAlert += $UpdateList
 }
    
 If ($SendAlert.count -ne 0)
 {
     Write-Verbose "$(Get-Date): Sending email to $MailList" -Verbose
     Foreach ($Alert in $SendAlert)
     {
         Write-Verbose "$(Get-Date): Sending Alert for: $($Alert.name)" -Verbose
     }
    
     $Style = @"
         <style>
         BODY{font-family: Arial; font-size: 10pt;}
         TABLE{border: 1px solid black; border-collapse: collapse;}
         TH{border: 1px solid black; background: #dddddd; padding: 5px; }
         TD{border: 1px solid black; padding: 5px; }
         .odd {background: #DCDCDC;}
         .even {background: #FFFFFF;}
    
         </style>
 "@
    
     $PreContent = "Link to the SOP for addressing this issue: https://x/vAMsFQ"
     $Message = $SendAlert | ConvertTo-Html -Head $style -PreContent $PreContent | Set-AlternatingRows -CSSEvenClass even -CSSOddClass odd
     $MailSplat = @{
         To         = $MailList
         From       = "noreply@.com"
         SmtpServer = "hub.corp.com"
         Subject    = "out of Sync"
         Body       = $Message | Out-String
         BodyAsHtml = $true
     }
    
     Send-MailMessage @MailSplat
 }
 Else
 {
     Write-Verbose "$(Get-Date): No Alerts to send" -Verbose
 }
windows-server-powershell
· 2
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

When you post code please use the "Code Sample" editor. It's the 5th icon from the left on the Format Bar (the icon has the "101 010" graphic).

The regular text editor makes a mess of PowerShell code.

Please edit your original post and replace the code portion.

0 Votes 0 ·

You have three places in you code that refer to $SyncStatusNotMatch: lines 40, 65, and 70!

I don't see any mention of "servers" in the code, only "statuses" and "alerts".

0 Votes 0 ·
MotoX80 avatar image
0 Votes"
MotoX80 answered

Ok, I think I see what you are doing. Give this a try. Note that I did not have a way to test this. There may be errors in the code.

  Param(
      $MailList = ""
  )    
        
  foreach ($Module in $Modules)
  {
      if (-not(get-module $module))
      {
          Import-Module $Module -ErrorAction Stop
      }
  }
        
  $SyncStatusNotMatch = @(
      "Enabled"
      "Success"
  ) -join "|"
        
  $CSVPath = "\\winrepo\winscripts\Get-SyncStatusAlert\SyncStatus.csv"
        
  If (-not(test-path $CSVPath))
  {
      Write-Verbose "$(Get-Date): CSV does not exist it is being created" -Verbose
      $Null = New-Item $CSVPath -ErrorAction Stop
  }
        
  Write-Verbose "$(Get-Date): Importing CSV for previous alerts" -Verbose
  if ($env:Winusername)
  {
      Write-verbose "$(Get-date): Creating Secret Server Login" -Verbose
      $SecurePassword = ConvertTo-SecureString $env:WinPassword -AsPlainText -Force -ErrorAction Stop
      $SSCred = New-Object System.Management.Automation.PSCredential ($env:WinUserName,$SecurePassword) -ErrorAction Stop
      $null = Get-SecretServerToken -OperatorCredentials $SSCred -ErrorAction Stop
  }
  $SyncStatus = Import-Csv $CSVPath -ErrorAction Stop
        
  Write-Verbose "$(Get-Date): Obtaining data from Netscalers" -Verbose
  $NSexsre = Get-sre
        
  Write-Verbose "$(Get-Date): Comparing existing alerts with new alerts" -Verbose
  $StillActives = foreach ($Status in $SyncStatus)
  {
      $StatusResult = $nsexsre |
          Where-Object hasyncstatus -notmatch $SyncStatusNotMatch |
          Where-Object hasyncstatus -eq $Status.hasyncstatus |
          Where-Object name -eq $Status.name
        
      if ($Null -ne $StatusResult)
      {
          [pscustomobject]@{
              Name         = $Status.name
              HAState      = $Status.HAState
              HASyncStatus = $Status.HASyncStatus
              AlertDate    = $Status.AlertDate
              EmailSent    = $False 
          }
      }
  }
        
  $SendAlert = @()
        
  if ($StillActives.count -gt 0)
  {
      Write-Verbose "$(Get-Date): Verifying if a previous alert has not been sent in 12 hours" -Verbose
      foreach ($StillActive in $StillActives)
      {
          $SAtimespan = New-TimeSpan –Start $StillActive.Alertdate –End (get-date)
          If (($SAtimespan.TotalMinutes -gt 10) -and ($StillActive.emailsent = $false))
          {                                                      # This entry has been seen for at least 10 minutes 
              $StillActive.emailsent = $True                     # no need to send another email alert for 12 hours 
              $SendAlert += $StillActive                         # send an email
          }
          if ($SAtimespan.TotalMinutes -gt (12 * 60))
          {                                                      # This entry has been down for a long time,   
                StillActive.EmailSent = $false                     # Include in the alert email once every 12 hours 
              StillActive.AlertDate = (get-date)                 # start the 10 minute clock ticking again.  
          }
      }
        
      $nsexsrefiltered = ($NSExsre |
          Where-Object hasyncstatus -NotMatch $SyncStatusNotMatch |
          Where-Object name -notmatch ($StillActives.name -join "|")
      )
  }
  else
  {
      $nsexsrefiltered = $NSExsre | Where-Object hasyncstatus -NotMatch $SyncStatusNotMatch
  }
     
 # Now we can update the CSV
    
  if ($Null -ne $nsexsrefiltered)
  {
      Write-Verbose "$(Get-Date): Adding new alerts to the list" -Verbose
      $UpdateList = foreach ($ns in $nsexsrefiltered)
      {
          [pscustomobject]@{
              Name         = $ns.Name
              HAState      = $ns.HAState
              HASyncStatus = $ns.HASyncStatus
              AlertDate    = (Get-Date)
              EmailSent    = $False 
          }
      }
  }
        
  if(($Null -eq $StillActives) -and ($null -eq $UpdateList))
  {
      $NoAlerts =
      [pscustomobject]@{
          Name         = $Null
          HAState      = $Null
          HASyncStatus = $Null
          AlertDate    = $Null
          EmailSent    = $Null
      }
      $NoAlerts | Export-Csv $CSVPath -NoTypeInformation
  }
  Else
  {
      if ($Null -ne $UpdateList)
      {
          $ActivesToExport = $StillActives + $UpdateList
          $ActivesToExport | Export-Csv $CSVPath -NoTypeInformation
      }
      else
      {
          $StillActives | Export-Csv $CSVPath -NoTypeInformation
      }
  }
     
    
 # Send out the alert email. 
     
  # UpdateList contains new alerts, but we can't do anything with them until 10 minutes have passed.  
  #If ($Null -ne $UpdateList)
  #{
  #   $SendAlert += $UpdateList
  #}
        
  If ($SendAlert.count -ne 0)
  {
      Write-Verbose "$(Get-Date): Sending email to $MailList" -Verbose
      Foreach ($Alert in $SendAlert)
      {
          Write-Verbose "$(Get-Date): Sending Alert for: $($Alert.name)" -Verbose
      }
        
      $Style = @"
          <style>
          BODY{font-family: Arial; font-size: 10pt;}
          TABLE{border: 1px solid black; border-collapse: collapse;}
          TH{border: 1px solid black; background: #dddddd; padding: 5px; }
          TD{border: 1px solid black; padding: 5px; }
          .odd {background: #DCDCDC;}
          .even {background: #FFFFFF;}
        
          </style>
 "@
        
      $PreContent = "Link to the SOP for addressing this issue: https://x/vAMsFQ"
      $Message = $SendAlert | ConvertTo-Html -Head $style -PreContent $PreContent | Set-AlternatingRows -CSSEvenClass even -CSSOddClass odd
      $MailSplat = @{
          To         = $MailList
          From       = "noreply@.com"
          SmtpServer = "hub.corp.com"
          Subject    = "out of Sync"
          Body       = $Message | Out-String
          BodyAsHtml = $true
      }
        
      Send-MailMessage @MailSplat
  }
  Else
  {
      Write-Verbose "$(Get-Date): No Alerts to send" -Verbose
  }
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Sara925 avatar image
0 Votes"
Sara925 answered Sara925 commented

Thanks @MotoX80 that was much helpful, I was wondering if we can do this instead, which will not send an alert if it is send already in the last 12 hrs + it exists for 10 mins in a single line. Thoughts?


foreach ($StillActive in $StillActives)
{
$SAtimespan = New-TimeSpan –Start $StillActive.Alertdate –End (get-date)
if ((Get-Date ($StillActive.alertdate)) -lt ((get-date).AddHours(-12)) -and ($SAtimespan.TotalMinutes -gt 10))
{
$SendAlert += $StillActive
}
}

· 2
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

I think that will cause an email alert to be sent every time the script runs after an alert has been seen for over 12 hours. Is that what you want?

0 Votes 0 ·

oh no, I just want both the conditions to be satisfied, I need the alert to be triggered only if it exists for 10 mins also it should not send another alert if it is already triggered in the last 12 hrs.

0 Votes 0 ·
MotoX80 avatar image
0 Votes"
MotoX80 answered

This should send the alert out after 12 hours, without waiting the extra 10 minutes as I initially had it.

      foreach ($StillActive in $StillActives)
       {
           $ForceAlert = $False
           $SAtimespan = New-TimeSpan –Start $StillActive.Alertdate –End (get-date)
           if ($SAtimespan.TotalMinutes -gt (12 * 60))
           {                                                      # This entry has been down for a long time,   
               StillActive.EmailSent = $false                     # Include in the alert email once every 12 hours 
               StillActive.AlertDate = (get-date)                 # Reset the time so we don't send another alert for 12 more hours 
               $ForceAlert = $True   
           }
           If ((($SAtimespan.TotalMinutes -gt 10) -and ($StillActive.emailsent = $false)) -or ($ForceAlert))
           {                                                      # This entry has been seen for at least 10 minutes 
               $StillActive.emailsent = $True                     # no need to send another email alert for 12 hours 
               $SendAlert += $StillActive                         # send an email
           }
       }
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.