SVT/SVT.ps1

Set-StrictMode -Version Latest
function Get-AzSDKAzureServicesSecurityStatus 
{
    <#
    .SYNOPSIS
    This command would help in validating the security controls for the Azure resources meeting the specified input criteria.
    .DESCRIPTION
    This command will execute the security controls and will validate their status as 'Success' or 'Failure' based on the security guidance. Refer https://aka.ms/azsdkdocs for more information
     
    .PARAMETER SubscriptionId
        Subscription id for which the security evaluation has to be performed.
    .PARAMETER ResourceGroupNames
        ResourceGroups for which the security evaluation has to be performed. Comma seperated values are supported. Wildcards are not permitted. By default, the command gets all resources in the subscription.
    .PARAMETER ResourceType
        Gets only resources of the specified resource type. Wildcards are not permitted. e.g.: Microsoft.KeyVault/vaults. Run command 'Get-AzSDKSupportedResourceTypes' to get the list of supported types.
    .PARAMETER ResourceTypeName
        Friendly name of resource type. e.g.: KeyVault. Run command 'Get-AzSDKSupportedResourceTypes' to get the list of supported values.
    .PARAMETER ResourceName
        Gets a resource with the specified name. Wildcards are not permitted. By default, the command gets all resources in the subscription.
    .PARAMETER Tag
        The tag filter for Azure resource. The expected format is @{tagName1=$null} or @{tagName = 'tagValue'; tagName2='value1'}.
    .PARAMETER TagName
        The name of the tag to query for Azure resource.
    .PARAMETER TagValue
        The value of the tag to query for Azure resource.
    .PARAMETER FilterTags
        Comma seperated tags to filter the security controls. e.g.: RBAC, SOX, AuthN etc.
    .PARAMETER ExcludeTags
        Comma seperated tags to exclude the security controls. e.g.: RBAC, SOX, AuthN etc.
    .PARAMETER AttestControls
        Enables users to attest controls with proper justification
    .PARAMETER DoNotOpenOutputFolder
        Switch to specify whether to open output folder containing all security evaluation report or not.
 
    .NOTES
    This command helps the application team to verify whether their Azure resources are compliant with the security guidance or not
 
    .LINK
    https://aka.ms/azsdkdocs
 
    #>

    [OutputType([String])]
    Param
    (

        [string]
        [Parameter(Mandatory = $true, HelpMessage = "Subscription id for which the security evaluation has to be performed.")]
        [ValidateNotNullOrEmpty()]
        $SubscriptionId,

        [string]
        [Parameter(Mandatory = $false, ParameterSetName = "ResourceFilter", HelpMessage = "ResourceGroups for which the security evaluation has to be performed. Comma seperated values are supported. Wildcards are not permitted. By default, the command gets all resources in the subscription.")]
        $ResourceGroupNames,
        
        [string]
        [Parameter(Mandatory = $false, ParameterSetName = "ResourceFilter", HelpMessage = "Gets only resources of the specified resource type. Wildcards are not permitted. e.g.: Microsoft.KeyVault/vaults. Run command 'Get-AzSDKSupportedResourceTypes' to get the list of supported types.")]
        $ResourceType,

        [Parameter(Mandatory = $false, ParameterSetName = "ResourceFilter", HelpMessage = "Friendly name of resource type. e.g.: KeyVault. Run command 'Get-AzSDKSupportedResourceTypes' to get the list of supported values.")]
        [ResourceTypeName]
        $ResourceTypeName = [ResourceTypeName]::All,
        
        [string]
        [Parameter(Mandatory = $false, ParameterSetName = "ResourceFilter", HelpMessage = "Gets a resource with the specified name. Wildcards are not permitted. By default, the command gets all resources in the subscription.")]
        $ResourceName,
    
        [Hashtable] 
        [Parameter(Mandatory = $true, ParameterSetName = "TagHashset", HelpMessage = "The tag filter for Azure resource. The expected format is @{tagName1=`$null} or @{tagName = 'tagValue'; tagName2='value1'}.")]
        $Tag,

        [string]
        [Parameter(Mandatory = $true, ParameterSetName = "TagName", HelpMessage = "The name of the tag to query for Azure resource.")]
        $TagName,

        [string]
        [Parameter(Mandatory = $true, ParameterSetName = "TagName", HelpMessage = "The value of the tag to query for Azure resource.")]
        $TagValue,

        [string] 
        [Parameter(Mandatory = $false, HelpMessage = "Comma seperated control ids to filter the security controls. e.g.: Azure_Subscription_AuthZ_Limit_Admin_Owner_Count, Azure_Storage_DP_Encrypt_At_Rest_Blob etc.")]
        $ControlIds,

        [string] 
        [Parameter(Mandatory = $false, HelpMessage = "Comma seperated tags to filter the security controls. e.g.: RBAC, SOX, AuthN etc.")]
        $FilterTags,

        [string] 
        [Parameter(Mandatory = $false, HelpMessage = "Comma seperated tags to exclude the security controls. e.g.: RBAC, SOX, AuthN etc.")]
        $ExcludeTags,
        
        [AttestControls]
        [Parameter(Mandatory = $false, HelpMessage = "Enables users to attest controls with proper justification.")]
        $AttestControls = [AttestControls]::None,

        [switch]
        [Parameter(Mandatory = $false, HelpMessage = "Switch to specify whether to open output folder containing all security evaluation report or not.")]
        $DoNotOpenOutputFolder
    )

    Begin
    {
        [ListenerHelper]::RegisterListeners();
    }

    Process
    {
     try 
        {
            $resolver = [SVTResourceResolver]::new($SubscriptionId, $ResourceGroupNames);
            $resolver.ResourceName = $ResourceName; 
            $resolver.ResourceType = $ResourceType;
            $resolver.ResourceTypeName = $ResourceTypeName;
            $resolver.Tag = $Tag;
            $resolver.TagName = $TagName;
            $resolver.TagValue = $TagValue;

            $secStatus = [ServicesSecurityStatus]::new($SubscriptionId, $PSCmdlet.MyInvocation, $resolver);
            if ($secStatus) 
            {
                # Just copy all the tags without validation. Validation will be done internally
                $secStatus.FilterTags = $FilterTags;
                $secStatus.ExcludeTags = $ExcludeTags;
                $secStatus.ControlIds = $ControlIds;
                $secStatus.AttestControls = $AttestControls;

                return $secStatus.EvaluateControlStatus();
            }    
        }
        catch 
        {
            [EventBase]::PublishGenericException($_);
        }  
    }

    End
    {
        [ListenerHelper]::UnregisterListeners();
    }
}

function Get-AzSDKSubscriptionSecurityStatus
{
    <#
    .SYNOPSIS
    This command would help in validating the security controls for the Azure Subscription meeting the specified input criteria.
    .DESCRIPTION
    This command will execute the security controls and will validate their status as 'Success' or 'Failure' based on the security guidance. Refer https://aka.ms/azsdkdocs for more information
     
    .PARAMETER SubscriptionId
        Subscription id for which the security evaluation has to be performed.
    .PARAMETER FilterTags
        Comma seperated tags to filter the security controls. e.g.: RBAC, SOX, AuthN etc.
    .PARAMETER ExcludeTags
        Comma seperated tags to exclude the security controls. e.g.: RBAC, SOX, AuthN etc.
    .PARAMETER AttestControls
        Enables users to attest controls with proper justification
    .PARAMETER DoNotOpenOutputFolder
        Switch to specify whether to open output folder containing all security evaluation report or not.
 
    .NOTES
    This command helps the application team to verify whether their Azure subscription are compliant with the security guidance or not
 
    .LINK
    https://aka.ms/azsdkdocs
 
    #>

    [OutputType([String])]
    Param
    (
        [Parameter(Mandatory = $True, HelpMessage = "Subscription id for which the security evaluation has to be performed.")]
        [string]
        [ValidateNotNullOrEmpty()]
        $SubscriptionId,
        
        [string] 
        [Parameter(Mandatory = $false, HelpMessage = "Comma seperated control ids to filter the security controls. e.g.: Azure_Subscription_AuthZ_Limit_Admin_Owner_Count, Azure_Storage_DP_Encrypt_At_Rest_Blob etc.")]
        $ControlIds,
        
        [string] 
        [Parameter(Mandatory = $false, HelpMessage = "Comma seperated tags to filter the security controls. e.g.: RBAC, SOX, AuthN etc.")]
        $FilterTags,

        [string] 
        [Parameter(Mandatory = $false, HelpMessage = "Comma seperated tags to exclude the security controls. e.g.: RBAC, SOX, AuthN etc.")]
        $ExcludeTags,

        [AttestControls]
        [Parameter(Mandatory = $false, HelpMessage = "Enables users to attest controls with proper justification.")]
        $AttestControls = [AttestControls]::None,
            
        [switch]
        [Parameter(Mandatory = $false, HelpMessage = "Switch to specify whether to open output folder containing all security evaluation report or not.")]
        $DoNotOpenOutputFolder            
    )
    Begin
    {
        [ListenerHelper]::RegisterListeners();
    }
    Process
    {
     try 
        {
            $sscore = [SubscriptionSecurityStatus]::new($SubscriptionId, $PSCmdlet.MyInvocation);
            if ($sscore) 
            {
                # Just copy all the tags without validation. Validation will be done internally
                $sscore.FilterTags = $FilterTags;
                $sscore.ExcludeTags = $ExcludeTags;
                $sscore.ControlIds = $ControlIds;
                $sscore.AttestControls = $AttestControls;
                
                return $sscore.EvaluateControlStatus();
            }    
        }
        catch 
        {
            [EventBase]::PublishGenericException($_);
        }  
    }
    End
    {
        [ListenerHelper]::UnregisterListeners();
    }
}

function Get-AzSDKExpressRouteNetworkSecurityStatus
{
    <#
    .SYNOPSIS
    This command would help in validating the security controls for the ExpressRoute enabled VNet resources meeting the specified input criteria.
    .DESCRIPTION
    This command will execute the security controls and will validate their status as 'Success' or 'Failure' based on the security guidance. Refer https://aka.ms/azsdkdocs for more information
     
    .PARAMETER SubscriptionId
        Subscription id for which the security evaluation has to be performed.
    .PARAMETER ResourceGroupNames
        ResourceGroups which host ExpressRoute VNets. Comma seperated values are supported. Wildcards are not permitted. By default, the command gets all resources in the subscription.
    .PARAMETER ResourceName
        ExpressRoute VNet resource name. Wildcards are not permitted. By default, the command gets all resources in the subscription.
    .PARAMETER FilterTags
        Comma seperated tags to filter the security controls. e.g.: RBAC, SOX, AuthN etc.
    .PARAMETER ExcludeTags
        Comma seperated tags to exclude the security controls. e.g.: RBAC, SOX, AuthN etc.
    .PARAMETER AttestControls
        Enables users to attest controls with proper justification
    .PARAMETER DoNotOpenOutputFolder
        Switch to specify whether to open output folder containing all security evaluation report or not.
 
    .NOTES
    This command helps the application team to verify whether their ExpressRoute enabled VNets are compliant with the security guidance or not
 
    .LINK
    https://aka.ms/azsdkdocs
 
    #>

    [OutputType([String])]
    Param(
        [string]
        [Parameter(Mandatory = $true, HelpMessage = "Provide the subscription id for which the security report has to be generated")]
        [ValidateNotNullOrEmpty()]
        $SubscriptionId,

        [string]
        [Parameter(Mandatory = $false, HelpMessage = "ResourceGroups which host ExpressRoute VNets. Comma seperated values are supported. Wildcards are not permitted. By default, the command gets all resources in the subscription.")]
        $ResourceGroupNames,
        
        [string]
        [Parameter(Mandatory = $false, ParameterSetName = "ResourceFilter", HelpMessage = "ExpressRoute VNet resource name. Wildcards are not permitted. By default, the command gets all resources in the subscription.")]
        $ResourceName,
    
        [string] 
        [Parameter(Mandatory = $false, HelpMessage = "Comma seperated control ids to filter the security controls. e.g.: Azure_Subscription_AuthZ_Limit_Admin_Owner_Count, Azure_Storage_DP_Encrypt_At_Rest_Blob etc.")]
        $ControlIds,
        
        [string] 
        [Parameter(Mandatory = $false, HelpMessage = "Comma seperated tags to filter the security controls. e.g.: RBAC, SOX, AuthN etc.")]
        $FilterTags,

        [string] 
        [Parameter(Mandatory = $false, HelpMessage = "Comma seperated tags to exclude the security controls. e.g.: RBAC, SOX, AuthN etc.")]
        $ExcludeTags,        
                
        [AttestControls]
        [Parameter(Mandatory = $false, HelpMessage = "Enables users to attest controls with proper justification.")]
        $AttestControls = [AttestControls]::None,

        [switch]
        [Parameter(Mandatory = $false, HelpMessage = "Switch to specify whether to open output folder containing all security evaluation report or not.")]
        $DoNotOpenOutputFolder
    )

    $erResourceGroups = $ResourceGroupNames;

    if([string]::IsNullOrEmpty($erResourceGroups))
    {
        $erResourceGroups = [ConfigurationManager]::GetAzSdkConfigData().ERvNetResourceGroupNames
    }

    Get-AzSDKAzureServicesSecurityStatus -SubscriptionId $SubscriptionId -ResourceGroupNames $erResourceGroups -ResourceName $ResourceName `
            -ResourceTypeName "ERvNet" -ControlIds $ControlIds -FilterTags $FilterTags -ExcludeTags $ExcludeTags -DoNotOpenOutputFolder:$DoNotOpenOutputFolder -AttestControls:$AttestControls
}

function Get-AzSDKControlsStatus
{
    <#
    .SYNOPSIS
    This command would help in validating the security controls for the Azure resources meeting the specified input criteria.
    .DESCRIPTION
    This command will execute the security controls and will validate their status as 'Success' or 'Failure' based on the security guidance. Refer https://aka.ms/azsdkdocs for more information
     
    .PARAMETER SubscriptionId
        Subscription id for which the security evaluation has to be performed.
    .PARAMETER ResourceGroupNames
        ResourceGroups for which the security evaluation has to be performed. Comma seperated values are supported. Wildcards are not permitted. By default, the command gets all resources in the subscription.
    .PARAMETER ResourceType
        Gets only resources of the specified resource type. Wildcards are not permitted. e.g.: Microsoft.KeyVault/vaults. Run command 'Get-AzSDKSupportedResourceTypes' to get the list of supported types.
    .PARAMETER ResourceTypeName
        Friendly name of resource type. e.g.: KeyVault. Run command 'Get-AzSDKSupportedResourceTypes' to get the list of supported values.
    .PARAMETER ResourceName
        Gets a resource with the specified name. Wildcards are not permitted. By default, the command gets all resources in the subscription.
    .PARAMETER Tag
        The tag filter for Azure resource. The expected format is @{tagName1=$null} or @{tagName = 'tagValue'; tagName2='value1'}.
    .PARAMETER TagName
        The name of the tag to query for Azure resource.
    .PARAMETER TagValue
        The value of the tag to query for Azure resource.
    .PARAMETER FilterTags
        Comma seperated tags to filter the security controls. e.g.: RBAC, SOX, AuthN etc.
    .PARAMETER ExcludeTags
        Comma seperated tags to exclude the security controls. e.g.: RBAC, SOX, AuthN etc.
    .PARAMETER AttestControls
        Enables users to attest controls with proper justification
    .PARAMETER DoNotOpenOutputFolder
        Switch to specify whether to open output folder containing all security evaluation report or not.
 
    .NOTES
    This command helps the application team to verify whether their Azure resources are compliant with the security guidance or not
 
    .LINK
    https://aka.ms/azsdkdocs
 
    #>

    [OutputType([String])]
    Param
    (

        [string]
        [Parameter(Mandatory = $true, HelpMessage = "Subscription id for which the security evaluation has to be performed.")]
        [ValidateNotNullOrEmpty()]
        $SubscriptionId,

        [string]
        [Parameter(Mandatory = $false, ParameterSetName = "ResourceFilter", HelpMessage = "ResourceGroups for which the security evaluation has to be performed. Comma seperated values are supported. Wildcards are not permitted. By default, the command gets all resources in the subscription.")]
        $ResourceGroupNames,
        
        [string]
        [Parameter(Mandatory = $false, ParameterSetName = "ResourceFilter", HelpMessage = "Gets only resources of the specified resource type. Wildcards are not permitted. e.g.: Microsoft.KeyVault/vaults. Run command 'Get-AzSDKSupportedResourceTypes' to get the list of supported types.")]
        $ResourceType,

        [Parameter(Mandatory = $false, ParameterSetName = "ResourceFilter", HelpMessage = "Friendly name of resource type. e.g.: KeyVault. Run command 'Get-AzSDKSupportedResourceTypes' to get the list of supported values.")]
        [ResourceTypeName]
        $ResourceTypeName = [ResourceTypeName]::All,
        
        [string]
        [Parameter(Mandatory = $false, ParameterSetName = "ResourceFilter", HelpMessage = "Gets a resource with the specified name. Wildcards are not permitted. By default, the command gets all resources in the subscription.")]
        $ResourceName,
    
        [Hashtable] 
        [Parameter(Mandatory = $true, ParameterSetName = "TagHashset", HelpMessage = "The tag filter for Azure resource. The expected format is @{tagName1=`$null} or @{tagName = 'tagValue'; tagName2='value1'}.")]
        $Tag,

        [string]
        [Parameter(Mandatory = $true, ParameterSetName = "TagName", HelpMessage = "The name of the tag to query for Azure resource.")]
        $TagName,

        [string]
        [Parameter(Mandatory = $true, ParameterSetName = "TagName", HelpMessage = "The value of the tag to query for Azure resource.")]
        $TagValue,

        [string] 
        [Parameter(Mandatory = $false, HelpMessage = "Comma seperated control ids to filter the security controls. e.g.: Azure_Subscription_AuthZ_Limit_Admin_Owner_Count, Azure_Storage_DP_Encrypt_At_Rest_Blob etc.")]
        $ControlIds,

        [string] 
        [Parameter(Mandatory = $false, HelpMessage = "Comma seperated tags to filter the security controls. e.g.: RBAC, SOX, AuthN etc.")]
        $FilterTags,

        [string] 
        [Parameter(Mandatory = $false, HelpMessage = "Comma seperated tags to exclude the security controls. e.g.: RBAC, SOX, AuthN etc.")]
        $ExcludeTags,
                
        [AttestControls]
        [Parameter(Mandatory = $false, HelpMessage = "Enables users to attest controls with proper justification.")]
        $AttestControls = [AttestControls]::None,

        [switch]
        [Parameter(Mandatory = $false, HelpMessage = "Switch to specify whether to open output folder containing all security evaluation report or not.")]
        $DoNotOpenOutputFolder
    )
    Begin
    {
        [ListenerHelper]::RegisterListeners();
    }
    Process
    {
     try 
        {
            $resolver = [SVTResourceResolver]::new($SubscriptionId, $ResourceGroupNames);
            $resolver.ResourceName = $ResourceName; 
            $resolver.ResourceType = $ResourceType;
            $resolver.ResourceTypeName = $ResourceTypeName;
            $resolver.Tag = $Tag;
            $resolver.TagName = $TagName;
            $resolver.TagValue = $TagValue;
        
            $controlReport = [SVTStatusReport]::new($SubscriptionId, $PSCmdlet.MyInvocation, $resolver);
            if ($controlReport) 
            {
                # Just copy all the tags without validation. Validation will be done internally
                $controlReport.FilterTags = $FilterTags;
                $controlReport.ExcludeTags = $ExcludeTags;
                $controlReport.ControlIds = $ControlIds;
                $controlReport.AttestControls = $AttestControls;

                return $controlReport.EvaluateControlStatus();
            }    
        }
        catch 
        {
            [EventBase]::PublishGenericException($_);
        }  
    }
    End
    {
        [ListenerHelper]::UnregisterListeners();
    }
}