Framework/Configurations/ContinuousAssurance/RunbookScanAgent.ps1
|
#telemetry functions function CreateHelperSchedule($frequencyInMinutes) { #create next run schedule Get-AzureRmAutomationSchedule -AutomationAccountName $AutomationAccountName ` -ResourceGroupName $AutomationAccountRG -Name $CAHelperScheduleName -ErrorAction SilentlyContinue | Remove-AzureRmAutomationSchedule -Force New-AzureRmAutomationSchedule -AutomationAccountName $AutomationAccountName -Name $CAHelperScheduleName ` -ResourceGroupName $AutomationAccountRG -StartTime $(get-date).AddMinutes($frequencyInMinutes) ` -OneTime -ErrorAction Stop | Out-Null Register-AzureRmAutomationScheduledRunbook -RunbookName $RunbookName -ScheduleName $CAHelperScheduleName ` -ResourceGroupName $AutomationAccountRG ` -AutomationAccountName $AutomationAccountName -ErrorAction Stop | Out-Null } function ConvertStringToBoolean($strToConvert) { switch($strToConvert) { "true" {return $true} "false" {return $false} } return $false #adding this to prevent error all path doesn't return value" } function GetCAStatus() { Set-AzSDKOMSSettings -OMSWorkspaceID $OMSWorkspaceId -OMSSharedKey $OMSWorkspaceSharedKey -Source "CC" #set values in azsdksettings.json $EnableAADAuthForOnlinePolicyStore = ConvertStringToBoolean($EnableAADAuthForOnlinePolicyStore) if($EnableAADAuthForOnlinePolicyStore) { Set-AzSDKPolicySettings -OnlinePolicyStoreUrl $OnlinePolicyStoreUrl -EnableAADAuthForOnlinePolicyStore } else { Set-AzSDKPolicySettings -OnlinePolicyStoreUrl $OnlinePolicyStoreUrl } $svtResultPath = [string]::Empty $subscriptionResultPath = [string]::Empty $parentFolderPath = [string]::Empty PublishEvent -EventName "Job Scan Started" ` -Properties @{"ResourceGroupNames"=$ResourceGroupNames;"OnlinePolicyStoreUrl"=$OnlinePolicyStoreUrl;"OMSWorkspaceId"=$OMSWorkspaceId;` "AzureADAppId"=$RunAsConnection.ApplicationId} "Running command 'Get-AzSDKSubscriptionSecurityStatus'" $subscriptionResultPath = Get-AzSDKSubscriptionSecurityStatus -SubscriptionId $SubscriptionID -ExcludeTags "OwnerAccess" "Running command 'Get-AzSDKAzureServicesSecurityStatus'" if($ResourceGroupNames.Trim() -eq "*") { #run command on all resources $svtResultPath = Get-AzSDKAzureServicesSecurityStatus -SubscriptionId $SubscriptionID -ExcludeTags "OwnerAccess" } else { $svtResultPath = Get-AzSDKAzureServicesSecurityStatus -SubscriptionId $SubscriptionID -ResourceGroupNames $ResourceGroupNames -ExcludeTags "OwnerAccess" } if([string]::IsNullOrWhiteSpace($subscriptionResultPath)) { "Subscription scan failed." PublishEvent -EventName "Scan Error" -Properties @{"ScanEntity"="Subscription"} ` -Metrics @{"SuccessCount"=0} } else { "Subscription scan succeeded." $parentFolderPath = (Get-Item $subscriptionResultPath).parent.FullName PublishEvent -EventName "Scan Completed" -Properties @{"ScanEntity"="Subscription"} ` -Metrics @{"SuccessCount"=1} } if([string]::IsNullOrWhiteSpace($svtResultPath)) { "Azure resources scan failed." PublishEvent -EventName "Scan Error" -Properties @{"ScanEntity"="Resources";"ResourceGroupNames"=$ResourceGroupNames} ` -Metrics @{"SuccessCount"=0} } else { "Azure resources scan succeeded." $parentFolderPath = (Get-Item $svtResultPath).parent.FullName PublishEvent -EventName "Scan Completed" -Properties @{"ScanEntity"="Resources";"ResourceGroupNames"=$ResourceGroupNames} ` -Metrics @{"SuccessCount"=1} } if(![string]::IsNullOrWhiteSpace($subscriptionResultPath) -or ![string]::IsNullOrWhiteSpace($svtResultPath)) { #Check if storage account exists try { Get-AzureRmStorageAccount -ResourceGroupName $StorageAccountRG -Name $StorageAccountName -ErrorAction stop | Out-Null } catch { Write-Error -Message $_.Exception throw $_.Exception } #Create output files in storage $containerName = "azsdkexecutionlogs" $archiveFilePath = "$parentFolderPath\AutomationLogs_" + $(Get-Date -format "yyyyMMdd_HHmmss") + ".zip" $keys = Get-AzureRmStorageAccountKey -ResourceGroupName $StorageAccountRG -Name $StorageAccountName $currentContext = New-AzureStorageContext -StorageAccountName $StorageAccountName -StorageAccountKey $keys[0].Value -Protocol Https try { Get-AzureStorageContainer -Name $containerName -Context $currentContext -ErrorAction Stop | Out-Null } catch { New-AzureStorageContainer -Name $containerName -Context $currentContext | Out-Null } try { if(![string]::IsNullOrWhiteSpace($svtResultPath)) { Compress-Archive -Path $svtResultPath -CompressionLevel Optimal -DestinationPath $archiveFilePath -Update } if(![string]::IsNullOrWhiteSpace($subscriptionResultPath)) { Compress-Archive -Path $subscriptionResultPath -CompressionLevel Optimal -DestinationPath $archiveFilePath -Update } Set-AzureStorageBlobContent -File $archiveFilePath -Container $containerName -Context $currentContext -ErrorAction Stop | Out-Null "Exported reports to storage $StorageAccountName" PublishEvent -EventName "Reports Persisted" -Properties @{"SuccessCount"=1} } catch { "Could not export reports to storage $StorageAccountName" PublishEvent -EventName "Reports Persist Error" -Properties @{"SuccessCount"=0} throw $_.Exception } #clean-up of logs in automation sandbox if(![string]::IsNullOrWhiteSpace($svtResultPath)) { Remove-Item -Path $svtResultPath -Recurse -ErrorAction Ignore } if(![string]::IsNullOrWhiteSpace($subscriptionResultPath)) { Remove-Item -Path $subscriptionResultPath -Recurse -ErrorAction Ignore } if(![string]::IsNullOrWhiteSpace($archiveFilePath)) { Remove-Item -Path $archiveFilePath -Recurse -ErrorAction Ignore } } } try { #config start $ResourceGroupNames = Get-AutomationVariable -Name "AppResourceGroupNames" $OMSWorkspaceId = Get-AutomationVariable -Name "OMSWorkspaceId" $OMSWorkspaceSharedKey = Get-AutomationVariable -Name "OMSSharedKey" $StorageAccountName = Get-AutomationVariable -Name "ReportsStorageAccountName" $AzSDKModuleName = "AzSDKStaging" $StorageAccountRG = "AzSDKRG" $RunbookName = "Continuous_Assurance_Runbook" $CAHelperScheduleName = "CA_Helper_Schedule" #config end #Set subscription id $SubscriptionID = $RunAsConnection.SubscriptionID $isAzSDKAvailable = (Get-AzureRmAutomationModule -ResourceGroupName $AutomationAccountRG ` -AutomationAccountName $AutomationAccountName ` -Name $AzSDKModuleName -ErrorAction SilentlyContinue | ` Where-Object {$_.ProvisioningState -eq "Succeeded" -or $_.ProvisioningState -eq "Created"} | ` Measure-Object).Count -gt 0 if($isAzSDKAvailable) { Import-Module $AzSDKModuleName } #check if AzureRM is available (for scenario where AzSDK is available but AzureRM extraction might have failed) $isAzureRMAvailable = (Get-AzureRmAutomationModule -ResourceGroupName $AutomationAccountRG ` -AutomationAccountName $AutomationAccountName ` -Name AzureRM -ErrorAction SilentlyContinue | ` Where-Object {$_.ProvisioningState -eq "Succeeded" -or $_.ProvisioningState -eq "Created"} | ` Measure-Object).Count -gt 0 #return if modules are not ready if((Get-Command -Name "Get-AzSDKAzureServicesSecurityStatus" -ErrorAction SilentlyContinue|Measure-Object).Count -eq 0 -or !$isAzureRMAvailable) { return; } #scan and save results to storage GetCAStatus #helper schedule not needed anymore Remove-AzureRmAutomationSchedule -Name $CAHelperScheduleName -ResourceGroupName $AutomationAccountRG -AutomationAccountName $AutomationAccountName -Force PublishEvent -EventName "Job Completed" -Properties @{"SubscriptionId"=$RunAsConnection.SubscriptionID} -Metrics @{"TimeTakenInMs" = $timer.ElapsedMilliseconds;"SuccessCount" = 1} } catch { PublishEvent -EventName "Job Error" -Properties @{"ErrorRecord"= $_.Exception.InnerException.ErrorRecord} -Metrics @{"TimeTakenInMs" = $timer.ElapsedMilliseconds;"SuccessCount" = 0} } |