Framework/Core/SVT/ServicesSecurityStatus.ps1
Set-StrictMode -Version Latest class ServicesSecurityStatus: SVTCommandBase { [SVTResourceResolver] $Resolver = $null; ServicesSecurityStatus([string] $subscriptionId, [InvocationInfo] $invocationContext, [SVTResourceResolver] $resolver): Base($subscriptionId, $invocationContext) { if(-not $resolver) { throw [System.ArgumentException] ("The argument 'resolver' is null"); } $this.Resolver = $resolver; $this.Resolver.LoadAzureResources(); #BaseLineControlFilter with control ids $this.UsePartialCommits =$invocationContext.BoundParameters["UsePartialCommits"]; $this.UseBaselineControls = $invocationContext.BoundParameters["UseBaselineControls"]; $this.BaselineFilterCheck(); $this.UsePartialCommitsCheck(); } hidden [SVTEventContext[]] RunAllControls() { [SVTEventContext[]] $result = @(); $this.PublishCustomMessage("Number of resources: $($this.Resolver.SVTResources.Count)"); $nonAutomatedResources = @(); $nonAutomatedResources += ($this.Resolver.SVTResources | Where-Object { $null -eq $_.ResourceTypeMapping }); $automatedResources = @(); $automatedResources += ($this.Resolver.SVTResources | Where-Object { $_.ResourceTypeMapping }); $this.PublishCustomMessage("Number of resources for which security controls will be evaluated: $($automatedResources.Count)"); if($nonAutomatedResources.Count -gt 0) { $this.PublishCustomMessage("Number of resources for which security controls will NOT be evaluated: $($nonAutomatedResources.Count)", [MessageType]::Warning); $nonAutomatedResTypes = [array] ($nonAutomatedResources | Select-Object -Property ResourceType -Unique); $this.PublishCustomMessage([MessageData]::new("Security controls are yet to be automated for the following service types: ", $nonAutomatedResTypes)); $this.PublishAzSdkRootEvent([AzSdkRootEvent]::UnsupportedResources, $nonAutomatedResources); } $totalResources = $automatedResources.Count; [int] $currentCount = 0; $automatedResources | ForEach-Object { $exceptionMessage = "Exception for resource: [ResourceType: $($_.ResourceTypeMapping.ResourceTypeName)] [ResourceGroupName: $($_.ResourceGroupName)] [ResourceName: $($_.ResourceName)]" try { $currentCount += 1; if($totalResources -gt 1) { $this.PublishCustomMessage(" `r`nChecking resource [$currentCount/$totalResources] "); } $svtClassName = $_.ResourceTypeMapping.ClassName; $svtObject = $null; try { $svtObject = New-Object -TypeName $svtClassName -ArgumentList $this.SubscriptionContext.SubscriptionId, $_ } catch { $this.PublishCustomMessage($exceptionMessage); # Unwrapping the first layer of exception which is added by New-Object function $this.CommandError($_.Exception.InnerException.ErrorRecord); } if($svtObject) { $this.SetSVTBaseProperties($svtObject); $result += $svtObject.EvaluateAllControls(); } # Register/Deregister all listeners to cleanup the memory [ListenerHelper]::RegisterListeners(); } catch { $this.PublishCustomMessage($exceptionMessage); $this.CommandError($_); } } return $result; } #BaseLineControlFilter Function [void] BaselineFilterCheck() { #Load ControlSetting Resource Types and Filter resources $scanSource = [AzSdkSettings]::GetInstance().GetScanSource(); #Load ControlSetting Resource Types and Filter resources [ControlBaselineManager] $controlBaselineMngr = [ControlBaselineManager]::GetInstance(); $baselineControlsDetails = $controlBaselineMngr.GetBaselineControlDetails() #If Scan source is in suported sources or baselineControls switch is available if ($null -ne $baselineControlsDetails -and ($baselineControlsDetails.SupportedSources -contains $scanSource -or $this.UseBaselineControls)) { #Get resource type and control ids mapping from controlsetting object #$this.PublishCustomMessage("Running cmdlet with baseline resource types and controls.", [MessageType]::Warning); $baselineResourceTypes = $baselineControlsDetails.ResourceTypeControlIdMappingList | Select ResourceType | Foreach-Object {$_.ResourceType} #Filter SVT resources based on baseline resource types $ResourcesWithBaselineFilter =$this.Resolver.SVTResources | Where-Object {$null -ne $_.ResourceTypeMapping -and $_.ResourceTypeMapping.ResourceTypeName -in $baselineResourceTypes } #Get the list of control ids $controlIds = $baselineControlsDetails.ResourceTypeControlIdMappingList | Select ControlIds | ForEach-Object { $_.ControlIds } $BaselineControlIds = [system.String]::Join(",",$controlIds); if(-not [system.String]::IsNullOrEmpty($BaselineControlIds)) { $this.ControlIds = $BaselineControlIds; } $this.Resolver.SVTResources = $ResourcesWithBaselineFilter } } [void] UsePartialCommitsCheck() { #Load ControlSetting Resource Types and Filter resources $scanSource = [AzSdkSettings]::GetInstance().GetScanSource(); #Load ControlSetting Resource Types and Filter resources [ControlBaselineManager] $controlBaselineMngr = [ControlBaselineManager]::GetInstance(); $baselineControlsDetails = $controlBaselineMngr.GetBaselineControlDetails() #If Scan source is in suported sources or UsePartialCommits switch is available if ($this.UsePartialCommits -or ($baselineControlsDetails.SupportedSources -contains $scanSource)) { #$this.PublishCustomMessage("Running cmdlet under transactional mode. This will scan resources and store intermittent scan progress to Storage. It resume scan in next run if something breaks inbetween.", [MessageType]::Warning); [ControlBaselineManager] $controlBaselineMngr = [ControlBaselineManager]::GetInstance(); #Validate if active resources list already available in store #If list not available in store. Get resources filtered by baseline resource types and store it storage if(($controlBaselineMngr.IsMasterListActive() -eq [ActiveStatus]::Yes) ) { $allResourcesList = $controlBaselineMngr.GetAllListedResources() # Get list of non scanned active resources $nonScannedResourcesList = $controlBaselineMngr.GetNonScannedResources(); $this.PublishCustomMessage("Resuming scan from last commit. $(($nonScannedResourcesList | Measure-Object).Count) out of $(($allResourcesList | Measure-Object).Count) resources will be scanned.", [MessageType]::Warning); $nonScannedResourceIdList = $nonScannedResourcesList | Select Id | ForEach-Object { $_.Id} #Filter SVT resources based on master resources list available and scan completed $this.Resolver.SVTResources = $this.Resolver.SVTResources | Where-Object {$_.ResourceId -in $nonScannedResourceIdList } } else{ $resourceIdList = $this.Resolver.SVTResources | Select ResourceId | ForEach-Object { $_.ResourceId } $controlBaselineMngr.CreateResourceMasterList($resourceIdList); } } } } |