Tip
Azure Stack Hub has built-in Azure Monitor capabilities; however, they are limited. Therefore, if you are looking for a more feature rich solution, you should use public Azure Monitor.
You can find out more about Azure Stack Hub's built-in Azure Monitor capabilities in the following article Use Azure Monitor on Azure Stack Hub.
Overview
This article explain how to utilise public Azure Monitor with Azure Stack Hub instead of the built-in Azure Monitor.
Azure Monitor is the platform service that provides a single source for monitoring Azure resources. With Azure Monitor, you can visualise, query, route, archive and otherwise take action on the metrics and logs coming from resources in Azure.
In this article we'll enable the following solutions for Azure Stack Hub VMs:
Prerequisites
To complete the steps in this article, you must have appropriate access to a subscription in the Azure and Azure Stack Hub portals.
Enabling Azure Monitor for VMs
Warning
Before proceeding, check here that your VMs' OS version is supported.
Creating the Log Analytics Workspace
Log in to the public Azure portal.
Create a Log Analytics Workspace in your Azure subscription:
Click Create a resource
In the search bar, search for log analytics
Click Log Analytics Workspace
Click Create

Provide the following:
A Subscription to link the workspace to
A Resource group to host the workspace in
A unique Name for the Log Analytics Workspace
A Region to host the workspace in
Note
Azure Monitor for VMs supports Log Analytics Workspace in the following regions.

Click Review + Create once finished, then click Create. The Log Analytics Workspace will now begin deploying. A notification will appear in the top right of the portal.
Once deployment is complete, navigate to the resource group you placed the Log Analytics Workspace in.
Click the newly created workspace.
On the new blade, under Settings, select Agents management.
Note down the Workspace ID and Primary Key values.

(Optional) Configure additional data sources
- Under Settings, select Agents configuration.
Windows event logs
Click Add windows event log
Select an event log from the dropdown and use the checkboxes to determine the severities that you want to collect for this log type.
Note
If the log type you want to add does not appear in the list, you can add it by typing in the full name. You can find the full name of the log type in Event Viewer. Open the Properties page for the log type and copy the string from the Full Name field.


Repeat for each event log you require, then click Apply

Click Add performance counter
Select a counter from the dropdown. You can adjust the sample rate to increase or decrease the amount of data collected for this counter.
Repeat for each performance counter you require, then click Apply

Syslog
Click Add facility
Select a facility from the dropdown and use the checkboxes to determine the severities that you want to collect for this facility.
Repeat for each facility you require, then click Apply

Click Add performance counter
Select a counter from the dropdown. You can adjust the sample rate to increase or decrease the amount of data collected for this counter.
Repeat for each performance counter you require, then click Apply

Execute the following PowerShell script to create the log analytics workspace.
Variable name |
Variable description |
Input |
$WorkspaceName |
The name of the log analytics workspace |
|
$WorkspaceResourceGroupName |
The name of the resource group which the log analytics workspace resides in |
|
$WorkspaceLocation |
The region to deploy the log analytics workspace and resource group in |
|
# Install module
Install-Module -Name "Az.OperationalInsights" -Scope AllUsers -Verbose -Force
# Initialise environment and variables
## Login to public Azure
Connect-AzAccount -Environment "AzureCloud"
## Create workspace analytics specific resources
# Input variables
$LogAnalyticsWorkspaceName = ""
$LogAnalyticsWorkspaceResourceGroupName = ""
$LogAnalyticsWorkspaceLocation = ""
# Check if the Log Analytics resource group exists, if it doesn't exist then create it
try {
$LogAnalyticsWorkspaceResourceGroup = Get-AzResourceGroup -Name $LogAnalyticsWorkspaceResourceGroupName -Location $LogAnalyticsWorkspaceLocation -Verbose -ErrorAction Stop
}
catch {
Write-Warning -Message "Log Analytics Workspace resource group ""$($LogAnalyticsWorkspaceResourceGroupName)"" in location ""$($LogAnalyticsWorkspaceLocation)"" doesn't exist. Creating now..."
try {
$LogAnalyticsWorkspaceResourceGroup = New-AzResourceGroup -Name $LogAnalyticsWorkspaceResourceGroupName -Location $LogAnalyticsWorkspaceLocation -Verbose -ErrorAction Stop
}
catch {
Write-Error -Message "Failed to create Log Analytics Workspace resource group ""$($LogAnalyticsWorkspaceResourceGroupName)"" in location ""$($LogAnalyticsWorkspaceLocation)"":`n$($_.Exception.Message)"
throw
}
}
# Check if the Log Analytics Workspace exists, if it doesn't exist then create it
try {
Write-Verbose "Attempting to retrieve Log Analytics Workspace ""$($LogAnalyticsWorkspaceName)"" in resource group ""$($LogAnalyticsWorkspaceResourceGroupName)"" and location ""$($LogAnalyticsWorkspaceLocation)""."
$LogAnalyticsWorkspace = Get-AzOperationalInsightsWorkspace -ResourceGroupName $LogAnalyticsWorkspaceResourceGroup.ResourceGroupName -Name $LogAnalyticsWorkspaceName -Verbose -ErrorAction Stop
}
catch {
try {
Write-Warning -Message "Log Analytics Workspace ""$($LogAnalyticsWorkspaceName)"" in location ""$($LogAnalyticsWorkspaceLocation)"" doesn't exist. Creating now..."
$LogAnalyticsWorkspace = New-AzOperationalInsightsWorkspace -ResourceGroupName $LogAnalyticsWorkspaceResourceGroup.ResourceGroupName -Name $LogAnalyticsWorkspaceName -Location $LogAnalyticsWorkspaceLocation -Verbose -ErrorAction Stop
}
catch {
Write-Error -Message "Failed to create Log Analytics Workspace ""$($LogAnalyticsWorkspaceName)"" in resource group ""$($LogAnalyticsWorkspaceResourceGroupName)"" and location ""$($LogAnalyticsWorkspaceLocation)"":`n$($_.Exception.Message)"
throw
}
}
try {
# Get Log Analytics Workspace GUID and primary key
Write-Verbose -Message "Attempting to retrieve Log Analytics Workspace ""$($LogAnalyticsWorkspace.Name)"" GUID, primary key and base64 encode them."
$EncodedWorkspaceGuid = [System.Convert]::ToBase64String([System.Text.Encoding]::UNICODE.GetBytes(($LogAnalyticsWorkspace.CustomerId).GUID))
$WorkspaceKey = (Get-AzOperationalInsightsWorkspaceSharedKey -ResourceGroupName $LogAnalyticsWorkspace.ResourceGroupName -Name $LogAnalyticsWorkspace.Name -Verbose -ErrorAction Stop).PrimarySharedKey
$EncodedWorkspaceKey = [System.Convert]::ToBase64String([System.Text.Encoding]::UNICODE.GetBytes($WorkspaceKey))
}
catch {
Write-Error -Message "Failed to obtain Log Analytics Workspace ""$($LogAnalyticsWorkspace.Name)"" GUID or primary key:`n$($_.Exception.Message)"
throw
}
(Optional) Configure data sources for additional logs
# Windows event logs
## The below example will create data sources for the event logs "System", "Application" and "Setup", with all severities being collected
$EventLogNames = @("System", "Application", "Setup")
foreach ($EventLogName in $EventLogNames) {
New-AzOperationalInsightsWindowsEventDataSource `
-ResourceGroupName $LogAnalyticsWorkspaceResourceGroupName `
-WorkspaceName $LogAnalyticsWorkspaceName `
-Name "$($EventLogName) Event Log" `
-EventLogName $EventLogName `
-CollectErrors `
-CollectWarnings `
-CollectInformation
}
<# ---- Performance counter format ----
To select all instances of a counter, add (*) after the object name:
Object name(*)\Counter name
To select a specific instance of a counter, add (Instance name) after the object name:
Object name(Instance name)\Counter name
#>
# Windows performance counters
## The below example will create the counter "Memory(*)\Available MBytes"
New-AzOperationalInsightsWindowsPerformanceCounterDataSource -ResourceGroupName $LogAnalyticsWorkspaceResourceGroupName -WorkspaceName $LogAnalyticsWorkspaceName -ObjectName "Memory" -InstanceName "*" -CounterName "Available MBytes" -IntervalSeconds 20 -Name "Example Windows Performance Counter"
# Enable IIS Log Collection using agent
Enable-AzOperationalInsightsIISLogCollection -ResourceGroupName $LogAnalyticsWorkspaceResourceGroupName -WorkspaceName $LogAnalyticsWorkspaceName
# Linux performance counters
## The below example will create multiple counters "% Used Inodes", "Free Megabytes", "% Used Space", "Disk Transfers/sec", "Disk Reads/sec" and "Disk Writes/sec", all under the parent counter "Logical Disk"
New-AzOperationalInsightsLinuxPerformanceObjectDataSource -ResourceGroupName $LogAnalyticsWorkspaceResourceGroupName -WorkspaceName $LogAnalyticsWorkspaceName -ObjectName "Logical Disk" -InstanceName "*" -CounterNames @("% Used Inodes", "Free Megabytes", "% Used Space", "Disk Transfers/sec", "Disk Reads/sec", "Disk Writes/sec") -IntervalSeconds 20 -Name "Example Linux Disk Performance Counters"
## Enable the collection of performance counters from Linux computers
Enable-AzOperationalInsightsLinuxPerformanceCollection -ResourceGroupName $LogAnalyticsWorkspaceResourceGroupName -WorkspaceName $LogAnalyticsWorkspaceName
# Linux Syslog
## The below example will create a data source for the "kern" facility, with all severities being collected
New-AzOperationalInsightsLinuxSyslogDataSource -ResourceGroupName $LogAnalyticsWorkspaceResourceGroupName -WorkspaceName $LogAnalyticsWorkspaceName -Facility "kern" -CollectEmergency -CollectAlert -CollectCritical -CollectError -CollectWarning -CollectNotice -CollectInfo -CollectDebug -Name "Example kernel Syslog collection"
## Enable the collection of Syslog data from Linux computers
Enable-AzOperationalInsightsLinuxSyslogCollection -ResourceGroupName $LogAnalyticsWorkspaceResourceGroupName -WorkspaceName $LogAnalyticsWorkspaceName
Installing the extensions
Log in to the Azure Stack Hub portal.
Navigate to the VM that you want to enable Azure Monitor on and under Settings, select the Extensions blade.
Warning
For any monitoring to work correctly, the VM must have HTTPS (port 443) enabled in the Network Security Group rules.
Click Add at the top, select the extension Azure Monitor Dependency Agent, click Create and then OK.
Warning
Wait for the deployment to finish before continuing.
Click Add at the top, select the extension Azure Monitor, Update and Configuration Management and then click Create.
Execute the following PowerShell script to setup the Azure Monitor Dependency Agent and Azure Monitor, Update and Configuration Management extensions.
Declare variables
Enter details below to provide values for the variables in the following script in this article:
Variable name |
Variable description |
Input |
$VMName |
The name of the virtual machine |
|
$ResourceGroupName |
The name of the resource group which the VM resides in |
|
$NetworkSecurityGroupName |
The name of the network security group to apply the inbound port 443 rule to |
|
$WorkspaceKey |
The log analytics workspace primary key |
|
$WorkspaceId |
The log analytics workspace ID |
|
# Declare variables
$VMName = ""
$ResourceGroupName = ""
$NetworkSecurityGroupName = ""
$WorkspaceKey = ""
$WorkspaceId = ""
$PublicSettings = "{'workspaceId': `'$WorkspaceId`'}"
$ProtectedSettings = "{'workspaceKey': `'$WorkspaceKey`'}"
$Location = (Get-AzLocation).Location
# Get the virtual machine to apply the custom script extensions to
$VM = Get-AzVM -ResourceGroupName $ResourceGroupName -VMName $VMName
# Obtain network security group, create the port 443 inbound network security group rule and apply the rule to it
Get-AzNetworkSecurityGroup -Name $NetworkSecurityGroupName -ResourceGroupName $ResourceGroupName | New-AzNetworkSecurityRuleConfig -Name "Port443-Rule" -Description "Allow port 443" -Access "Allow" -Protocol "TCP" -Direction "Inbound" -Priority 100 -DestinationPortRange 443 -SourceAddressPrefix "*" -SourcePortRange "*" -DestinationAddressPrefix "*" | Set-AzNetworkSecurityGroup
# Determine if VM is Windows or Linux based
if ($VM.OsProfile.WindowsConfiguration) {
$DependencyAgentType = "DependencyAgentWindows"
$DependencyAgentVersion = "9.10"
$MonitoringAgentType = "MicrosoftMonitoringAgent"
$MonitoringAgentVersion = "1.0"
}
else {
$DependencyAgentType = "DependencyAgentLinux"
$DependencyAgentVersion = "9.10"
$MonitoringAgentType = "OmsAgentForLinux"
$MonitoringAgentVersion = "1.13"
}
# Deploy DependencyAgent extension
Set-AzVMExtension -ExtensionName "DependencyAgent" `
-ResourceGroupName $VM.ResourceGroupName `
-VMName $VM.Name `
-Location $Location `
-Publisher "Microsoft.Azure.Monitoring.DependencyAgent" `
-ExtensionType $DependencyAgentType `
-TypeHandlerVersion $DependencyAgentVersion `
-Verbose
# Deploy Microsoft.EnterpriseCloud.Monitoring extension
Set-AzVMExtension -ExtensionName "Microsoft.EnterpriseCloud.Monitoring" `
-ResourceGroupName $VM.ResourceGroupName `
-VMName $VM.Name `
-Location $Location `
-Publisher "Microsoft.EnterpriseCloud.Monitoring" `
-ExtensionType $MonitoringAgentType `
-TypeHandlerVersion $MonitoringAgentVersion `
-SettingString $PublicSettings `
-ProtectedSettingString $ProtectedSettings `
-Verbose
Configuring the Log Analytics Workspace
In public Azure, select Monitor from the favourites menu on the left.

In the new blade under Insights, click Virtual Machines.
You will see three usage analytics tabs (Get Started, Performance and Map) for the VMs you have enabled Azure Monitor for VMs on.
Caution
The Get Started tab does not show Azure Stack Hub VMs.

At the top, click the Performance tab, then on the right, move the switch from Azure to Hybrid:

A prompt will appear to upgrade the workspace, click Upgrade. In the new blade, click Upgrade again.
Upon refreshing the page, the prompt will disappear and the workspace will begin showing usage analytics for the VMs you've enabled Azure Monitor for VMs on.
Note
It can take between 30 minutes and 6 hours for the dashboard to display updated data from Azure Monitor enabled VMs.


Executing Kusto Query Language (KQL) queries to retrieve data from the Log Analytics Workspace
Navigate to the Log Analytics Workspace you created.
Under General, click Logs.
Enter the KQL query in the New Query 1 tab, then click Run.
The below example will select data from the event log table Event
, filtering for events of type System
and containing the phrase was unexpected
, then sorted by the TimeGenerated
field in descending order.

# Declare KQL query
## The below example will select data from the event log table "Event", filtering for events of type "System" and containing the phrase "was unexpected", then sorted by the "TimeGenerated" field in descending order
$Query = 'Event | where EventLog == "System" | search "was unexpected" | sort by TimeGenerated desc'
# Execute the KQL query and obtain the results
$QueryResults = Invoke-AzOperationalInsightsQuery -WorkspaceId $WorkspaceId -Query $Query -Timespan "$(New-TimeSpan -Hours 48)"
# Convert the results to a PowerShell array object
$ResultsArray = [System.Linq.Enumerable]::ToArray($QueryResults.Results)
# Print the array
$ResultsArray
Feedback
If you find a problem with this article, click Improve this Doc to make the change yourself or raise an issue in GitHub. If you have an idea for how we could improve any of our services, send an email to feedback@ukcloud.com.