I often get some interesting tasks and one among that is to develop a PowerShell script to store custom logs in Azure log analytics workspace. The purpose of storing the logs and fields are based on the business requirements.
Step 1: Decide the content we need to store in Azure Monitor.
$Body = [pscustomobject]@{
Requester = $env:USERNAME
ComputerName = $env:COMPUTERNAME
Id = (New-Guid).Guid
Message = "Custom Message"
} | ConvertTo-Json
Step 2: String to Sign
$CustomerId = ""
$SharedKey = ""
$StringToSign = "POST" + "`n" + $Body.Length + "`n" + "application/json" + "`n" + $("x-ms-date:" + [DateTime]::UtcNow.ToString("r")) + "`n" + "/api/logs"
$BytesToHash = [Text.Encoding]::UTF8.GetBytes($StringToSign)
$KeyBytes = [Convert]::FromBase64String($SharedKey)
$HMACSHA256 = New-Object System.Security.Cryptography.HMACSHA256
$HMACSHA256.Key = $KeyBytes
$CalculatedHash = $HMACSHA256.ComputeHash($BytesToHash)
$EncodedHash = [Convert]::ToBase64String($CalculatedHash)
$Authorization = 'SharedKey {0}:{1}' -f $CustomerId, $EncodedHash
Step 3: Call the REST API
$Uri = "https://" + $CustomerId + ".ods.opinsights.azure.com" + "/api/logs" + "?api-version=2016-04-01"
$Headers = @{
"Authorization" = $Authorization;
"Log-Type" = "CUSTOMLOG";
"x-ms-date" = [DateTime]::UtcNow.ToString("r");
"time-generated-field" = $(Get-Date)
}
$Response = Invoke-WebRequest -Uri $Uri -Method Post -ContentType "application/json" -Headers $Headers -Body $Body -UseBasicParsing
if ($Response.StatusCode -eq 200) {
Write-Information -MessageData "Logs are Successfully Stored in Log Analytics Workspace" -InformationAction Continue
}
Upon successful REST API call, we see the results in custom logs. As per the documentation, we can see the Requester as Requester_s (string data type), ComputerName and ComputerName_s (string data type). Indeed, similarly we see Id as Id_g (GUID).