Get-AzureVmManagementSolutionOnboardingState.ps1
<#PSScriptInfo
.VERSION 1.0.0 .GUID 3268e204-99af-4846-8aa6-1a210e011bce .AUTHOR Stas Kuvshinov .COMPANYNAME Microsoft Corporation .COPYRIGHT Microsoft Corporation .TAGS Automation Management .LICENSEURI .PROJECTURI .ICONURI .EXTERNALMODULEDEPENDENCIES LogAnalyticsQuery .REQUIREDSCRIPTS .EXTERNALSCRIPTDEPENDENCIES .RELEASENOTES The LogAnalyticsQuery module is available on https://dev.loganalytics.io/documentation/Tools/PowerShell-Cmdlets .PRIVATEDATA #> #Requires -Module @{ ModuleName = 'AzureRM.Profile'; ModuleVersion = '3.1.0' } #Requires -Module @{ ModuleName = 'AzureRM.Compute'; ModuleVersion = '3.1.0' } #Requires -Module @{ ModuleName = 'AzureRM.Resources'; ModuleVersion = '3.1.0' } #Requires -Module @{ ModuleName = 'AzureRM.OperationalInsights'; ModuleVersion = '3.4.1' } <# .Parameter vmResourceId Required. Full resource identifier of an Azure VM .Parameter solutionType Required. Type of the management solution. Possible values: 'updates', 'changeTracking' .Parameter queryIntervalHours Optional. Query interval window in hours to use when looking for ingested data. (Default = 24) .EXAMPLE .\Get-AzureVmManagementSolutionOnboardingState.ps1 -vmResourceId /subscriptions/6c098ac2-6c43-4fd8-875c-6d089beb2ef5/resourceGroups/RG1/providers/Microsoft.Compute/virtualMachines/stas-ubuntu-1604-x -solutionType updates .EXAMPLE .\Get-AzureVmManagementSolutionOnboardingState.ps1 -vmResourceId /subscriptions/6c098ac2-6c43-4fd8-875c-6d089beb2ef5/resourceGroups/RG1/providers/Microsoft.Compute/virtualMachines/stas-ubuntu-1604-x -solutionType updates -queryIntervalHours 12 .Example .\Get-AzureVmManagementSolutionOnboardingState.ps1 -vmResourceId /subscriptions/6c098ac2-6c43-4fd8-875c-6d089beb2ef5/resourceGroups/RG1/providers/Microsoft.Compute/virtualMachines/ws-2012r2-a4 -solutionType changeTracking .DESCRIPTION The script gets management solution onboarding information for an Azure VM. Please run it in the authenticated Azure session with VM subscription selected - use the 'Login-AzureRmAccount' and 'Select-AzureRMSubscription' commands with required parameters. See the following docs for references: https://docs.microsoft.com/en-us/powershell/azure/authenticate-azureps https://docs.microsoft.com/en-us/powershell/azure/manage-subscriptions-azureps Most of the script dependencies are available at the PowerShell Gallery with the only exception of the LogAnalyticsQuery.psm1 module that you need to manually download from https://dev.loganalytics.io/documentation/Tools/PowerShell-Cmdlets. #> Param( [string] [Parameter(Mandatory = $true)] $vmResourceId, [string] [Parameter(Mandatory = $true)] [ValidateSet("updates", "changeTracking")] $solutionType, [int] [Parameter(Mandatory = $false)] $queryIntervalHours = 24 ) $information = [pscustomobject] [ordered] @{ 'AzureVMFound'=$false 'AzureVMHasManagementExtensionInstalled'='n/a' 'AzureVMManagementExtensionHasManagementWorkspaceInformation'='n/a' 'ManagementWorkspaceFoundInSubscription'='n/a' 'VmHeartbeatDataIngestedIntoWorkspace'='n/a' 'VmHeartbeatDataIndicatesThatVmHasSolutionEnabled'='n/a' 'SolutionDataIngestedIntoWorkspace'='n/a' } $vmDiscriminator = New-Object -Type PSObject -Proper @{'id'=$vmResourceId} $vm = $vmDiscriminator | Get-AzureRmResource if($vm -ne $null){ $information.AzureVMFound = $true $vmManagementExtensionResourceId = "$($vmResourceId)/extensions/MMAExtension" if($vm.Properties.osProfile.linuxConfiguration -ne $null){ $vmManagementExtensionResourceId = "$($vmResourceId)/extensions/OMSAgentLinuxExtension" } $vmManagementExtensionDiscriminator = New-Object -Type PSObject -Proper @{'id'=$vmManagementExtensionResourceId} $vmManagementExtensionResource = $vmManagementExtensionDiscriminator | Get-AzureRmResource $information.AzureVMHasManagementExtensionInstalled = $false if($vmManagementExtensionResource -ne $null){ $information.AzureVMHasManagementExtensionInstalled = $true $vmManagementWorkspaceId = $vmManagementExtensionResource.Properties.settings.workspaceId $information.AzureVMManagementExtensionHasManagementWorkspaceInformation = $false if($vmManagementWorkspaceId -ne $null){ $information.AzureVMManagementExtensionHasManagementWorkspaceInformation = $true $vmManagementWorkspace = Get-AzureRmOperationalInsightsWorkspace | where-object {$_.CustomerId -eq $vmManagementWorkspaceId} $information.ManagementWorkspaceFoundInSubscription = $false if($vmManagementWorkspace -ne $null){ $information.ManagementWorkspaceFoundInSubscription = $true $vmManagementWorkspaceResourceDiscriminator = New-Object -Type PSObject -Proper @{'id'=$vmManagementWorkspace.ResourceId} $vmManagementWorkspaceResource = $vmManagementWorkspaceResourceDiscriminator | Get-AzureRmResource $vmManagementWorkspaceSearchVersion = @{'0'='OQL';'1'='KQL'}[$vmManagementWorkspaceResource.Properties.features.searchVersion.ToString()] $queryVmHeartbeatDataIngestedIntoWorkspace = [String]::Format(@{ 'OQL'='Type=Heartbeat and (ResourceId="{0}" or Computer="{1}") | top 1' 'KQL'='Heartbeat | where (ResourceId=~"{0}" or Computer=~"{1}") | take 1' }[$vmManagementWorkspaceSearchVersion], $vmResourceId, $vm.Name, $solutionType) $solutionTableName = @{'updates'='Update';'changeTracking'='ConfigurationChange'}[$solutionType] if($vmManagementWorkspaceSearchVersion -eq 'OQL'){ $endDate = (get-date) $startDate = $endDate.AddHours(-1 * $queryIntervalHours) $queryVmHeartbeatDataIngestedIntoWorkspace = [String]::Format('Type=Heartbeat and (ResourceId="{0}" or Computer="{1}") | top 1', $vmResourceId, $vm.Name, $solutionType) $information.VmHeartbeatDataIngestedIntoWorkspace = ($vmManagementWorkspace | Get-AzureRmOperationalInsightsSearchResults -Query $queryVmHeartbeatDataIngestedIntoWorkspace -End $endDate -Start $startDate).Value.Count -eq 1 $queryVmHeartbeatDataIndicatesThatVmHasSolutionEnabled = [String]::Format('Type=Heartbeat and (ResourceId="{0}" or Computer="{1}") and Solutions:contains("{2}") | top 1', $vmResourceId, $vm.Name, $solutionType) $information.VmHeartbeatDataIndicatesThatVmHasSolutionEnabled = ($vmManagementWorkspace | Get-AzureRmOperationalInsightsSearchResults -Query $queryVmHeartbeatDataIndicatesThatVmHasSolutionEnabled -End $endDate -Start $startDate).Value.Count -eq 1 $querySolutionDataIngestedIntoWorkspace = [String]::Format('Type={0} and Computer="{1}" | top 1', $solutionTableName, $vm.Name) $information.SolutionDataIngestedIntoWorkspace = ($vmManagementWorkspace | Get-AzureRmOperationalInsightsSearchResults -Query $querySolutionDataIngestedIntoWorkspace -End $endDate -Start $startDate).Value.Count -eq 1 } elseif($vmManagementWorkspaceSearchVersion -eq 'KQL'){ if(-not (Get-Command Invoke-LogAnalyticsQuery -ErrorAction SilentlyContinue)) { Write-Error 'The VM is managed by a workspace with enhanced log analytics capabilities. Please, import the LogAnalyticsQuery module from https://dev.loganalytics.io/documentation/Tools/PowerShell-Cmdlets to verify if the solution data is being ingested into search.' return $information } $queryVmHeartbeatDataIngestedIntoWorkspace = [String]::Format('Heartbeat | where TimeGenerated > ago(24h) and (ResourceId=~"{0}" or Computer=~"{1}") | take 1', $vmResourceId, $vm.Name, $solutionType) $information.VmHeartbeatDataIngestedIntoWorkspace = (Invoke-LogAnalyticsQuery -WorkspaceName $vmManagementWorkspace.Name -ResourceGroup $vmManagementWorkspaceResource.ResourceGroupName -SubscriptionId $vmManagementWorkspaceResource.SubscriptionId -Query $queryVmHeartbeatDataIngestedIntoWorkspace).Results -ne $null $queryVmHeartbeatDataIndicatesThatVmHasSolutionEnabled = [String]::Format('Heartbeat | where TimeGenerated > ago(24h) and (ResourceId=~"{0}" or Computer=~"{1}") and Solutions has "{2}" | take 1', $vmResourceId, $vm.Name, $solutionType) $information.VmHeartbeatDataIndicatesThatVmHasSolutionEnabled = (Invoke-LogAnalyticsQuery -WorkspaceName $vmManagementWorkspace.Name -ResourceGroup $vmManagementWorkspaceResource.ResourceGroupName -SubscriptionId $vmManagementWorkspaceResource.SubscriptionId -Query $queryVmHeartbeatDataIndicatesThatVmHasSolutionEnabled).Results -ne $null $querySolutionDataIngestedIntoWorkspace = [String]::Format('{0} | where TimeGenerated > ago(24h) and Computer=~"{1}" | take 1', $solutionTableName, $vm.Name) $information.SolutionDataIngestedIntoWorkspace = (Invoke-LogAnalyticsQuery -WorkspaceName $vmManagementWorkspace.Name -ResourceGroup $vmManagementWorkspaceResource.ResourceGroupName -SubscriptionId $vmManagementWorkspaceResource.SubscriptionId -Query $querySolutionDataIngestedIntoWorkspace).Results -ne $null } } } } } return $information |