1

first thanks for your time. I create a really simple powershell code to check periodically gRPC health microservices, seven in a row every two seconds, and it is working since I got the response they are serving, the output is { "status": "SERVING" }

 while ($true) {grpcurl -d '{ \"service1\": \"name1\" }' -H "authorization: key key"  host1:port grpc.health.v1.Health/Check>> grpcurl -d '{ \"service2\": \"name2\" }' -H "authorization: key key"  host2:port grpc.health.v1.Health/Check>> grpcurl -d '{ \"service3\": \"name3\" }' -H "authorization: key key"  host3:port grpc.health.v1.Health/Check>> grpcurl -d '{ \"service4\": \"name4\" }' -H "authorization: key key"  host4:port grpc.health.v1.Health/Check>> grpcurl -d '{ \"service5\": \"name5\" }' -H "authorization: key key"  host5:port grpc.health.v1.Health/Check>> grpcurl -d '{ \"service6\": \"name6\" }' -H "authorization: key key" host6:port grpc.health.v1.Health/Check>> grpcurl -d '{ \"service7\": \"name7\" }' -H "authorization: key key" host7:port grpc.health.v1.Health/Check;start-sleep 2}

Now I wanted to got an email notification if the output is not "SERVING" while the code keeps running in a loop, how can I achieve this?

Clément Jean
  • 1,735
  • 1
  • 14
  • 32
Mark
  • 23
  • 5
  • Does this answer your question? [How to send email with PowerShell](https://stackoverflow.com/questions/36355271/how-to-send-email-with-powershell) – codaamok May 08 '22 at 08:54
  • partially, I dont know how to trigger the action (send email) based on the output when is not the expected ("SERVING") then keep checking in a loop, also be able to identify each service respectively, i,e one or more gRCP may fails but other can be ok, so the notification should be based on those fails and not send notification for the rest which are running, meaning they are healthy. – Mark May 08 '22 at 16:14

1 Answers1

1

I see two ways we can do it, the simplest way is creating a job and periodically receive it to see if the status changed:

$block = {
    while ($true) {
        grpcurl -d '{ \"service1\": \"name1\" }' -H "authorization: key key"  host1:port grpc.health.v1.Health/Check>> grpcurl -d '{ \"service2\": \"name2\" }' -H "authorization: key key"  host2:port grpc.health.v1.Health/Check>> grpcurl -d '{ \"service3\": \"name3\" }' -H "authorization: key key"  host3:port grpc.health.v1.Health/Check>> grpcurl -d '{ \"service4\": \"name4\" }' -H "authorization: key key"  host4:port grpc.health.v1.Health/Check>> grpcurl -d '{ \"service5\": \"name5\" }' -H "authorization: key key"  host5:port grpc.health.v1.Health/Check>> grpcurl -d '{ \"service6\": \"name6\" }' -H "authorization: key key" host6:port grpc.health.v1.Health/Check>> grpcurl -d '{ \"service7\": \"name7\" }' -H "authorization: key key" host7:port grpc.health.v1.Health/Check
        start-sleep 2
    }
}

$job = Start-Job -Name 'gRPCMon' -ScriptBlock $block

while ($true) {
    $result = Receive-Job -Id $job.Id
    if (($result | ConvertFrom-Json).status -ne 'SERVING') {
        ## Send-MailMessage here
    }
}

Or, in a more elegant way, we can run your code in a runspace and raise an event every time the condition is met. Then, we subscribe to that event:

$block = {
    while ($true) {
        grpcurl -d '{ \"service1\": \"name1\" }' -H "authorization: key key"  host1:port grpc.health.v1.Health/Check>> grpcurl -d '{ \"service2\": \"name2\" }' -H "authorization: key key"  host2:port grpc.health.v1.Health/Check>> grpcurl -d '{ \"service3\": \"name3\" }' -H "authorization: key key"  host3:port grpc.health.v1.Health/Check>> grpcurl -d '{ \"service4\": \"name4\" }' -H "authorization: key key"  host4:port grpc.health.v1.Health/Check>> grpcurl -d '{ \"service5\": \"name5\" }' -H "authorization: key key"  host5:port grpc.health.v1.Health/Check>> grpcurl -d '{ \"service6\": \"name6\" }' -H "authorization: key key" host6:port grpc.health.v1.Health/Check>> grpcurl -d '{ \"service7\": \"name7\" }' -H "authorization: key key" host7:port grpc.health.v1.Health/Check
        start-sleep 2
        if (($output | ConvertFrom-Json).status -ne 'SERVING') {
            $x.Host.Runspace.Events.GenerateEvent('StatusEvent', $null, $null, "Status Event")
        }
    }
}


$Global:x = [hashtable]::Synchronized(@{})
$x.Host = $Host
$runspace = [System.Management.Automation.Runspaces.RunspaceFactory]::CreateRunspace()
$runspace.Open()
$runspace.SessionStateProxy.SetVariable("x",$x)
$powershell = [System.Management.Automation.PowerShell]::Create()
$powershell.Runspace = $runspace
$powershell.AddScript($block)
$IActionResult = $powershell.BeginInvoke()

Register-EngineEvent -SourceIdentifier 'StatusEvent' -Action {
    ## Send-MailMessage here
}

Let me know if that did the trick.

FranciscoNabas
  • 505
  • 3
  • 9
  • Hi. Throws an error + if (($result | ConvertFrom-Json).status -ne 'SERVING') { + ~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [ConvertFrom-Json], ArgumentException + FullyQualifiedErrorId : System.ArgumentException,Microsoft.PowerShell.Commands.ConvertFromJsonCommand – Mark May 08 '22 at 22:33
  • the code works if is used only if (($result).status -ne 'SERVING') I mean without ConvertFrom-Json, also I am getting emails for each execution and the idea is get an email only if is not SERVING – Mark May 08 '22 at 22:37
  • And additionally would be great to have Write-Host when the code is runing in order to identify the response of each service. thanks!! – Mark May 08 '22 at 22:42
  • answer if you run grpcurl from the cli are these: { "status": "SERVING" } { "status": "NOT SERVING" } { "status": "UNKNOWN" } { "status": "SERVICE UNKNOWN" } – Mark May 09 '22 at 15:57
  • and need to trigger the action (send email) based on the output when is not "SERVING" – Mark May 09 '22 at 15:59