Skip to content

Instantly share code, notes, and snippets.

@jpbruckler
Created May 14, 2024 12:48
Show Gist options
  • Save jpbruckler/9955a49f51572c5c3385abd4e1ad3e78 to your computer and use it in GitHub Desktop.
Save jpbruckler/9955a49f51572c5c3385abd4e1ad3e78 to your computer and use it in GitHub Desktop.
Assigns Data Collection Rules to Windows Servers
<#
.SYNOPSIS
Assigns Data Collection Rules to Azure VMs and Azure Arc servers.
.DESCRIPTION
This script connects to Azure, retrieves all Windows Azure VMs and Azure Arc
servers from specified subscriptions, and applies Data Collection Rules to
them. It is intended to streamline the setup of monitoring across both Azure
VM and Azure Arc environments by automating the association of DCRs.
.PARAMETER AzVMSubscriptionID
The subscription ID where the Azure VMs are located. This ID is used to set
the context and retrieve VMs from this subscription.
.PARAMETER AzArcSubscriptionID
The subscription ID for Azure Arc services. This ID is used to retrieve all
connected Azure Arc machines.
.PARAMETER DCRResourceGroupName
The name of the resource group where the Data Collection Rules are stored.
.EXAMPLE
PS> $AzVMSubscriptionID = 'your-azure-vm-subscription-id'
PS> $AzArcSubscriptionID = 'your-azure-arc-subscription-id'
PS> $DCRResourceGroupName = 'your-dcr-resource-group-name'
PS> .\AssignDataCollectionRules.ps1
This example sets the necessary subscription IDs and resource group name,
then runs the script to assign Data Collection Rules to all Windows-based
Azure VMs and Azure Arc servers.
.NOTES
This script requires the Az.ConnectedMachine module to interact with Azure
Arc servers. If the module is not installed, it will be installed automatically.
This script is written to run in an Azure Automation runbook using a system-
assigned user identity. The runbook environment should be PowerShell 7.2 or
later.
Ensure that the Azure PowerShell module is installed and that you have the
necessary permissions to interact with the Azure and Azure Arc subscriptions,
VMs, and Data Collection Rules.
The script requires that the executing account has the rights to assign DCRs
and can connect to Azure with a system-assigned user identity. Consider using
a service principal with Contributor rights to the resource groups containing
the virtual machines and Data Collection Rules.
#>
$StartTime = Get-Date
$AzVMSubscriptionID = ''
$AzArcSubscriptionID = ''
$DCRResourceGroupName = ''
$DCRFilter = '*-windce-*'
# Azure Connected Machine module is required for Azure Arc servers
if (-not (Get-Module -ListAvailable -Name 'Az.ConnectedMachine')) {
Write-Output 'Installing Az.ConnectedMachine module...'
Install-Module Az.ConnectedMachine -Force
}
# Early exit if authentication goes wrong
try {
$AzureContext = (Connect-AzAccount -Identity).context
}
catch {
Write-Output "There is no system-assigned user identity. Aborting.";
exit
}
#
# Set the subscription context to the Azure VM subscription, then retrieve
# all Azure VMs
#
$null = Select-AzSubscription -SubscriptionId $AzVMSubscriptionID
$CurrentContext = Get-AzContext
$WinAzureVMs = Get-AzVM -DefaultProfile $CurrentContext |
Select-Object Name, Id, @{n="OS";E={$_.StorageProfile.OsDisk.OsType}} |
Where-Object OS -eq 'Windows'
#
# Set the subscription context to the Azure Arc subscription, then retrieve
# all Azure Arc servers
#
$null = Select-AzSubscription -SubscriptionId $AzArcSubscriptionID
$CurrentContext = Get-AzContext
$WinArcServers = Get-AzConnectedMachine -SubscriptionId $AzArcSubscriptionID |
Select-Object Name, Id, @{n="OS";e={$_.OSName}} |
Where-Object OS -eq 'Windows'
#
# Merge the Azure VMs and Azure Arc servers into a single list
#
$MergeList = $WinAzureVMs + $WinArcServers
Write-Output ('Retrieved {0} Azure VMs and {1} Azure Arc servers' -f $WinAzureVMs.Count, $WinArcServers.Count)
#
# Retrieve all data collection rules, filtered by $DCRFilter, then iterate over
# the merged list of servers to assign the DCRs to each server.
#
# This could be expanded to match DCR tags to server tags, etc.
#
$AllDCRs = Get-AzDataCollectionRule -ResourceGroupName $DCRResourceGroupName -WarningAction SilentlyContinue |
Where-Object { $_.Name -like $DCRFilter }
foreach ($server in $MergeList) {
$assoc = $null;
$assoc = Get-AzDataCollectionRuleAssociation -ResourceUri $server.Id
foreach ($rule in $AllDCRs) {
if ($rule.Id -notin $assoc.DataCollectionRuleId) {
Write-Output ("Creating association to {0} for server {1}" -f $rule.Name, $server.Name)
New-AzDataCollectionRuleAssociation -RuleId $rule.Id -TargetResourceId $server.Id -AssociationName ('{0}-assoc' -f $rule.Name)
}
}
}
$EndTime = Get-Date
$Duration = $EndTime - $StartTime
Write-Output ('Job completed in {0:c}' -f $Duration)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment