Azure Azure Monitor Azure PowerShell

Azure PowerShell script: Create a Log Analytics workspace in your management subscription


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 logicvisualization 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.
  • 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 TerminalVisual 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. 

<#
.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.
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:  18/08/2022
Author:         Wim Matthyssen
Version:        2.1
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

$companyShortName = #"<your company short name here>" The three-letter abbreviation of your company name here. Example: "myh"
$spoke = "hub"
$abbraviationManagement = "management"
$region = #<your region here> The used Azure public region. Example: "westeurope"

$rgNameLogAnalyticsWorkspace = #<your Log Analytics rg 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"

## ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

## 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.


2 comments on “Azure PowerShell script: Create a Log Analytics workspace in your management subscription

  1. Rohak Jain

    Great job, this was very well explained!

    Liked by 1 person

  2. Pingback: Create a Log Analytics workspace on your Control Subscription – Wim Matthyssen - Firnco

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: