Framework/Configurations/ContinuousAssurance/Alert_Runbook.ps1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
Param(
    [object]$WebHookData
)


$telemetryKey ="[#telemetryKey#]"
#Telemetry functions -- start here
function SetCommonProperties([psobject] $EventObj) {
    $notAvailable = "NA"

}

function GetEventBaseObject([string] $EventName) {
    $eventObj = "" | Select-Object data, iKey, name, tags, time
    $eventObj.iKey = $telemetryKey
    $eventObj.name = "Microsoft.ApplicationInsights." + $telemetryKey.Replace("-", "") + ".Event"
    $eventObj.time = [datetime]::UtcNow.ToString("o")

    $eventObj.tags = "" | Select-Object ai.internal.sdkVersion
    $eventObj.tags.'ai.internal.sdkVersion' = "dotnet: 2.1.0.26048"

    $eventObj.data = "" | Select-Object baseData, baseType
    $eventObj.data.baseType = "EventData"
    $eventObj.data.baseData = "" | Select-Object ver, name, measurements, properties

    $eventObj.data.baseData.ver = 2
    $eventObj.data.baseData.name = $EventName

    $eventObj.data.baseData.measurements = New-Object 'system.collections.generic.dictionary[string,double]'
    $eventObj.data.baseData.properties = New-Object 'system.collections.generic.dictionary[string,string]'

    return $eventObj;
}

function PublishEvent([string] $EventName, [hashtable] $Properties, [hashtable] $Metrics) {
    try {
        #return if telemetry key is empty
        if ([string]::IsNullOrWhiteSpace($telemetryKey)) { return; };

        $eventObj = GetEventBaseObject -EventName $EventName
        SetCommonProperties -EventObj $eventObj

        if ($null -ne $Properties) {
            $Properties.Keys | ForEach-Object {
                try {
                    if (!$eventObj.data.baseData.properties.ContainsKey($_)) {
                        $eventObj.data.baseData.properties.Add($_ , $Properties[$_].ToString())
                    }
                }
                catch
                {
                    # Left blank intentionally.
                    # Error while sending alert event to telemetry. No need to break the execution.
                }
            }
        }
        if ($null -ne $Metrics) {
            $Metrics.Keys | ForEach-Object {
                try {
                    $metric = $Metrics[$_] -as [double]
                    if (!$eventObj.data.baseData.measurements.ContainsKey($_) -and $null -ne $metric) {
                        $eventObj.data.baseData.measurements.Add($_ , $Metrics[$_])
                    }
                }
                catch {
                    # Left blank intentionally.
                    # Error while sending alert event to telemetry. No need to break the execution.
                }
            }
        }

        $eventJson = ConvertTo-Json $eventObj -Depth 100 -Compress
        $eventObj
        Invoke-WebRequest -Uri "https://dc.services.visualstudio.com/v2/track" `
            -Method Post `
            -ContentType "application/x-json-stream" `
            -Body $eventJson `
            -UseBasicParsing | Out-Null
    }
    catch {
        # Left blank intentionally.
        # Error while sending alert event to telemetry. No need to break the execution.
    }
}

if($null -ne $WebHookData)
{
   #Getting required properties of WebhookData.
    $EventName="ActivityAlertLog"
    $WebhookName    =   $WebhookData.WebhookName
    $WebhookBody    =   $WebhookData.RequestBody
    $WebhookHeaders =   $WebhookData.RequestHeader
 try
  {    
   # Obtain the WebhookBody containing the AlertContext
    $WebhookBody = (ConvertFrom-Json -InputObject $WebhookBody)
    Write-Output "`nWEBHOOK BODY"
    Write-Output "============="
    Write-Output $WebhookBody

     # Obtain the AlertContext
    $AlertContext = [object]$WebhookBody.data.context
    $AlertContext 

     # Some selected AlertContext information
    Write-Output "`nALERT CONTEXT DATA"
    Write-Output "==================="
    Write-Output $alertcontext.activityLog.eventSource
    Write-Output $alertcontext.activityLog.subscriptionId
    Write-Output $alertcontext.activityLog.resourceGroupName
    Write-Output $alertcontext.activityLog.operationName
    Write-Output $alertcontext.activityLog.resourceType
    Write-Output $alertcontext.activityLog.resourceId
    Write-Output $alertcontext.activityLog.eventTimestamp


    PublishEvent -EventName $EventName  -Properties @{
    "subscriptionID"=$alertcontext.activityLog.subscriptionId;`
    "rescourceID"=$alertcontext.activityLog.resourceId;`
    "eventTimeStamp"=$alertcontext.activityLog.eventTimestamp;`
    "operationName"=$alertcontext.activityLog.operationName;`
    "caller"=$alertcontext.activityLog.caller;`
    "correlationId"=$alertcontext.activityLog.correlationId;`
    "eventSource"=$alertcontext.activityLog.eventSource;`
    "eventDataId"=$alertcontext.activityLog.eventDataId;`
    "level"=$alertcontext.activityLog.level;`
    "operationId"=$alertcontext.activityLog.operationId;`
    "resourceGroupName"=$alertcontext.activityLog.resourceGroupName;`
    "resourceProviderName"=$alertcontext.activityLog.resourceProviderName;`
    "status"=$alertcontext.activityLog.status;`
    "submissionTimestamp"=$alertcontext.activityLog.submissionTimestamp;`
    "resourceType"=$alertcontext.activityLog.resourceType
    }
   }
   catch
   {
     
     PublishEvent -EventName "ActivityAlertLog Error" -Properties @{ "ErrorRecord" = ($_ | Out-String) }
   }  
}
else
{
  Write-Error "Runbook called without webhook data." 
}