Framework/Core/SVT/Services/CloudService.ps1

#
# CloudServices.ps1
#
Set-StrictMode -Version Latest 
class CloudService: SVTBase
{
    hidden [PSCloudService] $ResourceObject;

    CloudService([string] $subscriptionId, [string] $resourceGroupName, [string] $resourceName): 
        Base($subscriptionId, $resourceGroupName, $resourceName) 
    { 
        $this.GetResourceObject();
    }

    CloudService([string] $subscriptionId, [SVTResource] $svtResource): 
        Base($subscriptionId, $svtResource) 
    { 
        $this.GetResourceObject();
    }

    hidden [PSObject] GetResourceObject()
    {
        if (-not $this.ResourceObject) {
            $cloudService = Get-AzureRmResource -ResourceName $this.ResourceContext.ResourceName  `
                                        -ResourceType  "Microsoft.ClassicCompute/domainNames" `
                                        -ResourceGroupName $this.ResourceContext.ResourceGroupName `
                                        -ErrorAction Stop
            $this.UpdateCloudServiceInstance()
            if(-not $this.ResourceObject)
            {
                throw ("Resource '{0}' not found under Resource Group '{1}'" -f ($this.ResourceContext.ResourceName), ($this.ResourceContext.ResourceGroupName))
            }
        }

        return $this.ResourceObject;
    }

    hidden [void] UpdateCloudServiceInstance()
    {
        $ResourceAppIdURI = [WebRequestHelper]::ClassicManagementUri;
        $ClassicAccessToken = [Helpers]::GetAccessToken($ResourceAppIdURI)
        if($null -ne $ClassicAccessToken) 
        {
            $header = "Bearer " + $ClassicAccessToken
            $headers = @{"Authorization"=$header;"Content-Type"="application/json"; "x-ms-version" ="2013-08-01"}
            $uri = [string]::Format("{0}/{1}/services/hostedservices/{2}?embed-detail=true","https://management.core.windows.net", $this.SubscriptionContext.SubscriptionId ,$this.ResourceContext.ResourceName)        
            $cloudServiceResponse = Invoke-WebRequest -Method GET -Uri $uri -Headers $headers
            if($cloudServiceResponse.StatusCode -ge 200 -and $cloudServiceResponse.StatusCode -le 399)
            {             
                if($null -ne $cloudServiceResponse.Content)
                {                
                    [xml] $cloudService = $cloudServiceResponse.Content
                    $this.ResourceObject = [PSCloudService]::new()
                    $this.ResourceObject.LoadCloudConfiguration($cloudServiceResponse.Content);
                }
            }            
        }
    }

    hidden [ControlResult] CheckCloudServiceHttpCertificateSSLOnInstanceEndpoints([ControlResult] $controlResult)
    {
        $isCompliant = $true;
        $nonCompliantInstanceEndpoints = @();
        if($null -ne $this.ResourceObject -and $null -ne $this.ResourceObject.RoleInstances)
        {
            $this.ResourceObject.RoleInstances | Foreach-Object{
                $roleInstance = $_;
                if($null -ne $roleInstance)
                {
                    $roleInstance.InstanceEndpoints | ForEach-Object {
                        $instanceEndpoint = $_
                        if($instanceEndpoint.Protocol -eq "http")
                        {
                            $isCompliant = $false;
                            $nonCompliantInstanceEndpoints += $_
                        }
                    }
                }
            }
        }
        if($isCompliant)
        {
            $controlResult.VerificationResult = [VerificationResult]::Passed;
        }
        else
        {
            #$controlResult.AddMessage([VerificationResult]::Failed, "Instance endpoints of cloud service must have http disabled.",$nonCompliantInstanceEndpoints, $true, "InstanceEndpoints");
            $controlResult.AddMessage([VerificationResult]::Failed,  "Instance endpoints of cloud service must have http disabled.",$nonCompliantInstanceEndpoints);
        }   
        return $controlResult;
    }

    hidden [ControlResult] CheckCloudServiceHttpCertificateSSLOnInputEndpoints([ControlResult] $controlResult)
    {        
        $isCompliant = $true; 
        $nonCompliantInputEndpoints = @();
        if($null -ne $this.ResourceObject -and $null -ne $this.ResourceObject.Roles)
        {
            $this.ResourceObject.Roles | Foreach-Object {
                $role = $_;
                if($null -ne $role.InputEndpoint)
                {
                    $role.InputEndpoint | ForEach-Object {
                        $endpoint = $_
                        if($endpoint.Protocol -eq "http")
                        {
                            $isCompliant = $false;
                            $nonCompliantInputEndpoints += $_
                        }
                    }
                }
            }
        }
              
        if($isCompliant)
        {
            $controlResult.VerificationResult = [VerificationResult]::Passed;
        }
        else
        {
            #$controlResult.AddMessage([VerificationResult]::Failed, "Input endpoints of cloud service must have http disabled.", $nonCompliantInputEndpoints, $true, "InputEndpoints");
            $controlResult.AddMessage([VerificationResult]::Failed,  "Input endpoints of cloud service must have http disabled.", $nonCompliantInputEndpoints);
        }   
      
        return $controlResult;
    }

    hidden [ControlResult] CheckCloudServiceInstanceEndpointsIPSettings([ControlResult] $controlResult)
    {
        $instanceEndpoints = @();
        if($null -ne $this.ResourceObject -and $null -ne $this.ResourceObject.RoleInstances)
        {
            $this.ResourceObject.RoleInstances | Foreach-Object{
                $roleInstance = $_;
                if($null -ne $roleInstance)
                {
                    $roleInstance.InstanceEndpoints | ForEach-Object {
                        $instanceEndpoints += $_
                    }
                }
            }
        }
        #$controlResult.AddMessage([VerificationResult]::Verify, "Validate the IP Settings configured for the instance endpoints on cloud service.", $instanceEndpoints, $true, "InstanceEndpoints" );
        $controlResult.AddMessage([VerificationResult]::Verify,  "Validate the IP Settings configured for the instance endpoints on cloud service.", $instanceEndpoints);
        return $controlResult;
    }

    hidden [ControlResult] CheckCloudServiceInputEndpoints([ControlResult] $controlResult)
    {
        $isCompliant = $true; 
        $inputEndpoints = @();
        if($null -ne $this.ResourceObject -and $null -ne $this.ResourceObject.Roles)
        {
            $this.ResourceObject.Roles | Foreach-Object {
                $role = $_;
                if($null -ne $role.InputEndpoint)
                {
                    $role.InputEndpoint | ForEach-Object {
                        $inputEndpoints += $role.InputEndpoint
                    }
                }
            }
        }
        #$controlResult.AddMessage([VerificationResult]::Verify, "Remove any un-used internal endpoints from your cloud service.", $inputEndpoints, $true, "InputEndpoints" );
        $controlResult.AddMessage([VerificationResult]::Verify,  "Remove any un-used internal endpoints from your cloud service.", $inputEndpoints);
        return $controlResult;
    }

    hidden [ControlResult] CheckCloudServiceRemoteDebuggingStatus([ControlResult] $controlResult)
    {
        $isCompliant = $true;
        $nonCompliantInstanceEndpoints = @();
        if($null -ne $this.ResourceObject -and $null -ne $this.ResourceObject.RoleInstances)
        {
            $this.ResourceObject.RoleInstances | Foreach-Object{
                $roleInstance = $_;
                if($null -ne $roleInstance)
                {
                    $roleInstance.InstanceEndpoints | ForEach-Object {
                        $instanceEndpoint = $_
                        if($instanceEndpoint.Name -like "Microsoft.WindowsAzure.Plugins.RemoteDebugger*")
                        {
                            $isCompliant = $false;
                            $nonCompliantInstanceEndpoints += $_
                        }
                    }
                }
            }
        }

        if($isCompliant)
        {
            $controlResult.VerificationResult = [VerificationResult]::Passed;
        }
        else
        {
            #$controlResult.AddMessage([VerificationResult]::Failed, "Remote debugging endpoints enabled on cloud service.", $nonCompliantInstanceEndpoints, $true, "InstanceEndpoints");
            $controlResult.AddMessage([VerificationResult]::Failed,  "Remote debugging endpoints enabled on cloud service.", $nonCompliantInstanceEndpoints);
        }   
        return $controlResult;
    }

    hidden [ControlResult] CheckCloudServiceAntiMalwareStatus([ControlResult] $controlResult)
    {
        $isCompliant = $false;
        $extensions = @{};
        if($null -ne $this.ResourceObject -and $null -ne $this.ResourceObject.Extensions)
        {
            $this.ResourceObject.Extensions | Foreach-Object{
                $extension = $_;
                $extensions.Add($extension.RoleName,$false);
                if($null -ne $extension -and $null -ne $extension.ExtensionId)
                {
                    $extension.ExtensionId | ForEach-Object {
                        $extensionId = $_
                        if($extensionId.Id -like "*Antimalware*")
                        {
                            $extensions[$extension.RoleName] = $true
                        }
                    }
                }
            }
        }

        if(($extensions.Values | Where-Object {-not $_} | Measure-Object).Count -le 0)
        {
            $controlResult.VerificationResult = [VerificationResult]::Passed;
        }
        else
        {
            #$controlResult.AddMessage([VerificationResult]::Failed, "Antimalware extension is not enabled on cloud service.", $this.ResourceObject.Extensions, $true, "Extensions");
            $controlResult.AddMessage([VerificationResult]::Failed,  "Antimalware extension is not enabled on cloud service.", $this.ResourceObject.Extensions);
        }   
        return $controlResult;
    }

    hidden [ControlResult] CheckCloudServiceRemoteDesktopAccess([ControlResult] $controlResult)
    {
        $extensions = @{};
        if($null -ne $this.ResourceObject -and $null -ne $this.ResourceObject.Extensions)
        {
            $this.ResourceObject.Extensions | Foreach-Object{
                $extension = $_;
                $extensions.Add($extension.RoleName,$true);
                if($null -ne $extension -and $null -ne $extension.ExtensionId)
                {
                    $extension.ExtensionId | ForEach-Object {
                        $extensionId = $_
                        if($extensionId.Id -like "*RDP*")
                        {
                            $extensions[$extension.RoleName] = $false
                        }
                    }
                }
            }
        }

        if(($extensions.Values | Where-Object {-not $_} | Measure-Object).Count -le 0)
        {
            $isCompliant = $true;
        }
        else
        {
            $isCompliant = $false;
            #$controlResult.AddMessage("Remote desktop endpoints are enabled on cloud service.", $extensions, $true, "InstanceEndpoints");
            $controlResult.AddMessage("Remote desktop endpoints are enabled on cloud service.", $extensions);
        }   

        #$b.ServiceConfiguration.Role[0].ConfigurationSettings.Setting.SyncRoot["Microsoft.WindowsAzure.Plugins.RemoteAccess.Enabled"]
        $nonCompliantInstanceEndpoints = @();
        if($isCompliant)
        {
            if($null -ne $this.ResourceObject -and $null -ne $this.ResourceObject.RoleInstances)
            {
                $this.ResourceObject.RoleInstances | Foreach-Object{
                    $roleInstance = $_;
                    if($null -ne $roleInstance)
                    {
                        $roleInstance.InstanceEndpoints | ForEach-Object {
                            $instanceEndpoint = $_
                            if($instanceEndpoint.Name -like "Microsoft.WindowsAzure.Plugins.RemoteForwarder*")
                            {
                                $isCompliant = $false;
                                $nonCompliantInstanceEndpoints += $_
                            }
                        }
                    }
                }
            }
        }
        if(-not $isCompliant)
        {
            if($null -ne $this.ResourceObject.Configuration -and $null -ne $this.ResourceObject.Configuration.ServiceConfiguration -and $null -ne $this.ResourceObject.Configuration.ServiceConfiguration.Role)
            {
                $isRemoteAccessEnabled = $false;
                $tempRoles = $this.ResourceObject.Configuration.ServiceConfiguration.Role;
                $tempRoles | ForEach-Object {
                    $tempRole = $_;
                    if($null -ne $tempRole.ConfigurationSettings -and $null -ne $tempRole.ConfigurationSettings.Setting)
                    {
                        $remoteEndpointValue = $tempRole.ConfigurationSettings.Setting | Where-Object { $_.name -eq 'Microsoft.WindowsAzure.Plugins.RemoteAccess.Enabled'}
                        if(($remoteEndpointValue| Measure-Object).Count -eq 1)
                        {
                            if(-not $isRemoteAccessEnabled)
                            {
                                $isRemoteAccessEnabled = [bool]::Parse($remoteEndpointValue.Value);
                            }
                        }
                    }
                }
                if(-not $isRemoteAccessEnabled)
                {
                    $isCompliant = $true;
                }
                else
                {
                    #$controlResult.AddMessage("Remote desktop endpoints are enabled on cloud service.", $nonCompliantInstanceEndpoints, $true, "InstanceEndpoints");
                    $controlResult.AddMessage("Remote desktop endpoints are enabled on cloud service.", $nonCompliantInstanceEndpoints);
                }
            }            
        }

        if($isCompliant)
        {
            $controlResult.VerificationResult = [VerificationResult]::Passed;
        }
        else
        {
            $controlResult.VerificationResult = [VerificationResult]::Failed;
        }   
        return $controlResult;
    }
}