Framework/Core/SVT/Services/Automation.ps1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
Set-StrictMode -Version Latest 
class Automation: AzSVTBase
{       

    Automation([string] $subscriptionId, [SVTResource] $svtResource): 
        Base($subscriptionId, $svtResource) 
    { 
    }
    hidden [ControlResult] CheckWebhooks([ControlResult] $controlResult)
    {   
        $webhooks = Get-AzAutomationWebhook -AutomationAccountName $this.ResourceContext.ResourceName -ResourceGroupName $this.ResourceContext.ResourceGroupName -ErrorAction Stop
        if(($webhooks|Measure-Object).Count -gt 0)
        {
            $webhookdata = $webhooks | Select-Object ResourceGroupName, AutomationAccountName, Name, Description, IsEnabled, Parameters, RunbookName, WebhookURI, HybridWorker
            $controlResult.AddMessage([VerificationResult]::Verify, "Please verify below webhook(s) created for the runbooks. Remove webhook(s) which are not in use.", $webhookdata)
            $controlResult.SetStateData("Webhooks", $webhookdata);                      
        }
        else
        {
            $controlResult.AddMessage([VerificationResult]::Passed, "No webhook(s) are created for runbook(s) in this Automation account.")
        }
        return $controlResult;
    }
    hidden [ControlResult] CheckWebhookExpiry([ControlResult] $controlResult)
    {   
        $webhooks = Get-AzAutomationWebhook -AutomationAccountName $this.ResourceContext.ResourceName -ResourceGroupName $this.ResourceContext.ResourceGroupName -ErrorAction Stop
        $longExpiryWebhooks = @()
        if(($webhooks|Measure-Object).Count -gt 0)
        {
            $webhooks | ForEach-Object{
                if(($_.IsEnabled -eq $true) -and (($_.ExpiryTime - $_.CreationTime).Days -gt $this.ControlSettings.Automation.WebhookValidityInDays))
                {
                    $expiryTime = ($_.ExpiryTime - $_.CreationTime).days;
                    $webhookdata = $_ | Select-Object ResourceGroupName, AutomationAccountName, Name, Description, IsEnabled, Parameters, RunbookName, WebhookURI, HybridWorker
                    $webhookdata | Add-Member ExpiryTime -NotePropertyValue $expiryTime
                    $longExpiryWebhooks += $webhookdata
                }
            }
            if($longExpiryWebhooks)
            {
                $controlResult.AddMessage([VerificationResult]::Failed, "Webhook URL must have shorter validity period (<=$($this.ControlSettings.Automation.WebhookValidityInDays) days) to prevent malicious access. Below webhook(s) URL have validity period >$($this.ControlSettings.Automation.WebhookValidityInDays) days.", $longExpiryWebhooks)
                $controlResult.SetStateData("Webhook(s) with >$($this.ControlSettings.Automation.WebhookValidityInDays) days validity", $longExpiryWebhooks);                      
            }
            else
            {
                $controlResult.VerificationResult =[VerificationResult]::Passed
            }
        }
        else
        {
            $controlResult.AddMessage([VerificationResult]::Passed, "No webhooks are created for runbooks in this Automation account.")
        }
        return $controlResult;
    }
    hidden [ControlResult] CheckVariables([ControlResult] $controlResult)
    {   
        $variables = Get-AzAutomationVariable -AutomationAccountName $this.ResourceContext.ResourceName -ResourceGroupName $this.ResourceContext.ResourceGroupName -ErrorAction Stop
        if(($variables|Measure-Object).Count -gt 0 )
        {
            if($this.ResourceContext.ResourceGroupName -eq [ConfigurationManager]::GetAzSKConfigData().AzSKRGName -and [Helpers]::CheckMember($this.ControlSettings,"Automation.variablesToSkip"))
            {
                $variablestoskip = $this.ControlSettings.Automation.variablesToSkip
                $temp = $variables | Where {$variablestoskip -notcontains $_.Name}
                $variables = $temp
            }
            $encryptedVars = @()
            $unencryptedVars = @()

            $variables | ForEach-Object{
                if($_.Encrypted)
                {
                    $encryptedVars += $_
                }
                else
                {
                    $unencryptedVars += $_
                }
            }
            if($encryptedVars)
            {
                $controlResult.AddMessage("$($encryptedVars.Count) variable(s) are encrypted in this Automation account.")
            }
            if($unencryptedVars)
            {
                $controlResult.AddMessage([VerificationResult]::Verify, "Below variable(s) are not encrypted, use encrypted variable if it contains sensitive data.", $unencryptedVars)
                $controlResult.SetStateData("Unencrypted variable(s)", $unencryptedVars);                      
            }
            else
            {
                $controlResult.VerificationResult =[VerificationResult]::Passed
            }
        }
        else
        {
            $controlResult.AddMessage([VerificationResult]::Passed, "No variables are present in this Automation account.")
        }
        return $controlResult;
    }
    hidden [ControlResult] CheckLAWSSetup([ControlResult] $controlResult)
    {   
        $resource = Get-AzResource -Name $this.ResourceContext.ResourceName -ResourceGroupName $this.ResourceContext.ResourceGroupName -ResourceType "Microsoft.Automation/automationAccounts" -ErrorAction Stop
        $resourceId = $resource.ResourceId
        $diaSettings = $null
        try 
        {
            $diaSettings = Get-AzDiagnosticSetting -ResourceId $resourceId -ErrorAction Stop -WarningAction SilentlyContinue
        }
        catch
        {
            if([Helpers]::CheckMember($_.Exception, "Response") -and ($_.Exception).Response.StatusCode -eq [System.Net.HttpStatusCode]::NotFound)
            {
                $controlResult.AddMessage([VerificationResult]::Failed, "Log Analytics workspace is not configured with this Automation account.")
                return $controlResult
            }
            else
            {
                $this.PublishException($_);
            }
        }
        if($null -ne $diaSettings -and (Get-Member -InputObject $diaSettings -Name WorkspaceId -MemberType Properties) -and $null -ne $diaSettings.WorkspaceId)
        {
            $controlResult.AddMessage([VerificationResult]::Passed, "Log Analytics workspace is configured with this Automation account. Log Analytics Workspace Id is given below.", $diaSettings.WorkspaceId)
        }
        else
        {
            $controlResult.AddMessage([VerificationResult]::Failed, "Log Analytics workspace is not configured with this Automation account.")
        }
        return $controlResult;
    }    
}