Skip to content
BG Logging mit PowerShell, Azure Protection Account und Data Collection Rules zu LogAnalytics Workspace
Michael SedyDec 19, 2024 5:14:45 PM4 min read

Logging mit PowerShell, Azure Automation Account und Data Collection Rules zu LogAnalytics Workspace

BG Logging mit PowerShell, Azure Automation Account und Data Collection Rules zu LogAnalytics Workspace

Wir bei Experts Inside verwenden für viele automatisierte Aufgaben den Automation Account und Runbooks. Dabei hat sich das zuverlässige Logging oft als Problem herausgestellt. Deshalb werden bei uns wichtige Operationen in einen Log-Analytics-Workspace geschrieben.

Voraussetzungen für dieses Beispiel in diesem Blog sind ein Automation Account und ein Log Analytics workspace.

Aber es kann im Prinzip auch jede ARC-enabled Maschine verwendet werden.

Erstellen eines neuen Data collection Endpoints:

Picture5

Erstellen einer neuen custom log Tabelle (DCR based)

Picture6

Erstellen einer neuen data collection rule:

Picture7

Picture8

Picture9

schemasample.json

Picture10

Picture11

Managed identity des Automation Account einschalten oder die Managed identity einer Maschine die Arc-enabled ist verwenden.

Picture12

Picture13

Picture14

Picture15

 

Hier das zugehörige PowerShell-Script (5.1):

$endpoint_uri = "https://xi-expertsinside-t-euw-dce-01-b1j8.westeurope-1.ingest.monitor.azure.com" #Get-AutomationVariable -Name 'LogAnalyticsWorkspaceID'

$ImmutableId = "dcr-d16763b3b5b14d00aa83827563515dc4" #Get-AutomationVariable -Name 'LogAnalyticsWorkspaceKey'

$PSDefaultParameterValues = @{

    "Write-XiLog:LogsIngestionEndpoint"  = $endpoint_uri

    "Write-XiLog:ImmutableId" = $ImmutableId

}

 

function Write-XiLog {

    <#

    .SYNOPSIS

        This function writes log output for automation accounts

    .DESCRIPTION

        Logging in automation account is crap, so we send everything to log analytics.

        The log ingestion api requires authentication, we need to grant the Monitoring Metrics Publisher role

        to any identiy that uses this function. We need to call Connect-AzAccount -Identity and retrieve an access token.

    .NOTES

        log everything

    .EXAMPLE

        Write-XiLog -Message "this is what's happening"

       

        This just writes a message to the output of the runbook

    .EXAMPLE

        Write-XiLog -Message "this is what's happening" -Scriptname RUN-ExchangeMigration

       

        This writes a message to the output of the runbook AND sends the message to log analytics

    .EXAMPLE

        Write-XiLog -Message "this is what's happening" -Scriptname RUN-ExchangeMigration -Type Warning

       

        This writes a warning to the output of the runbook AND sends the message to log analytics

    #>

    [CmdletBinding()]

    param(

        [string]$Message,

        [string]$ScriptName,

        [ValidatePattern('.ingest.monitor.azure.com$')]

        [string]$LogsIngestionEndpoint,

        [ValidatePattern('^dcr-')]

        [string]$ImmutableId,

        [ValidatePattern('^Custom-')]

        [string]$StreamName = 'Custom-AutomationEngine',

        [ValidateSet("output", "warning", "error")]

        $Type = "output"

    )

    begin {

        $azContext = Get-AzContext

        if (-not($azContext)) {

            Connect-AzAccount -identity -TenantID 'a6k4k3k2-b751-46b9-85e0-78e7c873hd61' -SubscriptionId '027463n9-a84b-4b53-b972-c9f7473hf685' -ErrorAction Stop -WarningAction SilentlyContinue

        }

        Get-AzContext

        $Token = (Get-AzAccessToken -ResourceUrl 'https://monitor.azure.com' -ErrorAction Stop -WarningAction SilentlyContinue).Token

        $secureToken = ConvertTo-SecureString -String $Token -AsPlainText -Force

        $accesToken = [System.Net.NetworkCredential]::new(0,$secureToken).Password

        if (-not($accesToken)) {

            Write-Error "Could not retrieve access token."

        }

    }

    process {

        $time = Get-Date ([datetime]::Now) -Format O

        $logEvent = @{

            TimeGenerated = $time

            EventType     = $type

            Message       = $message

            Script        = $scriptname

        }

        $uri = "$LogsIngestionEndpoint/dataCollectionRules/$ImmutableId/streams/$($StreamName)?api-version=2023-01-01"

        $headers = @{"Authorization" = "Bearer $accesToken" }

        $body = ConvertTo-Json -InputObject @($logevent) -Compress

        #$body = $logEvent | ConvertTo-Json -AsArray -Compress

        Write-Verbose "Invoking [$uri] with body [$body]"

        $null = Invoke-RestMethod -Uri $uri -Method "Post" -Body $body -Headers $headers -ContentType 'application/json'

        switch ($type) {

            "output" { Write-Output "$time`: $message" }

            "warning" { Write-Warning "$time`: $message" }

            "error" { Write-Error "$time`: $message" }

        }

    }

}

 

Write-XiLog -Message "Testcomment" -Scriptname RUN-ExchangeMigration

 

Folgende Parameter müssen jetzt im Powershell-Skript eingesetzt werden:


Tenant-ID
Subscription-ID
Data collection endpoint:

Picture16

 

Data collection rule Immutable ID:

Picture17

 

StreamName Parameter:

Picture18

 

Jetzt kann das Script ausgeführt werden:

Picture19

Jetzt heisst es sich in Geduld zu üben bis der Eintrag in Log Analytics erscheint.
Die KQL Abfrage ist einfach der Tabellenname.

Picture20

 

Code-Archiv:

schemasample.json

[

    {

        "TimeGenerated": "2024-12-02T14:45:32Z",

        "EventType": "SampleEvent",

        "Script": "SampleScript",

        "Message": "This is a sample message."

    }

]

 

RUN-WriteToLogAnalytics.ps1

$endpoint_uri = "https://xi-expertsinside-t-euw-dce-01-b1j8.westeurope-1.ingest.monitor.azure.com" #Get-AutomationVariable -Name 'LogAnalyticsWorkspaceID'

$ImmutableId = "dcr-d16763b3b5b14d00aa83827563515dc4" #Get-AutomationVariable -Name 'LogAnalyticsWorkspaceKey'

$PSDefaultParameterValues = @{

   "Write-XiLog:LogsIngestionEndpoint" = $endpoint_uri

   "Write-XiLog:ImmutableId" = $ImmutableId

}

 

function Write-XiLog {

   <#

   .SYNOPSIS

       This function writes log output for automation accounts

   .DESCRIPTION

       Logging in automation account is crap, so we send everything to log analytics.

       The log ingestion api requires authentication, we need to grant the Monitoring Metrics Publisher role

       to any identiy that uses this function. We need to call Connect-AzAccount -Identity and retrieve an access token.

   .NOTES

       log everything

   .EXAMPLE

       Write-XiLog -Message "this is what's happening"

      

       This just writes a message to the output of the runbook

   .EXAMPLE

       Write-XiLog -Message "this is what's happening" -Scriptname RUN-ExchangeMigration

      

       This writes a message to the output of the runbook AND sends the message to log analytics

   .EXAMPLE

       Write-XiLog -Message "this is what's happening" -Scriptname RUN-ExchangeMigration -Type Warning

      

       This writes a warning to the output of the runbook AND sends the message to log analytics

   #>

   [CmdletBinding()]

   param(

       [string]$Message,

       [string]$ScriptName,

       [ValidatePattern('.ingest.monitor.azure.com$')]

       [string]$LogsIngestionEndpoint,

       [ValidatePattern('^dcr-')]

       [string]$ImmutableId,

       [ValidatePattern('^Custom-')]

       [string]$StreamName = 'Custom-AutomationEngine',

       [ValidateSet("output", "warning", "error")]

       $Type = "output"

   )

   begin {

       $azContext = Get-AzContext

       if (-not($azContext)) {

           Connect-AzAccount -identity -TenantID 'a6k4k3k2-b751-46b9-85e0-78e7c873hd61' -SubscriptionId '027463n9-a84b-4b53-b972-c9f7473hf685' -ErrorAction Stop -WarningAction SilentlyContinue

       }

       Get-AzContext

       $Token = (Get-AzAccessToken -ResourceUrl 'https://monitor.azure.com' -ErrorAction Stop -WarningAction SilentlyContinue).Token

       $secureToken = ConvertTo-SecureString -String $Token -AsPlainText -Force

       $accesToken = [System.Net.NetworkCredential]::new(0,$secureToken).Password

       if (-not($accesToken)) {

           Write-Error "Could not retrieve access token."

       }

   }

   process {

       $time = Get-Date ([datetime]::Now) -Format O

       $logEvent = @{

           TimeGenerated = $time

           EventType     = $type

           Message       = $message

           Script       = $scriptname

       }

       $uri = "$LogsIngestionEndpoint/dataCollectionRules/$ImmutableId/streams/$($StreamName)?api-version=2023-01-01"

       $headers = @{"Authorization" = "Bearer $accesToken" }

       $body = ConvertTo-Json -InputObject @($logevent) -Compress

       #$body = $logEvent | ConvertTo-Json -AsArray -Compress

       Write-Verbose "Invoking [$uri] with body [$body]"

       $null = Invoke-RestMethod -Uri $uri -Method "Post" -Body $body -Headers $headers -ContentType 'application/json'

       switch ($type) {

           "output" { Write-Output "$time`: $message" }

           "warning" { Write-Warning "$time`: $message" }

           "error" { Write-Error "$time`: $message" }

       }

   }

}

 

Write-XiLog -Message "Testcomment" -Scriptname RUN-ExchangeMigration

 

avatar

Michael Sedy

Azure Cloud Architect Infrastructure Expert @ Experts Inside Skills: Azure Infrastructure, Windows Server, PowerShell

VERWANDTE ARTIKEL