This blog post will show you how you can deploy a Log Analytics workspace and monitoring solutions in your Azure management subscription with the use of an Azure PowerShell script.
Log Analytics is a tool that ingests logs from Azure Monitor (store collected data) and on-premises or other systems (multiple sources). It then allows you to perform additional analysis on the collection of logs, like viewing, querying, or further analyzing them to get insights into the resources in your environment.
You can access those logs trough the Azure Portal, Azure PowerShell or Azure CLI. Or you can even export the log data to Excel or PowerBI for further analyzing and visualizing the data outside of Log Analytics.
When using a Log Analytics workspace, keep in mind that Azure Monitor has a log ingestion cost that is measured in gigabytes per day (GB/day), and that this is the main cost of using Log Analytics. For example, monitoring servers contributes from 1 to 3 GB per month in log and metric data. So, I recommend that you monitor your Log Analytics workspace to keep track of your exact usage.
If you want to read some more about Log Analytics, you can do so via the following Microsoft Docs link: Log Analytics documentation
Monitoring solutions are a collection of logic, visualization and data acquisition rules that provide metrics pivoted around a particular problem area. They help you to investigate and resolve operational issues faster and can help you with for example, patch status reporting and security auditing.
Keep in mind that monitoring solutions are no longer in active development (phased out) and are being replaced by the Azure Monitor Insights technology. Some examples of already deprecated solutions are: KeyVault, AzureNetworking and Backup.
If a solution requires an Automation account, then the Log Analytics workspace and Automation account must be linked to one another. Keep in mind that a Log Analytics workspace can be linked to only one Automation account, and an Automation account can be linked to only one Log Analytics workspace.
Also know that it can take a while (several hours) before you can see any relevant data in any solution after it is deployed.
If you want to read some more about the available monitoring solutions in Azure Monitor, you can do so via the following Microsoft Docs link: Monitoring solutions in Azure Monitor
To automate the deployment process of a Log Analytics workspace and the preferred monitoring solutions, I wrote the below Azure PowerShell script which does all of the following:
- Check if the PowerShell window is running as Administrator (when not running from Cloud Shell), otherwise the Azure PowerShell script will be exited.
- Suppress breaking change warning messages.
- Install Azure PowerShell module Az.MonitoringSolutions.
- Register required resource provider (Microsoft.HybridCompute) if not already registered. Registration may take up to 10 minutes.
- Change the current context to use a management subscription (a subscription with *management* in the Subscription name will be automatically selected).
- Store a specified set of tags in a hash table.
- Create a resource group for Log Analytics if it does not exist. Add specified tags and lock with a CanNotDelete lock.
- Create the Log Analytics workspace if it does not exist and add the specified tags.
- Save the Log Analytics workspace in a variable.
- Save the list of solutions to enable in a variable. The following solutions are stored: Security, SecurityInsights, AgentHealthAssessment, AzureActivity, SecurityCenterFree, DnsAnalytics, ADAssessment, AntiMalware, ServiceMap, SQLAssessment, SQLVulnerabilityAssessment, SQLAdvancedThreatProtection, AzureAutomation, Containers, ChangeTracking (optional -> also automatically installed by Azure Automation), Updates (optional -> also automatically installed by Azure Automation Updating Solution), VMInsights (optional -> also automatically installed by linking the Log Analytics workspace with VM Insights).
- Add the required solutions to the Log Analytics workspace.
- Set the log and metrics settings for the Log Analytics workspace, if they don’t exist.
To use the script copy and save it as Create-Log-Analytics-workspace-management-subscription.ps1 or download it from GitHub. Then before using the script, adjust all variables to your use and then run the customized script with Administrator privileges from Windows Terminal, Visual Studio Code, or Windows PowerShell. Or you can simply run it from Cloud Shell.
Prerequisites
- An Azure subscription (preferable with management in the naming).
- An Azure Administrator account with the necessary RBAC roles.
- At least Azure Az PowerShell module version 5.9.0
- Change all the variables in the script where needed to fit your needs (you can find an adjusted example in the screenshot below).


Azure PowerShell script
If you are not running the script from Cloud Shell, don’t forget to sign in with the Connect-AzAccount cmdlet to connect your Azure account. And if you are using multiple Azure subscriptions, select the proper subscription (if you removed the change the current context to use a management subscription part in het script) with the Set-AzContext cmdlet before running the script.

<#
.SYNOPSIS
A script used to create a Log Analytics workspace with enabled solutions in a management subscription.
.DESCRIPTION
A script used to create a Log Analytics workspace with enabled solutions in a management subscription.
The script will do all of the following:
Check if the PowerShell window is running as Administrator (when not running from Cloud Shell), otherwise the Azure PowerShell script will be exited.
Suppress breaking change warning messages.
Install Azure PowerShell module Az.MonitoringSolutions.
Register required resource provider (Microsoft.HybridCompute) if not already registered. Registration may take up to 10 minutes.
Change the current context to use a management subscription (a subscription with *management* in the subscription name will be automatically selected).
Store a specified set of tags in a hash table.
Create a resource group for Log Analytics if it does not exist. Add specified tags and lock with a CanNotDelete lock.
Create the Log Analytics workspace if it does not exist and add the specified tags.
Save the Log Analytics workspace in a variable.
Save the list of solutions to enable in a variable.
Add the required solutions to the Log Analytics workspace.
Set the log and metrics settings for the Log Analytics workspace, if they don't exist.
.NOTES
Filename: Create-Log-Analytics-workspace-management-subscription.ps1
Created: 14/10/2021
Last modified: 04/10/2022
Author: Wim Matthyssen
Version: 2.2
PowerShell: Azure PowerShell and Azure Cloud Shell
Requires: PowerShell Az (v5.9.0)
Action: Change variables were needed to fit your needs.
Disclaimer: This script is provided "As Is" with no warranties.
.EXAMPLE
Connect-AzAccount
Get-AzTenant (if not using the default tenant)
Set-AzContext -tenantID "xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx" (if not using the default tenant)
.\Create-Log-Analytics-workspace-management-subscription.ps1
.LINK
https://wmatthyssen.com/2022/08/01/azure-powershell-script-create-a-log-analytics-workspace-in-your-management-subscription/
#>
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Variables
$spoke = "hub"
$abbraviationManagement = "management"
$region = #<your region here> The used Azure public region. Example: "westeurope"
$rgNameLogAnalyticsWorkspace = #<your Log Analytics resource group name here> The name of the resource group in which the new Log Analytics resources will be created. Example: "rg-hub-myh-management-01"
$LogAnalyticsWorkspaceName = #<your Log Analytics workspace name here> The name for your Log Analytics workspace. Example: "law-hub-myh-01"
$logAnalyticsWorkspaceSku = "pergb2018"
$logAnalyticsDiagnosticsName = #<your Log Analytics Diagnostics settings name here> The name of the new diagnostic settings for your Log Analytics workspace. Example: "diag-law-hub-myh-01"
$tagSpokeName = #<your environment tag name here> The environment tag name you want to use. Example: "Env"
$tagSpokeValue = "$($spoke[0].ToString().ToUpper())$($spoke.SubString(1))"
$tagCostCenterName = #<your costCenter tag name here> The costCenter tag name you want to use. Example: "CostCenter"
$tagCostCenterValue = #<your costCenter tag value here> The costCenter tag value you want to use. Example: "23"
$tagCriticalityName = #<your businessCriticality tag name here> The businessCriticality tag name you want to use. Example: "Criticality"
$tagCriticalityValue = #<your businessCriticality tag value here> The businessCriticality tag value you want to use. Example: "High"
$tagPurposeName = #<your purpose tag name here> The purpose tag name you want to use. Example: "Purpose"
$tagPurposeValue = "$($abbraviationManagement[0].ToString().ToUpper())$($abbraviationManagement.SubString(1))"
$global:currenttime= Set-PSBreakpoint -Variable currenttime -Mode Read -Action {$global:currenttime= Get-Date -UFormat "%A %m/%d/%Y %R"}
$foregroundColor1 = "Red"
$foregroundColor2 = "Yellow"
$writeEmptyLine = "`n"
$writeSeperatorSpaces = " - "
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Check if PowerShell runs as Administrator (when not running from Cloud Shell), otherwise exit the script
if ($PSVersionTable.Platform -eq "Unix") {
Write-Host ($writeEmptyLine + "# Running in Cloud Shell" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor1 $writeEmptyLine
## Start script execution
Write-Host ($writeEmptyLine + "# Script started. Without any errors, it will need around 1 minute to complete" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor1 $writeEmptyLine
} else {
$currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
$isAdministrator = $currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
## Check if running as Administrator, otherwise exit the script
if ($isAdministrator -eq $false) {
Write-Host ($writeEmptyLine + "# Please run PowerShell as Administrator" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor1 $writeEmptyLine
Start-Sleep -s 3
exit
}
else {
## If running as Administrator, start script execution
Write-Host ($writeEmptyLine + "# Script started. Without any errors, it will need around 1 minute to complete" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor1 $writeEmptyLine
}
}
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Suppress breaking change warning messages
Set-Item Env:\SuppressAzurePowerShellBreakingChangeWarnings "true"
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Install module Az.MonitoringSolutions
Install-Module Az.MonitoringSolutions
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Register required resource provider if not already registered. Registration may take up to 10 minutes
# Register Microsoft.HybridCompute resource provider
Register-AzResourceProvider -ProviderNamespace Microsoft.OperationsManagement | Out-Null
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Change the current context to use a management subscription
$subNameManagement = Get-AzSubscription | Where-Object {$_.Name -like "*management*"}
Set-AzContext -SubscriptionId $subNameManagement.SubscriptionId | Out-Null
Write-Host ($writeEmptyLine + "# Management subscription in current tenant selected" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Store the specified set of tags in a hash table
$tags = @{$tagSpokeName=$tagSpokeValue;$tagCostCenterName=$tagCostCenterValue;$tagCriticalityName=$tagCriticalityValue}
Write-Host ($writeEmptyLine + "# Specified set of tags available to add" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Create a resource group for Log Analytics if it does not exist. Add specified tags and lock with a CanNotDelete lock
try {
Get-AzResourceGroup -Name $rgNameLogAnalyticsWorkspace -ErrorAction Stop | Out-Null
} catch {
New-AzResourceGroup -Name $rgNameLogAnalyticsWorkspace -Location $region -Force | Out-Null
}
# Set tags Log Analytics resource group
Set-AzResourceGroup -Name $rgNameLogAnalyticsWorkspace -Tag $tags | Out-Null
# Add purpose tag to the Log Analytics resource group
$storeTags = (Get-AzResourceGroup -Name $rgNameLogAnalyticsWorkspace).Tags
$storeTags += @{$tagPurposeName = $tagPurposeValue}
Set-AzResourceGroup -Name $rgNameLogAnalyticsWorkspace -Tag $storeTags | Out-Null
# Lock Log Analytics resource group with a CanNotDelete lock
$lock = Get-AzResourceLock -ResourceGroupName $rgNameLogAnalyticsWorkspace
if ($null -eq $lock){
New-AzResourceLock -LockName DoNotDeleteLock -LockLevel CanNotDelete -ResourceGroupName $rgNameLogAnalyticsWorkspace -LockNotes "Prevent $rgNameLogAnalyticsWorkspace from deletion" -Force | Out-Null
}
Write-Host ($writeEmptyLine + "# Resource group $rgNameLogAnalyticsWorkspace available with tags and CanNotDelete lock" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Create the Log Analytics workspace if it does not exist and add the specified tags
try {
Get-AzOperationalInsightsWorkspace -Name $LogAnalyticsWorkspaceName -ResourceGroupName $rgNameLogAnalyticsWorkspace -ErrorAction Stop | Out-Null
} catch {
New-AzOperationalInsightsWorkspace -ResourceGroupName $rgNameLogAnalyticsWorkspace -Name $LogAnalyticsWorkspaceName -Location $region -Sku $logAnalyticsWorkspaceSku -Force | Out-Null
}
# Set tags Log Analytics workspace
Set-AzOperationalInsightsWorkspace -ResourceGroupName $rgNameLogAnalyticsWorkspace -Name $LogAnalyticsWorkspaceName -Tag $tags | Out-Null
# Add purpose tag Log Analytics workspace
$storeTags = (Get-AzOperationalInsightsWorkspace -Name $LogAnalyticsWorkspaceName -ResourceGroupName $rgNameLogAnalyticsWorkspace).Tags
$storeTags += @{$tagPurposeName = $tagPurposeValue}
Set-AzOperationalInsightsWorkspace -ResourceGroupName $rgNameLogAnalyticsWorkspace -Name $LogAnalyticsWorkspaceName -Tag $storeTags | Out-Null
Write-Host ($writeEmptyLine + "# Log Analytics workspace $LogAnalyticsWorkspaceName created" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Save the Log Analytics workspace in a variable
$workSpace = Get-AzOperationalInsightsWorkspace -Name $LogAnalyticsWorkspaceName -ResourceGroupName $rgNameLogAnalyticsWorkspace
Write-Host ($writeEmptyLine + "# Log Analytics workspace variable created" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## List all solutions and their installation status
# Get-AzOperationalInsightsIntelligencePack -ResourceGroupName $rgNameLogAnalyticsWorkspace -Name $LogAnalyticsWorkspaceName
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Save the list of solutions to enable in a variable
# Optional solution -> ChangeTracking (also automatically installed by Azure Automation)
# Optional solution -> Updates (also automatically installed by Azure Automation Updating Solution)
# Optional solution -> VMInsights (also automatically installed by linking the Log Analytics workspace with VM Insights)
# Deprecated solution -> KeyVault
# Deprecated solution -> AzureNetworking
# Deprecated solution -> Backup
$lawSolutions = "Security", "SecurityInsights", "AgentHealthAssessment", "AzureActivity", "SecurityCenterFree", "DnsAnalytics", "ADAssessment", "AntiMalware", "ServiceMap", `
"SQLAssessment", "SQLVulnerabilityAssessment", "SQLAdvancedThreatProtection", "AzureAutomation", "Containers", "ChangeTracking", "Updates", "VMInsights"
Write-Host ($writeEmptyLine + "# Solutions variable created" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Add the required solutions to the Log Analytics workspace
foreach ($solution in $lawSolutions) {
New-AzMonitorLogAnalyticsSolution -Type $solution -ResourceGroupName $rgNameLogAnalyticsWorkspace -Location $workSpace.Location -WorkspaceResourceId $workSpace.ResourceId | Out-Null
}
Write-Host ($writeEmptyLine + "# Solutions added to Log Analytics workspace $LogAnalyticsWorkspaceName" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## List all monitor log analytics solutions under the Log Analytics workspace resource group
# Get-AzMonitorLogAnalyticsSolution -ResourceGroupName $rgNameLogAnalyticsWorkspace
## ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Set the log and metrics settings for the Log Analytics workspace if they don't exist
try {
Get-AzDiagnosticSetting -Name $logAnalyticsDiagnosticsName -ResourceId $workSpace.ResourceId -ErrorAction Stop | Out-Null
} catch {
Set-AzDiagnosticSetting -Name $logAnalyticsDiagnosticsName -ResourceId $workSpace.ResourceId -Category Audit -MetricCategory AllMetrics -Enabled $true `
-WorkspaceId ($workSpace.ResourceId) | Out-Null
}
Write-Host ($writeEmptyLine + "# Log Analytics workspace $LogAnalyticsWorkspaceName diagnostic settings set" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor2 $writeEmptyLine
## ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
## Write script completed
Write-Host ($writeEmptyLine + "# Script completed" + $writeSeperatorSpaces + $currentTime)`
-foregroundcolor $foregroundColor1 $writeEmptyLine
## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------








I hope this Azure PowerShell script is useful for you and provides you with a good starting point to use Log Analytics into your Azure environment.
If you have any questions or recommendations about it, feel free to contact me through my Twitter handle (@wmatthyssen) or to just leave a comment.
Great job, this was very well explained!
LikeLiked by 1 person
Pingback: Create a Log Analytics workspace on your Control Subscription – Wim Matthyssen - Firnco