Skip to content

Instantly share code, notes, and snippets.

@JustinGrote
Last active August 3, 2024 08:19
Show Gist options
  • Save JustinGrote/22c4963f7eb5af08399c26cbf60bc3ae to your computer and use it in GitHub Desktop.
Save JustinGrote/22c4963f7eb5af08399c26cbf60bc3ae to your computer and use it in GitHub Desktop.
Create a Data Collection rule with embedded Ingestion DCRs
#requires -module Az.Monitor
using namespace Microsoft.Azure.PowerShell.Cmdlets.Monitor.DataCollection.Models
param(
$Workspace = '/subscriptions/xxxx/resourceGroups/SOC-Sentinel-Syslog/providers/Microsoft.OperationalInsights/workspaces/SOC-Sentinel-TestWorkspace',
$ResourceGroupName = 'SOC-Sentinel-Syslog',
$Location = 'westus3',
$StreamName = 'Custom-Test',
$Table = 'Custom-merakitest_CL' #This table must already exist
)
#Building the DCR definition in this way is type safe and will give you intellisense/validation in VSCode/CLI, but you can also build a JSON if you prefer.
$Definition = [DataCollectionRule]@{
StreamDeclaration = @{
$StreamName = [StreamDeclaration]@{
Column = @(
@{
Name = 'TimeGenerated'
Type = 'datetime'
}
)
}
}
DestinationLogAnalytic = [LogAnalyticsDestination]@{
WorkspaceResourceId = $Workspace
Name = 'workspace'
}
DataFlow = [DataFlow]@{
Stream = $StreamName
Destination = 'workspace'
OutputStream = $Table
}
}
$testDcrParams = @{
Location = $Location
ResourceGroupName = $ResourceGroupName
Definition = $Definition
}
$newRule = New-JAzDataCollectionRule @testDcrParams -Name 'TestRule2023Linux'
Write-Output $newRule
#This will return the endpoints needed for the log ingestion API
Invoke-AzRestMethod -path "$($newRule.id)?api-version=2023-03-11" |% Content | ConvertFrom-JSon |% properties |% endpoints
#Alternatively you can go to the Azure Portal, go to the DCR, and go to JSON view AND BE SURE TO TOGGLE API VERSION TO 2023-03-11
using namespace Microsoft.Azure.PowerShell.Cmdlets.Monitor.DataCollection.Models
using namespace System.Management.Automation
function New-JAzDataCollectionRule {
<#
.SYNOPSIS
Create a new Data Collection Rule in Azure Monitor. Uses 2023 API for direct DCRs
.NOTES
The MS Documentation on this sucks but the reference has a good example which is how I figured it out: https://learn.microsoft.com/en-us/rest/api/monitor/data-collection-rules/create?view=rest-monitor-2023-03-11&tabs=HTTP#create-or-update-data-collection-rule-with-embedded-ingestion-endpoints
#>
[CmdletBinding(DefaultParameterSetName = 'DataCollectionRule')]
param(
[Parameter(Mandatory)]
[string]$Name,
[Parameter(Mandatory)]
[string]$ResourceGroupName,
[Parameter(Mandatory)]
[string]$Location,
[ValidateSet('Direct', 'Linux', 'Windows','WorkspaceTransforms', 'AgentDirectToStore', 'AgentSettings', 'PlatformTelemetry')]
[string]$Kind = 'Direct',
[Parameter(ParameterSetName = 'DataCollectionRule', Mandatory)]
[ValidateNotNullOrEmpty()]
[DataCollectionRule]$Definition,
[Parameter(ParameterSetName = 'AsJsonString', Mandatory)]
[ValidateNotNullOrEmpty()]
#Provide a JSON definition of a DCR. Unlike the other examples, this should just be the properties section without the header.
[string]$Json,
[Parameter(ParameterSetName = 'FromJsonPath', Mandatory)]
[ValidateNotNullOrEmpty()]
#Provide a path to a JSON definition of a DCR. Unlike the other examples, this should just be the properties section without the header.
[string]$JsonFilePath,
[string]$ApiVersion = '2023-03-11'
)
if ($JsonFilePath) {
$Json = Get-Content -Path $JsonFilePath -Raw
}
if ($Definition) {
$Json = [DataCollectionRule]::FromJsonString($Definition)
}
[string]$payload = @"
{
"location": "$Location",
'kind': "$Kind",
"properties": $Json
}
"@
$iarmParams = @{
ApiVersion = $ApiVersion
Method = 'PUT'
SubscriptionId = (Get-AzContext).Subscription.Id
ResourceGroupName = $ResourceGroupName
ResourceProviderName = 'Microsoft.Insights'
ResourceType = 'dataCollectionRules'
Name = $Name
Payload = $payload
}
$response = Invoke-AzRestMethod @iarmParams
$result = $response.content | ConvertFrom-Json
if ($result.error) {
$message = "$($result.error.code): $($result.error.message)."
if ($result.error.details) {
foreach ($detail in $result.error.details) {
$message += [Environment]::NewLine + ' ' + "[$($detail.target)] " + $detail.code + ": " + $detail.message
}
}
$PSCmdlet.ThrowTerminatingError([ErrorRecord]::new(
[System.InvalidOperationException]::new($message),
$result.error.code,
[ErrorCategory]::InvalidOperation,
$response
))
}
Write-Output $result
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment