Framework/Core/AzureMonitoring/OMSMonitoring.ps1
Set-StrictMode -Version Latest class OMSMonitoring: AzSdkRoot { [string] $OMSSampleViewTemplateFilepath; [string] $OMSSearchesTemplateFilepath; [string] $OMSAlertsTemplateFilepath; [string] $OMSLocation; [string] $OMSResourceGroup; [string] $OMSWorkspaceName; [string] $ApplicationSubscriptionName OMSMonitoring([string] $_omsSubscriptionId,[string] $_omsResourceGroup,[string] $_omsWorkspaceName): Base([string] $_omsSubscriptionId) { #made offline $searchesTemplateFilepath = [ConfigurationHelper]::LoadModuleRawFile("AzSDK.AM.OMS.Searches.omsview"); $alertsTemplateFilepath = [ConfigurationHelper]::LoadModuleRawFile("AzSDK.AM.OMS.Alerts.omsview"); $sampleViewTemplateFilepath = [ConfigurationHelper]::LoadModuleRawFile("AzSDK.AM.OMS.SampleView.omsview"); $this.OMSResourceGroup = $_omsResourceGroup $this.OMSWorkspaceName = $_omsWorkspaceName $omsWorkSpaceInstance = Get-AzureRmOperationalInsightsWorkspace -Name $this.OMSWorkspaceName -ResourceGroupName $this.OMSResourceGroup if($null -eq $omsWorkSpaceInstance) { throw "Invalid OMS Workspace." } $locationInstance = Get-AzureRmLocation | Where-Object { $_.DisplayName -eq $omsWorkSpaceInstance.Location -or $_.Location -eq $omsWorkSpaceInstance.Location } $this.OMSLocation = $locationInstance.Location $OMSLogPath = [Constants]::AzSdkTempFolderPath + "\OMS"; if(-not (Test-Path -Path $OMSLogPath)) { mkdir -Path $OMSLogPath -Force | Out-Null } $this.OMSSearchesTemplateFilepath = $OMSLogPath+"\AzSDK.AM.OMS.Searches.omsview"; $this.OMSAlertsTemplateFilepath = $OMSLogPath+"\AzSDK.AM.OMS.Alerts.omsview"; $this.OMSSampleViewTemplateFilepath = $OMSLogPath+"\AzSDK.AM.OMS.SampleView.omsview"; $searchesTemplateFilepath | Out-File $this.OMSSearchesTemplateFilepath $alertsTemplateFilepath | Out-File $this.OMSAlertsTemplateFilepath $sampleViewTemplateFilepath | Out-File $this.OMSSampleViewTemplateFilepath } [void] ConfigureOMS([string] $_applicationSubscriptionId,[string] $_applicationResourceGroups,[string] $_applicationName,[string] $_securityContactEmails,[OMSInstallationOption] $_omsInstallationOption, [bool] $_validateOnly) { $OptionalParameters = New-Object -TypeName Hashtable #the default installation option is All if($null -eq $_omsInstallationOption) { $OMSInstallationOption = [OMSInstallationOption]::All } $appSub = Get-AzureRmSubscription -SubscriptionId $_applicationSubscriptionId $this.ApplicationSubscriptionName = $appSub.Name if([OMSInstallationOption]::All -eq $_omsInstallationOption -or [OMSInstallationOption]::Queries -eq $_omsInstallationOption) { $this.ConfigureSearches($_validateOnly); } if([OMSInstallationOption]::All -eq $_omsInstallationOption -or [OMSInstallationOption]::Alerts -eq $_omsInstallationOption) { $this.ConfigureAlerts($_applicationName, $_securityContactEmails, $_validateOnly); } if([OMSInstallationOption]::All -eq $_omsInstallationOption -or [OMSInstallationOption]::SampleView -eq $_omsInstallationOption) { $this.ConfigureSampleView($_applicationName, $_applicationResourceGroups, $_validateOnly); } } [void] ConfigureSampleView([string] $_applicationName, [string] $_applicationResourceGroups, [bool] $_validateOnly) { $OptionalParameters = New-Object -TypeName Hashtable $_query = $this.GetOMSAppQuery($_applicationResourceGroups); $OptionalParameters = $this.GetOMSSampleViewParameters($_applicationName, $_query); $ErrorMessages = @() if ($_validateOnly) { $ErrorMessages =@() Test-AzureRmResourceGroupDeployment -ResourceGroupName $this.OMSResourceGroup ` -TemplateFile $this.OMSSampleViewTemplateFilepath ` -TemplateParameterObject $OptionalParameters -Verbose } else { $ErrorMessages =@() $SubErrorMessages = @() New-AzureRmResourceGroupDeployment -Name ((Get-ChildItem $this.OMSSampleViewTemplateFilepath).BaseName + '-' + ((Get-Date).ToUniversalTime()).ToString('MMdd-HHmm')) ` -ResourceGroupName $this.OMSResourceGroup ` -TemplateFile $this.OMSSampleViewTemplateFilepath ` -TemplateParameterObject $OptionalParameters ` -Verbose -Force -ErrorVariable SubErrorMessages $SubErrorMessages = $SubErrorMessages | ForEach-Object { $_.Exception.Message.TrimEnd("`r`n") } $ErrorMessages += $SubErrorMessages } if ($ErrorMessages) { "", ("{0} returned the following errors:" -f ("Template deployment", "Validation")[[bool]$_validateOnly]), @($ErrorMessages) | ForEach-Object { $this.PublishCustomMessage([MessageData]::new($_));} } } [void] ConfigureSearches([bool] $_validateOnly) { $OptionalParameters = New-Object -TypeName Hashtable $savedSearches = Get-AzureRmOperationalInsightsSavedSearch -ResourceGroupName $this.OMSResourceGroup -WorkspaceName $this.OMSWorkspaceName $azSdkSearches = @() if($savedSearches -ne $null -and $savedSearches.Value -ne $null) { $savedSearches.Value | %{ Set-Variable -Name savedSearch -Value $_ if($savedSearch.Properties -ne $null -and $savedSearch.Properties.Category -like "AzSDK_Searches*") { $azSdkSearches += $savedSearch } } } if($azSdkSearches.Length -gt 0) { return; } $OptionalParameters = $this.GetOMSBaseParameters(); $ErrorMessages = @() if ($_validateOnly) { $ErrorMessages =@() Test-AzureRmResourceGroupDeployment -ResourceGroupName $this.OMSResourceGroup ` -TemplateFile $this.OMSSearchesTemplateFilepath ` -TemplateParameterObject $OptionalParameters -Verbose } else { $ErrorMessages =@() $SubErrorMessages = @() New-AzureRmResourceGroupDeployment -Name ((Get-ChildItem $this.OMSSearchesTemplateFilepath).BaseName + '-' + ((Get-Date).ToUniversalTime()).ToString('MMdd-HHmm')) ` -ResourceGroupName $this.OMSResourceGroup ` -TemplateFile $this.OMSSearchesTemplateFilepath ` -TemplateParameterObject $OptionalParameters ` -Verbose -Force -ErrorVariable SubErrorMessages $SubErrorMessages = $SubErrorMessages | ForEach-Object { $_.Exception.Message.TrimEnd("`r`n") } $ErrorMessages += $SubErrorMessages } if ($ErrorMessages) { "", ("{0} returned the following errors:" -f ("Template deployment", "Validation")[[bool] $_validateOnly]), @($ErrorMessages) | ForEach-Object { $this.PublishCustomMessage([MessageData]::new($_));} } } [void] ConfigureAlerts([string] $_applicationName, [string] $_alertemails, [bool] $_validateOnly) { $OptionalParameters = New-Object -TypeName Hashtable $OptionalParameters = $this.GetOMSAlertParameters($_applicationName, $_alertemails); $ErrorMessages = @() if ($_validateOnly) { $ErrorMessages =@() Test-AzureRmResourceGroupDeployment -ResourceGroupName $this.OMSResourceGroup ` -TemplateFile $this.OMSAlertsTemplateFilepath ` -TemplateParameterObject $OptionalParameters -Verbose } else { $ErrorMessages =@() $SubErrorMessages = @() New-AzureRmResourceGroupDeployment -Name ((Get-ChildItem $this.OMSAlertsTemplateFilepath).BaseName + '-' + ((Get-Date).ToUniversalTime()).ToString('MMdd-HHmm')) ` -ResourceGroupName $this.OMSResourceGroup ` -TemplateFile $this.OMSAlertsTemplateFilepath ` -TemplateParameterObject $OptionalParameters ` -Verbose -Force -ErrorVariable SubErrorMessages $SubErrorMessages = $SubErrorMessages | ForEach-Object { $_.Exception.Message.TrimEnd("`r`n") } $ErrorMessages += $SubErrorMessages } if ($ErrorMessages) { "", ("{0} returned the following errors:" -f ("Template deployment", "Validation")[[bool]$_validateOnly]), @($ErrorMessages) | ForEach-Object { $this.PublishCustomMessage([MessageData]::new($_));} } } [void] UninstallOMSPack() { $this.PublishCustomMessage("Started Clean up of OMS Security Solution pack"); #Get all the searches with the name of AzSDK $savedSearches = Get-AzureRmOperationalInsightsSavedSearch -ResourceGroupName $this.OMSResourceGroup -WorkspaceName $this.OMSWorkspaceName $azSdkSearches = @() if($savedSearches -ne $null -and $savedSearches.Value -ne $null) { $savedSearches.Value | %{ Set-Variable -Name savedSearch -Value $_ if($savedSearch.Properties -ne $null -and $savedSearch.Properties.Category -like "*AzSDK*") { $azSdkSearches += $savedSearch } } } $RequestURI= [Constants]::OMSRequestURI $accessToken = [Helpers]::GetAccessToken([Constants]::ARMManagementUri); $header = "Bearer " + $accessToken $headers = @{"Authorization"=$header;"Content-Type"="application/json"} $schedules = $null $azSdkSearches | %{ Set-Variable -Name azSdkSearch -Value $_ $azSdkSearchId = $azSdkSearch.Id.Replace($azSdkSearch.Properties.DisplayName.ToLower(),$azSdkSearch.Properties.DisplayName) Set-Variable -Name scheduleURI $scheduleURI = ($RequestURI -f ($azSdkSearchId +"/schedules")) #Get all the Schedules configured using this search $result = "" $err = $null; try { $result = Invoke-WebRequest -Method GET -Uri $scheduleURI -Headers $headers } catch{ $err = $_ } if($result.StatusCode -ge 200 -and $result.StatusCode -le 399){ if($result.Content -ne $null){ $json = (ConvertFrom-Json $result.Content) if($json -ne $null){ $schedules = $json if($json.value -ne $null) { $schedules = $json.value } } } } if($err -ne $null) { if($err.ErrorDetails.Message -ne $null){ $json = (ConvertFrom-Json $err.ErrorDetails.Message) if($json -ne $null){ $return = $json if($json.'odata.error'.code -eq "Request_ResourceNotFound") { $return = $json.'odata.error'.message } } } return $null } $actions = $null; #Get AlertActions if($schedules -ne $null) { $schedules | %{ Set-Variable -Name schedule -Value $_ Set-Variable -Name actionsURI if(Get-Member -InputObject $schedule -Name id) { $actionsURI = ($RequestURI -f ($schedule.Id +"/Actions")) #Get all the actions configured using this search $result = "" $err = $null; try { $result = Invoke-WebRequest -Method GET -Uri $actionsURI -Headers $headers } catch{ $err = $_ } if($result.StatusCode -ge 200 -and $result.StatusCode -le 399){ if($result.Content -ne $null){ $json = (ConvertFrom-Json $result.Content) if($json -ne $null){ $actions = $json if($json.value -ne $null) { $actions = $json.value } } } } if($err -ne $null) { if($err.ErrorDetails.Message -ne $null){ $json = (ConvertFrom-Json $err.ErrorDetails.Message) if($json -ne $null){ $return = $json if($json.'odata.error'.code -eq "Request_ResourceNotFound") { $return = $json.'odata.error'.message } } } return $null } if($actions -ne $null) { $actions | %{ Set-Variable -Name action -Value $_ if(Get-Member -InputObject $actions -Name name) { $subValues = $action.name.Split("|",[StringSplitOptions]::RemoveEmptyEntries) if($subValues.Length -gt 0) { $actionid = $subValues[$subValues.Length-1] Set-Variable -Name actionURI $actionURI = ($RequestURI -f ($schedule.Id+"/Actions/"+$actionid)) #Get all the actions configured using this search $result = "" $err = $null; try { $result = Invoke-WebRequest -Method DELETE -Uri $actionURI -Headers $headers $this.PublishCustomMessage($action.Id + " : Deleted") } catch{ $err = $_ } if($result.StatusCode -ge 200 -and $result.StatusCode -le 399){ if($result.Content -ne $null){ $json = (ConvertFrom-Json $result.Content) if($json -ne $null){ $actions = $json if($json.value -ne $null) { $actions = $json.value } } } } if($err -ne $null) { if($err.ErrorDetails.Message -ne $null){ $json = (ConvertFrom-Json $err.ErrorDetails.Message) if($json -ne $null){ $return = $json if($json.'odata.error'.code -eq "Request_ResourceNotFound") { $return = $json.'odata.error'.message } } } return $null } } } #TODO Message } } #clean up schedule Set-Variable -Name scheduleURI $scheduleURI = ($RequestURI -f $schedule.Id) #Get all the actions configured using this search $result = "" try { $result = Invoke-WebRequest -Method DELETE -Uri $scheduleURI -Headers $headers $this.PublishCustomMessage($schedule.Id + " : Deleted") } catch{ $err = $_ } if($result.StatusCode -ge 200 -and $result.StatusCode -le 399){ if($result.Content -ne $null){ $json = (ConvertFrom-Json $result.Content) if($json -ne $null){ $actions = $json if($json.value -ne $null) { $actions = $json.value } } } } if($err -ne $null) { if($err.ErrorDetails.Message -ne $null){ $json = (ConvertFrom-Json $err.ErrorDetails.Message) if($json -ne $null){ $return = $json if($json.'odata.error'.code -eq "Request_ResourceNotFound") { $return = $json.'odata.error'.message } } } return $null } } } } #Done cleaning up all the schedules and actions } #Finally remove the saved search $azSdkSearches | ForEach-Object { $tempAzSDKSearch = $_; Remove-AzureRmOperationalInsightsSavedSearch -ResourceGroupName $this.OMSResourceGroup -WorkspaceName $this.OMSWorkspaceName -SavedSearchId $tempAzSDKSearch.Properties.DisplayName $this.PublishCustomMessage($tempAzSDKSearch.Id + " : Deleted"); } $this.PublishCustomMessage("Completed clean up of OMS Security Solution pack."); } [Hashtable] GetOMSBaseParameters() { [Hashtable] $omsParams = @{}; $omsParams.Add("omsWorkspaceLocation",$this.OMSLocation); $omsParams.Add("omsResourcegroup",$this.OMSResourceGroup); $omsParams.Add("omsSubscriptionId",$this.SubscriptionContext.SubscriptionId); $omsParams.Add("omsWorkspaceName",$this.OMSWorkspaceName); return $omsParams; } [Hashtable] GetOMSAlertParameters([string] $_applicationName, [string] $_alertemails) { $uniqueID = (Get-Date).ToUniversalTime().ToString("yyyyMMddHHmmss"); $emailList = $_alertemails.Split(",",[StringSplitOptions]::RemoveEmptyEntries) [Hashtable] $omsParams = $this.GetOMSBaseParameters(); $omsParams.Add("alertEmailsPointOfContact",$emailList); $omsParams.Add("appName",$_applicationName); $omsParams.Add("uniqueId",$uniqueID); $omsParams.Add("applicationSubscriptionName",$this.ApplicationSubscriptionName); return $omsParams; } [Hashtable] GetOMSSampleViewParameters([string] $_applicationName,[string] $_query) { [Hashtable] $omsParams = $this.GetOMSBaseParameters(); $omsParams.Add("appName",$_applicationName); $omsParams.Add("query",$_query); $omsParams.Add("applicationSubscriptionName",$this.ApplicationSubscriptionName); return $omsParams; } [string] GetOMSAppQuery([string] $_resourceGroups) { $rgQueryFormat = "ResourceGroup=""{0 }""" $queryOutput = "" $resourceGroupList = $_resourceGroups.Split(',',[StringSplitOptions]::RemoveEmptyEntries); if($resourceGroupList.Length -gt 0) { $resourceGroupList | ForEach-Object { if([string]::IsNullOrWhiteSpace($queryOutput)) { $queryOutput = $rgQueryFormat -f $_ } else { $queryOutput += " OR " + [string]::Format($rgQueryFormat, $_); } } } return $queryOutput; } } |