Framework/Core/SubscriptionSecurity/SecurityCenter.ps1
using namespace System.Management.Automation Set-StrictMode -Version Latest class SecurityCenter: AzSdkRoot { [PSObject] $Policy = $null; [string] $Off = "Off"; [string] $On = "On"; SecurityCenter([string] $subscriptionId): Base($subscriptionId) { $this.Policy = $this.LoadServerConfigFile("SecurityCenter.json"); } [PSObject[]] GetMisconfiguredPolicies() { $misConfiguredPolicies = @(); $allPolicies = @(); $allPolicies += [SecurityCenterHelper]::InvokeGetSecurityCenterRequest($this.SubscriptionContext.SubscriptionId, [SecurityCenterHelper]::PoliciesApi) if($allPolicies.Count -ne 0) { #Query to select only subscription level polices and other polices which are modified explicitly $uniquePolicies = @(); $uniquePolicies += $allPolicies | Where-Object { [Helpers]::CheckMember($_, "properties.policyLevel") -and ($_.properties.policyLevel -eq "Subscription" -or $_.properties.unique -eq $this.On ) }; if($uniquePolicies.Count -ne 0) { #If recommendations object is kept blank in Policy json, consider to check all properties to be 'On' #Check with get-member here if(($this.Policy.properties.recommendations | Get-Member -MemberType Properties | Measure-Object).Count -eq 0) { #Pick first object and add all recommendation property to policy json object $samplePolicy = $allPolicies | Select-Object -First 1 if([Helpers]::CheckMember($samplePolicy, "properties.recommendations")) { $samplePolicy.properties.recommendations | Get-Member -MemberType Properties | ForEach-Object { Add-Member -InputObject $this.Policy.properties.recommendations -MemberType NoteProperty -Name $_.Name -Value $this.On } } } $uniquePolicies | ForEach-Object { $isMisconfigured = $true; if([Helpers]::CompareObject($this.Policy.properties, $_.properties)) { # Check for email address and phone nnumber props if([Helpers]::CheckMember($_, "properties.securityContactConfiguration.securityContactEmails") -and -not [string]::IsNullOrEmpty($_.properties.securityContactConfiguration.securityContactEmails) -and [Helpers]::CheckMember($_, "properties.securityContactConfiguration.securityContactPhone") -and -not [string]::IsNullOrEmpty($_.properties.securityContactConfiguration.securityContactPhone)) { $isMisconfigured = $false } } if($isMisconfigured) { $misConfiguredPolicies += $_; } }; #$misConfiguredPolicies += $uniquePolicies | Where-Object { -not [Helpers]::CompareObject($this.Policy.properties, $_.properties) }; } else { #no relevant policies found message here $this.PublishCustomMessage("No Subscription level or uniquely configured policies found in the Security Center", [MessageType]::Warning); } } else { #Error message here $this.PublishCustomMessage("Not able to get the Security Center policies", [MessageType]::Error); } return $misConfiguredPolicies; } [MessageData[]] SetPolicies([string] $securityContactEmails, [string] $securityPhoneNumber) { [MessageData[]] $messages = @(); $misConfiguredPolicies = $this.GetMisconfiguredPolicies(); if($misConfiguredPolicies.Count -ne 0) { $messageText = "Found Security Center policies which are not correctly configured. Updating the policies. Total: $($misConfiguredPolicies.Count)"; $messages += [MessageData]::new("Security center policies must be configured with settings mentioned below:", $this.Policy.properties); $messages += [MessageData]::new($messageText, $misConfiguredPolicies); $this.PublishCustomMessage($messageText); #Keeping a copy of policy email addresses. The original policy object is going to update while merging email addresses $policyEmails = @(); if([Helpers]::CheckMember($this.Policy, "properties.securityContactConfiguration.securityContactEmails")) { $policyEmails += $this.Policy.properties.securityContactConfiguration.securityContactEmails; } $updateObject = $this.Policy | Select-Object -Property properties $misConfiguredPolicies | Where-Object { $_.properties.policyLevel -eq "Subscription" } | ForEach-Object { #Merge email addresses $allEmails = @(); # User provided email addresses $allEmails += $this.ConvertToStringArray($securityContactEmails); # Ignore existing email addresses if user has provided any email addresses if($allEmails.Count -eq 0 -and $_.properties.securityContactConfiguration.securityContactEmails.Count -ne 0) { $allEmails += $_.properties.securityContactConfiguration.securityContactEmails | Where-Object { -not [string]::IsNullOrWhiteSpace($_) }; } # Add email addresses from policy files $allEmails += $policyEmails; $updateObject.properties.securityContactConfiguration.securityContactEmails = [array] ($allEmails | Select-Object -Unique) $policyName = ""; if([Helpers]::CheckMember($_, "name")) { $policyName = "[$($_.name)]"; } $exceptionMessage = ""; # Check if securityContactEmails is still null, then set it to blank array if(-not $updateObject.properties.securityContactConfiguration.securityContactEmails) { $exceptionMessage += "Please provide 'SecurityContactEmails' parameter in the command to set up security center policy $policyName`r`n"; $updateObject.properties.securityContactConfiguration.securityContactEmails = @(""); } $isPhoneRequired = $true; if([Helpers]::CheckMember($_, "properties.securityContactConfiguration.securityContactPhone")) { if(-not [string]::IsNullOrEmpty($_.properties.securityContactConfiguration.securityContactPhone)) { $isPhoneRequired = $false; } } if($isPhoneRequired -and [string]::IsNullOrWhiteSpace($securityPhoneNumber)) { $exceptionMessage += "Please provide 'SecurityPhoneNumber' parameter in the command to set up security center policy $policyName`r`n"; } if(-not [string]::IsNullOrWhiteSpace($exceptionMessage)) { throw $exceptionMessage; } # Set phone number if(-not [string]::IsNullOrWhiteSpace($securityPhoneNumber)) { Add-Member -InputObject $updateObject.properties.securityContactConfiguration -MemberType NoteProperty -Name "securityContactPhone" -Value $securityPhoneNumber } $messages += [MessageData]::new("Updating [$($_.properties.policyLevel)] level security center policy $policyName"); $response = [SecurityCenterHelper]::InvokePutSecurityCenterRequest($_.id, $updateObject); [MessageData] $resultMessage = $null if(($response | Measure-Object).Count -ne 0) { $resultMessage = [MessageData]::new("Successfully updated [$($_.properties.policyLevel)] level security center policy $policyName", [MessageType]::Update); } else { $resultMessage = [MessageData]::new("Not able to update [$($_.properties.policyLevel)] level security center policy $policyName", [MessageType]::Error); } $messages += $resultMessage; $this.PublishCustomMessage($resultMessage); } #Setting up the original values $this.Policy.properties.securityContactConfiguration.securityContactEmails = $policyEmails; $nonDefaultPolicies = $misConfiguredPolicies | Where-Object { $_.properties.unique -eq $this.On } | Select-Object -Property id, name if(($nonDefaultPolicies | Measure-Object).Count -ne 0) { $messageText = "Found policies at resource group level in overridden state. These policies have to be manually setup correctly. Total: $($nonDefaultPolicies.Count)"; $messages += [MessageData]::new($messageText + "`r`nBelow are the policies that have to be manually corrected: ", $nonDefaultPolicies); $this.PublishCustomMessage($messageText); } } else { $this.PublishCustomMessage("All security center policies are correctly configured. No changes are required."); } return $messages; } } |