Get-AzureVmManagementSolutionOnboardingState.ps1


<#PSScriptInfo
 
.VERSION 1.0.4
 
.GUID 3268e204-99af-4846-8aa6-1a210e011bce
 
.AUTHOR stasku
 
.COMPANYNAME Microsoft Corporation
 
.COPYRIGHT Microsoft Corporation
 
.TAGS Automation Management
 
.LICENSEURI
 
.PROJECTURI
 
.ICONURI
 
.EXTERNALMODULEDEPENDENCIES LogAnalyticsQuery.psm1
 
.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' }



<#
 
.DESCRIPTION
 The script gets management solution onboarding information for an Azure VM.
 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
)

$information = [pscustomobject] [ordered] @{
    #$information = New-Object -Type PSObject -Proper [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

        $vmMmaExtensionResourceId = "$($vmResourceId)/extensions/MMAExtension"
        $vmMmaExtensionDiscriminator = New-Object -Type PSObject -Proper @{'id'=$vmMmaExtensionResourceId}
        $vmMmaExtensionResource = $vmMmaExtensionDiscriminator | Get-AzureRmResource

        $information.AzureVMHasManagementExtensionInstalled = $false
        if($vmMmaExtensionResource -ne $null){
            $information.AzureVMHasManagementExtensionInstalled = $true

            $vmManagementWorkspaceId = $vmMmaExtensionResource.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'){
                        $queryVmHeartbeatDataIngestedIntoWorkspace = [String]::Format('Type=Heartbeat and (ResourceId="{0}" or Computer="{1}") | top 1', $vmResourceId, $vm.Name, $solutionType)
                        $information.VmHeartbeatDataIngestedIntoWorkspace = ($vmManagementWorkspace | Get-AzureRmOperationalInsightsSearchResults -Query $queryVmHeartbeatDataIngestedIntoWorkspace).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).Value.Count -eq 1
                    
                        $querySolutionDataIngestedIntoWorkspace = [String]::Format('Type={0} and Computer="{1}" | top 1', $solutionTableName, $vm.Name)
                        $information.SolutionDataIngestedIntoWorkspace = ($vmManagementWorkspace | Get-AzureRmOperationalInsightsSearchResults -Query $querySolutionDataIngestedIntoWorkspace).Value.Count -eq 1
                    }
                    elseif($vmManagementWorkspaceSearchVersion -eq 'KQL'){
                        $queryVmHeartbeatDataIngestedIntoWorkspace = [String]::Format('Heartbeat | where (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 (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 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