Framework/Core/SVT/SVTStatusReport.ps1
# Set-StrictMode -Version Latest # class SVTStatusReport : SVTCommandBase # { # [SVTResourceResolver] $ServicesResolver = $null; # SVTStatusReport([string] $subscriptionId, [InvocationInfo] $invocationContext, [SVTResourceResolver] $resolver): # Base($subscriptionId, $invocationContext) # { # if(-not $resolver) # { # throw [System.ArgumentException] ("The argument 'resolver' is null"); # } # $this.ServicesResolver = $resolver; # $this.ServicesResolver.LoadAzureResources(); # } # hidden [SVTEventContext[]] RunAllControls() # { # [SVTEventContext[]] $result = @(); # # Run all Subscription security controls # try # { # $this.PublishCustomMessage(" `r`n" + [Constants]::DoubleDashLine + "`r`nStarted Subscription security controls`r`n" + [Constants]::DoubleDashLine); # $sscore = [SubscriptionSecurityStatus]::new($this.SubscriptionContext.SubscriptionId, $this.InvocationContext); # if ($sscore) # { # # Just copy all the tags without validation. Validation will be done internally # $sscore.FilterTags = $this.FilterTags; # $sscore.ExcludeTags = $this.ExcludeTags; # $sscore.ControlIdString = $this.ControlIdString; # $sscore.ExcludeControlIdString = $this.ExcludeControlIdString; # $sscore.GenerateFixScript = $this.GenerateFixScript; # $sscore.AttestationOptions = $this.AttestationOptions; # $result += $sscore.RunAllControls(); # $this.PublishCustomMessage([Constants]::DoubleDashLine + "`r`nCompleted Subscription security controls`r`n" + [Constants]::DoubleDashLine, [MessageType]::Update); # } # } # catch # { # $this.CommandError($_); # } # # Run all Azure services security controls # try # { # $this.PublishCustomMessage(" `r`n" + [Constants]::DoubleDashLine + "`r`nStarted Azure services security controls`r`n" + [Constants]::DoubleDashLine); # $secStatus = [ServicesSecurityStatus]::new($this.SubscriptionContext.SubscriptionId, $this.InvocationContext, $this.ServicesResolver); # if ($secStatus) # { # # Just copy all the tags without validation. Validation will be done internally # $secStatus.FilterTags = $this.FilterTags; # $secStatus.ExcludeTags = $this.ExcludeTags; # $secStatus.ControlIdString = $this.ControlIdString; # $secStatus.ExcludeControlIdString = $this.ExcludeControlIdString; # $secStatus.GenerateFixScript = $this.GenerateFixScript; # $secStatus.AttestationOptions = $this.AttestationOptions; # $result += $secStatus.RunAllControls(); # $this.PublishCustomMessage([Constants]::DoubleDashLine + "`r`nCompleted Azure services security controls`r`n" + [Constants]::DoubleDashLine, [MessageType]::Update); # } # } # catch # { # $this.CommandError($_); # } # return $result; # } # hidden [SVTEventContext[]] FetchAttestationInfo() # { # [SVTEventContext[]] $result = @(); # # Fetch state of all Subscription security controls # try # { # $this.PublishCustomMessage(" `r`n" + [Constants]::DoubleDashLine + "`r`nGetting attestation info for Subscription level controls`r`n" + [Constants]::DoubleDashLine); # $sscore = [SubscriptionSecurityStatus]::new($this.SubscriptionContext.SubscriptionId, $this.InvocationContext); # if ($sscore) # { # # Just copy all the tags without validation. Validation will be done internally # $sscore.ControlIdString = $this.ControlIdString; # $sscore.AttestationOptions = $this.AttestationOptions; # $result += $sscore.FetchAttestationInfo(); # if(($result|Measure-object).count -gt 0) # { # $this.PublishCustomMessage([Constants]::DoubleDashLine + "`r`nCompleted Subscription level controls`r`n" + [Constants]::DoubleDashLine, [MessageType]::Update); # } # elseif([string]::IsNullOrWhiteSpace($sscore.ControlIdString)) # { # $this.PublishCustomMessage([Constants]::SingleDashLine + "`r`nNo attestation data found for Subscription level controls`r`n" + [Constants]::DoubleDashLine, [MessageType]::Update) # } # } # } # catch # { # $this.CommandError($_); # } # # Fetch state of all Azure services security controls # try # { # $this.PublishCustomMessage(" `r`n" + [Constants]::DoubleDashLine + "`r`nGetting attestation info for Azure services controls`r`n" + [Constants]::DoubleDashLine); # $secStatus = [ServicesSecurityStatus]::new($this.SubscriptionContext.SubscriptionId, $this.InvocationContext, $this.ServicesResolver); # if ($secStatus) # { # # Just copy all the tags without validation. Validation will be done internally # $secStatus.ControlIdString = $this.ControlIdString; # #$secStatus.GenerateFixScript = $this.GenerateFixScript; # $secStatus.AttestationOptions = $this.AttestationOptions; # $secStatusResult = $secStatus.FetchAttestationInfo() # if(($secStatusResult|Measure-Object).Count -gt 0) # { # $result += $secStatusResult # $this.PublishCustomMessage([Constants]::DoubleDashLine + "`r`nCompleted Azure services controls`r`n" + [Constants]::DoubleDashLine, [MessageType]::Update); # } # else # { # $this.PublishCustomMessage([Constants]::SingleDashLine + "`r`nNo attestation data found for Azure services controls`r`n" + [Constants]::DoubleDashLine, [MessageType]::Update) # } # } # } # catch # { # $this.CommandError($_); # } # #display summary # if(($result|Measure-Object).Count -gt 0) # { # $this.DisplayAttetstationStatistics($result) # } # else # { # } # return $result; # } # hidden [void] DisplayAttetstationStatistics([SVTEventContext[]] $Result) # { # $this.PublishCustomMessage("`r`n"+[Constants]::DoubleDashLine+"`r`nSummary of attestation details:`r`n`r`n"); # $this.DisplayAttestationStatusWiseControlsCount($Result); # $this.DisplaySeverityWiseControlsCount($Result); # $this.DisplayControlIdWiseCount($Result) # $this.DisplayExpiryDateWiseControlsCount($Result); # } # hidden [void] DisplayAttestationStatusWiseControlsCount([SVTEventContext[]] $Result) # { # $subCoreResult = $Result|Where-Object{!$_.IsResource()}; # $resResult = $Result|Where-Object{$_.IsResource()}; # if(($subCoreResult|Measure-Object).Count -gt 0) # { # $subCoreGroup = $subCoreResult.ControlResults|Group-Object ActualVerificationResult,AttestationStatus | ForEach{ # [pscustomobject]@{ # 'ActualVerificationResult'=$_.Group[0].ActualVerificationResult # 'AttestationStatus'=$_.Group[0].AttestationStatus # 'ControlsCount'=$_.count} # } # $this.PublishCustomMessage([Constants]::SingleDashLine+"`r`nSubscription controls:`r`n"+($subCoreGroup|out-string)) # $this.PublishCustomMessage([Constants]::SingleDashLine) # } # if(($resResult|Measure-Object).Count -gt 0) # { # $resGroup = $resResult.ControlResults|Group-Object ActualVerificationResult,AttestationStatus | ForEach{ # [pscustomobject]@{ # 'ActualVerificationResult'=$_.Group[0].ActualVerificationResult # 'AttestationStatus'=$_.Group[0].AttestationStatus # 'ControlsCount'=$_.count} # } # $this.PublishCustomMessage("Azure Services controls:`r`n"+($resGroup|out-string)) # $this.PublishCustomMessage([Constants]::DoubleDashLine) # } # } # hidden [void] DisplaySeverityWiseControlsCount([SVTEventContext[]] $Result) # { # $groupResult = $Result.ControlItem| Group ControlSeverity | ForEach{ # [pscustomobject]@{ # 'ControlSeverity'=$_.name # 'ControlsCount'=$_.count} # } # $this.PublishCustomMessage("Distribution of attested controls by severity:`r`n"+($groupResult|out-string)) # $this.PublishCustomMessage([Constants]::DoubleDashLine); # } # hidden [void] DisplayControlIdWiseCount([SVTEventContext[]] $Result) # { # $groupResult = $Result.ControlItem| Group ControlId | ForEach{ # [pscustomobject]@{ # 'ControlId'=$_.name # 'ControlsCount'=$_.count} # } # $this.PublishCustomMessage("Distribution of controls that have been attested:`r`n"+($groupResult|out-string)); # $this.PublishCustomMessage([Constants]::DoubleDashLine); # } # hidden [void] DisplayExpiryDateWiseControlsCount([SVTEventContext[]] $Result) # { # $subCoreResult = $Result|Where-Object{!$_.IsResource()}; # $resResult = $Result|Where-Object{$_.IsResource()}; # $expiringSubControls = @() # $expiringStateResources = @() # if(($subCoreResult|Measure-Object).Count -gt 0) # { # $subControlsWithExpDate = $subCoreResult | Where-Object{ $_.ControlResults|Where-Object{![string]::IsNullOrWhiteSpace($_.StateManagement.AttestedStateData.ExpiryDate)}} # $expiringSubControls= $subControlsWithExpDate | Where-Object{ $_.ControlResults | Where-Object{([datetime]$_.StateManagement.AttestedStateData.ExpiryDate - $(Get-Date).ToUniversalTime()).TotalDays -le 30}} # } # if(($resResult|Measure-Object).Count -gt 0) # { # $resourcesWithExpDate = $resResult | Where-Object{ $_.ControlResults|Where-Object{![string]::IsNullOrWhiteSpace($_.StateManagement.AttestedStateData.ExpiryDate)}} # $expiringStateResources = $resourcesWithExpDate | Where-Object{ $_.ControlResults | Where-Object{([datetime]$_.StateManagement.AttestedStateData.ExpiryDate - $(Get-Date).ToUniversalTime()).TotalDays -le 30}} # } # if(($expiringSubControls|Measure-Object).Count -gt 0 -or ($expiringStateResources|Measure-Object).Count -gt 0) # { # $expiringSubControls15Days= $expiringSubControls | Where-Object{ $_.ControlResults | Where-Object{([datetime]$_.StateManagement.AttestedStateData.ExpiryDate - $(Get-Date).ToUniversalTime()).TotalDays -le 15}} # $expiringStateResources15Days = $expiringStateResources | Where-Object{ $_.ControlResults | Where-Object{([datetime]$_.StateManagement.AttestedStateData.ExpiryDate - $(Get-Date).ToUniversalTime()).TotalDays -le 15}} # $expiringSubControls7Days= $expiringSubControls | Where-Object{ $_.ControlResults | Where-Object{([datetime]$_.StateManagement.AttestedStateData.ExpiryDate - $(Get-Date).ToUniversalTime()).TotalDays -le 7}} # $expiringStateResources7Days = $expiringStateResources | Where-Object{ $_.ControlResults | Where-Object{([datetime]$_.StateManagement.AttestedStateData.ExpiryDate - $(Get-Date).ToUniversalTime()).TotalDays -le 7}} # $this.PublishCustomMessage("Summary of controls expiring in near future:`r`n`r`nDays CountOfSubscriptionControls CountOfAzureServicesControls`r`n"+[Constants]::SingleDashLine); # if(($expiringSubControls7Days|Measure-Object).Count -gt 0 -or ($expiringStateResources7Days|Measure-Object).Count -gt 0) # { # $this.PublishCustomMessage("07`t`t$(($expiringSubControls7Days|Measure-Object).Count)`t`t`t`t`t`t`t$(($expiringStateResources7Days|Measure-Object).Count)"); # } # if(($expiringSubControls15Days|Measure-Object).Count -gt 0 -or ($expiringStateResources15Days|Measure-Object).Count -gt 0) # { # $this.PublishCustomMessage("15`t`t$(($expiringSubControls15Days|Measure-Object).Count)`t`t`t`t`t`t`t$(($expiringStateResources15Days|Measure-Object).Count)`t`t`t`t"); # } # $this.PublishCustomMessage("30`t`t$(($expiringSubControls|Measure-Object).Count)`t`t`t`t`t`t`t$(($expiringStateResources|Measure-Object).Count)`t`t`t`t`r`n`r`n"); # $this.PublishCustomMessage("Recommendation: Check Attestation report to get details of expiring controls and fix/attest them before expiry.",[MessageType]::Warning); # } # else # { # $this.PublishCustomMessage([Constants]::SingleDashLine+"`r`n`r`nCount of Controls expiring in the next 30 days: 0`r`n"); # } # } # } |