AzReports.psm1

#Region '.\Private\CheckAzContext.ps1' 0
function CheckAzContext {
    if (-not (Get-AzContext).Account) {
        Connect-AzAccount
    }
}
#EndRegion '.\Private\CheckAzContext.ps1' 6
#Region '.\Private\CheckPath.ps1' 0
function CheckPath {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [System.IO.FileInfo]
        $Path,

        [string]
        $Extension,

        [switch]
        $Force
    )

    if ($Extension) {
        if ($Path.Extension -ne $Extension) {
            throw "File extension must be $( $Extension )!"
        }
    }

    if (Test-Path -Path $Path.DirectoryName) {
        if (Test-Path -Path $Path.FullName) {
            if ($Force) {
                [void](Remove-Item -Path $Path.FullName -Force)
            } else {
                throw "$( $Path.FullName ) already exists, pass -Force to overwrite!"
            }
        }
    } else {
        [void](New-Item -Path $Path.DirectoryName -ItemType Directory -Force)
    }
}
#EndRegion '.\Private\CheckPath.ps1' 33
#Region '.\Private\SearchAzGraph.ps1' 0
function SearchAzGraph {
    [CmdletBinding()]
    param(
        [string]
        $Query
    )

    try {
        $results = [System.Collections.ArrayList]::new()

        $responses = Search-AzGraph -Query $query -First 100

        $results.AddRange([array]$responses)

        while ($responses.SkipToken) {
            $responses = Search-AzGraph -Query $query -SkipToken $responses.SkipToken

            $results.AddRange([array]$responses)
        }

        return $results.ToArray()
    } catch {
        throw $PSItem
    }
}
#EndRegion '.\Private\SearchAzGraph.ps1' 26
#Region '.\Public\New-AzReportsAppInsights.ps1' 0
#requires -Modules ImportExcel

function New-AzReportsAppInsights {
    <#
    .SYNOPSIS
        Creates an Excel spreadsheet report with the details for Azure ApplicationInsights
    .DESCRIPTION
        Creates an Excel spreadsheet report with the details for Azure ApplicationInsights
    .EXAMPLE
        PS C:\> New-AzReportsAppInsights -Path .\temp\AppInsights.xlsx -Force
 
        Creates a report of the Azure ApplicationInsights and if the Path already exists it overwrites it.
    .INPUTS
        None
    .OUTPUTS
        Excel Spreadsheet
    #>

    [CmdletBinding()]
    param(
        # Path to create the Excel report. Must end with '.xlsx'.
        [Parameter(Mandatory)]
        [System.IO.FileInfo]
        $Path,

        # Only generate report for the current Azure Subscription.
        [switch]
        $Current,

        # Do not automatically open the generated Excel spreadsheet.
        [switch]
        $NoInvoke,

        # Overwrite existing Excel spreadsheet.
        [switch]
        $Force
    )
    $InformationPreference = 'Continue'
    $env:SuppressAzurePowerShellBreakingChangeWarnings = 'true'

    try {
        CheckAzContext

        CheckPath -Path $Path -Extension '.xlsx' -Force:$Force -ErrorAction Stop

        $currentSubscription = Get-AzSubscription -SubscriptionId (Get-AzContext).Subscription.Id

        if ($Current) {
            $subscriptions = $currentSubscription
        } else {
            $subscriptions = Get-AzSubscription
        }

        $appInsightsReport = @()

        foreach ($subscription in $subscriptions) {

            Write-Information "Setting Azure Context to Subscription: $( $subscription.Name )"
            $null = Set-AzContext -SubscriptionId $subscription.Id

            $appInsights = Get-AzApplicationInsights

            Write-Information "AppInsights Count: $( $appInsights.Count )"

            foreach ($appInsight in $appInsights) {
                $insight = Get-AzApplicationInsights -ResourceGroupName $appInsight.ResourceGroupName -Name $appInsight.Name
                $appInsightsReport += [PSCustomObject]@{
                    'Subscription Id'                     = $subscription.Id
                    'Subscription Name'                   = $subscription.Name
                    'Resource Group Name'                 = $insight.ResourceGroupName
                    Name                                  = $insight.Name
                    Id                                    = $insight.Id
                    'App Id'                              = $insight.AppId
                    'Application Id'                      = $insight.ApplicationId
                    'Application Type'                    = $insight.ApplicationType
                    'Creation Date'                       = $insight.CreationDate
                    'Disable IP Masking'                  = $insight.DisableIPMasking
                    'Disable Local Auth'                  = $insight.DisableLocalAuth
                    'Immediate Purge Data on 30 Day'      = $insight.ImmediatePurgeDataOn30Day
                    'Ingestion Mode'                      = $insight.IngestionMode
                    Kind                                  = $insight.Kind
                    Location                              = $insight.Location
                    'Private Link Scoped Resource'        = $insight.PrivateLinkScopedResource
                    'Provisioning State'                  = $insight.ProvisioningState
                    'Public Network Access for Ingestion' = $insight.PublicNetworkAccessForIngestion
                    'Public Network Access for Query'     = $insight.PublicNetworkAccessForQuery
                    'Retention In Day'                    = $insight.RetentionInDay
                    'Sampling Percentage'                 = $insight.SamplingPercentage
                    Type                                  = $insight.Type
                    'Workspace Resource Id'               = $insight.WorkspaceResourceId
                }
            }
        }

        $excelSplat = @{
            Path          = $Path
            WorksheetName = 'AppInsights'
            TableStyle    = 'Medium2'
            AutoSize      = $true
            FreezeTopRow  = $true
            Style         = $excelStyle
            PassThru      = $true
        }

        $excel = $appInsightsReport |
            Sort-Object -Property 'Subscription Name', 'Resource Group Name', Name |
            Export-Excel @excelSplat

        $workSheet = $excel.Workbook.Worksheets[$excelSplat.WorksheetName]

        Set-ExcelRow -Worksheet $workSheet -Row 1 -Bold -HorizontalAlignment Center

        Set-ExcelColumn -Worksheet $workSheet -Column 1 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 2 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 3 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 4 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 5 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 6 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 7 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 8 -AutoSize

        if ($NoInvoke) {
            Close-ExcelPackage -ExcelPackage $excel
        } else {
            Close-ExcelPackage -ExcelPackage $excel -Show
        }

        if ((Get-AzContext).Subscription.Id -ne $currentSubscription.Id) {
            Write-Information "Setting Azure Context to Subscription: $( $currentSubscription.Name )"
            $null = Set-AzContext -SubscriptionId $currentSubscription.Id
        }
    } catch {
        throw $PSItem
    }
}
#EndRegion '.\Public\New-AzReportsAppInsights.ps1' 135
#Region '.\Public\New-AzReportsAppServices.ps1' 0
#requires -Modules ImportExcel

function New-AzReportsAppServices {
    <#
    .SYNOPSIS
        Creates an Excel spreadsheet report with the details for Azure App Services
    .DESCRIPTION
        Creates an Excel spreadsheet report with the details for Azure App Services
    .EXAMPLE
        PS C:\> New-AzReportsAppServices -Path .\temp\AppServices.xlsx -Force
 
        Creates a report of the Azure App Services and if the Path already exists it overwrites it.
    .INPUTS
        None
    .OUTPUTS
        Excel Spreadsheet
    #>

    [CmdletBinding()]
    param(
        # Path to create the Excel report. Must end with '.xlsx'.
        [Parameter(Mandatory)]
        [System.IO.FileInfo]
        $Path,

        # Only generate report for the current Azure Subscription.
        [switch]
        $Current,

        # Do not automatically open the generated Excel spreadsheet.
        [switch]
        $NoInvoke,

        # Overwrite existing Excel spreadsheet.
        [switch]
        $Force
    )
    $InformationPreference = 'Continue'
    $env:SuppressAzurePowerShellBreakingChangeWarnings = 'true'

    try {
        CheckAzContext

        CheckPath -Path $Path -Extension '.xlsx' -Force:$Force -ErrorAction Stop

        $currentSubscription = Get-AzSubscription -SubscriptionId (Get-AzContext).Subscription.Id

        if ($Current) {
            $subscriptions = $currentSubscription
        } else {
            $subscriptions = Get-AzSubscription
        }

        $report = @()

        foreach ($subscription in $subscriptions) {

            Write-Information "Setting Azure Context to Subscription: $( $subscription.Name )"
            $null = Set-AzContext -SubscriptionId $subscription.Id

            $plans = Get-AzAppServicePlan

            Write-Information "App Service Plans Count: $( $plans.Count )"

            foreach ($plan in $plans) {
                $appServices = Get-AzWebApp -AppServicePlan $plan

                Write-Information "App Service Plan - $( $plan.Name ) - App Services Count: $( $appServices.Count )"

                foreach ($appService in $appServices) {
                    $service = Get-AzWebApp -ResourceGroupName $appService.ResourceGroup -Name $appService.Name

                    Write-Information "Processing App Service - $( $service.Name )..."

                    if ($service.VirtualNetworkSubnetId) {
                        $vnetName = $service.VirtualNetworkSubnetId.Split('/')[8]
                        $subnetName = $service.VirtualNetworkSubnetId.Split('/')[-1]
                    } else {
                        $vnetName = $null
                        $subnetName = $null
                    }

                    $report += [PSCustomObject]@{
                        'Subscription Id'                              = $subscription.Id
                        'Subscription Name'                            = $subscription.Name
                        'Plan Resource Group Name'                     = $plan.ResourceGroup
                        'Plan Name'                                    = $plan.Name
                        'Plan Kind'                                    = $plan.Kind
                        'Plan Sku'                                     = $plan.Sku.Name
                        'Resource Group Name'                          = $service.ResourceGroup
                        Name                                           = $service.Name
                        Kind                                           = $service.Kind
                        Location                                       = $service.Location
                        'Default Host Name'                            = $service.DefaultHostName
                        'Https Only'                                   = $service.HttpsOnly
                        'Virtual Network Name'                         = $vnetName
                        'Subnet Name'                                  = $subnetName
                        'Site Config AlwaysOn'                         = $service.SiteConfig.AlwaysOn
                        'Site Config FtpsState'                        = $service.SiteConfig.FtpsState
                        'Site Config Http20Enabled'                    = $service.SiteConfig.Http20Enabled
                        'Site Config HttpLoggingEnabled'               = $service.SiteConfig.HttpLoggingEnabled
                        'Site Config IpSecurityRestrictions'           = $service.SiteConfig.IpSecurityRestrictions.Name -join ', '
                        'Site Config JavaVersion'                      = $service.SiteConfig.JavaVersion
                        'Site Config LinuxFxVersion'                   = $service.SiteConfig.LinuxFxVersion
                        'Site Config MinTlsVersion'                    = $service.SiteConfig.MinTlsVersion
                        'Site Config NetFrameworkVersion'              = $service.SiteConfig.NetFrameworkVersion
                        'Site Config NodeVersion'                      = $service.SiteConfig.NodeVersion
                        'Site Config PhpVersion'                       = $service.SiteConfig.PhpVersion
                        'Site Config PowerShellVersion'                = $service.SiteConfig.PowerShellVersion
                        'Site Config PythonVersion'                    = $service.SiteConfig.PythonVersion
                        'Site Config RemoteDebuggingEnabled'           = $service.SiteConfig.RemoteDebuggingEnabled
                        'Site Config RequestTracingEnabled'            = $service.SiteConfig.RequestTracingEnabled
                        'Site Config ScmIpSecurityRestrictions'        = $service.SiteConfig.ScmIpSecurityRestrictions.Name -join ', '
                        'Site Config ScmIpSecurityRestrictionsUseMain' = $service.SiteConfig.ScmIpSecurityRestrictionsUseMain
                        'Site Config ScmMinTlsVersion'                 = $service.SiteConfig.ScmMinTlsVersion
                        'Site Config ScmType'                          = $service.SiteConfig.ScmType
                        'Site Config Use32BitWorkerProcess'            = $service.SiteConfig.Use32BitWorkerProcess
                        'Site Config VnetRouteAllEnabled'              = $service.SiteConfig.VnetRouteAllEnabled
                        'Site Config WebSocketsEnabled'                = $service.SiteConfig.WebSocketsEnabled
                        'Site Config WindowsFxVersion'                 = $service.SiteConfig.WindowsFxVersion
                    }
                }
            }
        }

        $excelSplat = @{
            Path          = $Path
            WorksheetName = 'AppInsights'
            TableStyle    = 'Medium2'
            AutoSize      = $true
            FreezeTopRow  = $true
            Style         = $excelStyle
            PassThru      = $true
        }

        $excel = $report |
            Sort-Object -Property 'Subscription Name', 'Plan Resource Group Name', 'Plan Name', 'Resource Group Name', Name |
            Export-Excel @excelSplat

        $workSheet = $excel.Workbook.Worksheets[$excelSplat.WorksheetName]

        Set-ExcelRow -Worksheet $workSheet -Row 1 -Bold -HorizontalAlignment Center

        Set-ExcelColumn -Worksheet $workSheet -Column 1 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 2 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 3 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 4 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 5 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 6 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 7 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 8 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 9 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 10 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 11 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 12 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 13 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 14 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 15 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 16 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 17 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 18 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 19 -HorizontalAlignment Left -Width 50 -WrapText
        Set-ExcelColumn -Worksheet $workSheet -Column 20 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 21 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 22 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 23 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 24 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 25 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 26 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 27 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 28 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 29 -HorizontalAlignment Left -Width 50 -WrapText
        Set-ExcelColumn -Worksheet $workSheet -Column 30 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 31 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 32 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 33 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 34 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 35 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 36 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 37 -AutoSize

        if ($NoInvoke) {
            Close-ExcelPackage -ExcelPackage $excel
        } else {
            Close-ExcelPackage -ExcelPackage $excel -Show
        }

        if ((Get-AzContext).Subscription.Id -ne $currentSubscription.Id) {
            Write-Information "Setting Azure Context to Subscription: $( $currentSubscription.Name )"
            $null = Set-AzContext -SubscriptionId $currentSubscription.Id
        }
    } catch {
        throw $PSItem
    }
}
#EndRegion '.\Public\New-AzReportsAppServices.ps1' 195
#Region '.\Public\New-AzReportsPolicyAssignment.ps1' 0
#requires -Modules ImportExcel

function New-AzReportsPolicyAssignment {
    <#
    .SYNOPSIS
        Creates an Excel spreadsheet report with the details for Azure Policy Assignment
    .DESCRIPTION
        Creates an Excel spreadsheet report with the details for Azure Policy Assignment
    .EXAMPLE
        PS C:\> New-AzReportsPolicyAssignment -Path .\temp\SecurityCenterBuiltIn.xlsx -Name SecurityCenterBuiltIn -Force
 
        Creates a report of the Azure Policy Assignment and if the Path already exists it overwrites it.
    .INPUTS
        None
    .OUTPUTS
        Excel Spreadsheet
    #>

    [CmdletBinding()]
    param(
        # Path to create the Excel report. Must end with '.xlsx'.
        [Parameter(Mandatory)]
        [System.IO.FileInfo]
        $Path,

        [string]
        $Name,

        # Do not automatically open the generated Excel spreadsheet.
        [switch]
        $NoInvoke,

        # Overwrite existing Excel spreadsheet.
        [switch]
        $Force
    )
    $InformationPreference = 'Continue'
    $env:SuppressAzurePowerShellBreakingChangeWarnings = 'true'

    try {
        CheckAzContext

        CheckPath -Path $Path -Extension '.xlsx' -Force:$Force -ErrorAction Stop

        if ($Name) {
            $policyAssignments = Get-AzPolicyAssignment -Name $Name
        } else {
            $policyAssignments = Get-AzPolicyAssignment
        }

        $objects = @()

        foreach ( $policyAssignment in $policyAssignments) {
            if ($policyAssignment.Properties.Parameters) {
                $objects += GetPolicyAssignmentParameters -PolicyAssignment $policyAssignment
            } else {
                Write-Information "Policy Assignment: $( $policyAssignment.Properties.DisplayName ) - has no parameters."

                $objects += [PSCustomObject]@{
                    Name             = $policyAssignment.Name
                    'Display Name'   = $policyAssignment.Properties.DisplayName
                    Scope            = $policyAssignment.Properties.Scope
                    'Parameter Name' = $null
                    Value            = $null
                }
            }
        }

        $excelSplat = @{
            Path          = $Path
            WorksheetName = 'PolicyAssignment'
            TableStyle    = 'Medium2'
            AutoSize      = $true
            FreezeTopRow  = $true
            Style         = $excelStyle
            PassThru      = $true
        }

        $excel = $objects |
            Sort-Object -Property Category, Name |
            Export-Excel @excelSplat

        $workSheet = $excel.Workbook.Worksheets[$excelSplat.WorksheetName]

        Set-ExcelRow -Worksheet $workSheet -Row 1 -Bold -HorizontalAlignment Center

        Set-ExcelColumn -Worksheet $workSheet -Column 1 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 2 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 3 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 4 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 5 -AutoSize

        if ($NoInvoke) {
            Close-ExcelPackage -ExcelPackage $excel
        } else {
            Close-ExcelPackage -ExcelPackage $excel -Show
        }
    } catch {
        throw $PSItem
    }
}
#EndRegion '.\Public\New-AzReportsPolicyAssignment.ps1' 101
#Region '.\Public\New-AzReportsPolicyDefinition.ps1' 0
#requires -Modules ImportExcel

function New-AzReportsPolicyDefinition {
    <#
    .SYNOPSIS
        Creates an Excel spreadsheet report with the details for Azure Policy Definitions.
    .DESCRIPTION
        Creates an Excel spreadsheet report with the details for Azure Policy Definitions.
    .EXAMPLE
        PS C:\> New-AzReportsPolicyDefinition -Path .\BuiltInPolicies -BuiltIn -Force
 
        Creates a report of the BuiltIn Azure Policy Definitions and if the Path already exists it overwrites it.
    .EXAMPLE
        PS C:\> New-AzReportsPolicyDefinition -Path .\CustomPolicies -Custom -Force
 
        Creates a report of the custom Azure Policy Definitions and if the Path already exists it overwrites it.
    .EXAMPLE
        PS C:\> New-AzReportsPolicyDefinition -Path .\CustomPolicies
 
        Creates a report of all Azure Policy Definitions.
    .INPUTS
        None
    .OUTPUTS
        Excel Spreadsheet
    #>

    [CmdletBinding(DefaultParameterSetName = 'Default')]
    param(
        # Path to create the Excel report. Must end with '.xlsx'.
        [Parameter(Mandatory)]
        [Parameter(ParameterSetName = 'Default')]
        [Parameter(ParameterSetName = 'BuiltIn')]
        [Parameter(ParameterSetName = 'Custom')]
        [System.IO.FileInfo]
        $Path,

        # Only output BuiltIn Azure Policy Definitions.
        [Parameter(ParameterSetName = 'BuiltIn')]
        [switch]
        $BuiltIn,

        #Only output Custom Azure Policy Definitions.
        [Parameter(ParameterSetName = 'Custom')]
        [switch]
        $Custom,

        # Do not automatically open the generated Excel spreadsheet.
        [Parameter(ParameterSetName = 'Default')]
        [Parameter(ParameterSetName = 'BuiltIn')]
        [Parameter(ParameterSetName = 'Custom')]
        [switch]
        $NoInvoke,

        # Overwrite existing Excel spreadsheet.
        [Parameter(ParameterSetName = 'Default')]
        [Parameter(ParameterSetName = 'BuiltIn')]
        [Parameter(ParameterSetName = 'Custom')]
        [switch]
        $Force
    )
    $InformationPreference = 'Continue'

    CheckAzContext

    CheckPath -Path $Path -Extension '.xlsx' -Force:$Force

    if ($PSBoundParameters.Keys -contains 'BuiltIn') {
        $policyDefinitions = Get-AzPolicyDefinition -Builtin
    } elseif ($PSBoundParameters.Keys -contains 'Custom') {
        $policyDefinitions = Get-AzPolicyDefinition -Custom
    } else {
        $policyDefinitions = Get-AzPolicyDefinition
    }

    $objects = @()

    foreach ($policyDefinition in $policyDefinitions) {
        Write-Information "Policy Name: $($policyDefinition.Properties.DisplayName)"

        $item = [ordered]@{
            Name                     = $policyDefinition.Name
            Category                 = $policyDefinition.Properties.Metadata.category
            Type                     = $policyDefinition.Properties.PolicyType
            'Display Name'           = $policyDefinition.Properties.DisplayName
            Description              = $policyDefinition.Properties.Description
            'Resource Id'            = $policyDefinition.ResourceId
            'Available Effects'      = $policyDefinition.Properties.PolicyRule.then.effect
            'Parameter Name'         = $null
            'Parameter Type'         = $null
            'Parameter Display Name' = $null
            'Parameter Description'  = $null
            'Allowed Values'         = $null
            'Default Value'          = $null
            'Desired Value'          = $null
        }

        if ($policyDefinition.Properties.Parameters) {
            $parameters = $policyDefinition.Properties.Parameters.PSObject.Members |
                Where-Object { $_.MemberType -eq 'NoteProperty' } |
                Select-Object -ExpandProperty Name

            foreach ($parameter in $parameters) {
                Write-Information "Parameter Name: $parameter"
                $item.'Parameter Name' = $parameter
                $item.'Parameter Type' = $policyDefinition.Properties.Parameters.$parameter.type
                $item.'Parameter Display Name' = $policyDefinition.Properties.Parameters.$parameter.metadata.displayName
                $item.'Parameter Description' = $policyDefinition.Properties.Parameters.$parameter.metadata.description
                $item.'Allowed Values' = $policyDefinition.Properties.Parameters.$parameter.allowedValues -join ', '

                if ($policyDefinition.Properties.Parameters.$parameter.type -eq 'Object') {
                    $item.'Default Value' = $policyDefinition.Properties.Parameters.$parameter.defaultValue |
                        ConvertTo-Json -Compress
                } else {
                    $item.'Default Value' = $policyDefinition.Properties.Parameters.$parameter.defaultValue -join ', '
                }

                $objects += [PSCustomObject]$item
            }

        } else {
            $objects += [PSCustomObject]$item
        }
    }

    $excelStyle = New-ExcelStyle -VerticalAlignment Top

    $excelSplat = @{
        Path          = $Path
        WorksheetName = 'Policies'
        TableStyle    = 'Medium2'
        AutoSize      = $true
        FreezeTopRow  = $true
        Style         = $excelStyle
        PassThru      = $true
    }

    $excel = $objects |
        Sort-Object -Property Category, 'Display Name', 'Parameter Name' |
        Export-Excel @excelSplat

    $workSheet = $excel.Workbook.Worksheets[$excelSplat.WorksheetName]

    Set-ExcelRow -Worksheet $workSheet -Row 1 -Bold -HorizontalAlignment Center

    Set-ExcelColumn -Worksheet $workSheet -Column 1 -AutoSize -Hide
    Set-ExcelColumn -Worksheet $workSheet -Column 2 -AutoSize -HorizontalAlignment Center
    Set-ExcelColumn -Worksheet $workSheet -Column 3 -AutoSize -HorizontalAlignment Center
    Set-ExcelColumn -Worksheet $workSheet -Column 4 -Width 50 -WrapText
    Set-ExcelColumn -Worksheet $workSheet -Column 5 -Width 60 -WrapText
    Set-ExcelColumn -Worksheet $workSheet -Column 6 -AutoSize -HorizontalAlignment Left
    Set-ExcelColumn -Worksheet $workSheet -Column 7 -AutoSize -HorizontalAlignment Center
    Set-ExcelColumn -Worksheet $workSheet -Column 8 -Width 50 -WrapText -HorizontalAlignment Center
    Set-ExcelColumn -Worksheet $workSheet -Column 9 -AutoSize -HorizontalAlignment Center
    Set-ExcelColumn -Worksheet $workSheet -Column 10 -Width 50 -WrapText
    Set-ExcelColumn -Worksheet $workSheet -Column 11 -Width 50 -WrapText
    Set-ExcelColumn -Worksheet $workSheet -Column 12 -Width 50 -WrapText -HorizontalAlignment Center
    Set-ExcelColumn -Worksheet $workSheet -Column 13 -Width 50 -WrapText -HorizontalAlignment Center
    Set-ExcelColumn -Worksheet $workSheet -Column 14 -Width 50 -WrapText -HorizontalAlignment Center

    if ($NoInvoke) {
        Close-ExcelPackage -ExcelPackage $excel
    } else {
        Close-ExcelPackage -ExcelPackage $excel -Show
    }
}
#EndRegion '.\Public\New-AzReportsPolicyDefinition.ps1' 165
#Region '.\Public\New-AzReportsRegion.ps1' 0
function New-AzReportsRegion {
    <#
    .SYNOPSIS
        Creates an Markdown file report with the details for Azure Policy Assignment
    .DESCRIPTION
        Creates an Markdown file report with the details for Azure Policy Assignment
    .EXAMPLE
        PS C:\> New-AzReportsPolicyAssignment -Path .\temp\SecurityCenterBuiltIn.xlsx -Name SecurityCenterBuiltIn -Force
 
        Creates a report of the Azure Policy Assignment and if the Path already exists it overwrites it.
    .INPUTS
        None
    .OUTPUTS
        Markdown File
    #>

    [CmdletBinding()]
    param(
        # Path to create the Markdown report. Must end with '.md'.
        [System.IO.FileInfo]
        $Path,

        # Do not automatically open the generated Markdown file.
        [switch]
        $NoInvoke,

        # Overwrite existing Markdown file.
        [switch]
        $Force
    )
    CheckAzContext

    if ($Path) {
        CheckPath -Path $Path -Extension '.md' -Force:$Force
    }

    $azRegions = Get-AzLocation |
        Sort-Object -Property DisplayName

    $customAzRegions = [System.Collections.ArrayList]@()

    foreach ($azRegion in $azRegions) {
        $shortLocation = ''
        $shortLocationSubstitions = @(
            @{
                Southeast = 'SE'
            }
        )
        $displayNameComponents = $azRegion.DisplayName.Split(' ')

        foreach ($displayNameComponent in $displayNameComponents) {
            if ($shortLocationSubstitions.Keys -contains $displayNameComponent) {
                $shortLocation += $shortLocationSubstitions.$displayNameComponent
            } elseif ([Int]::TryParse($displayNameComponent, [ref]$null)) {
                $shortLocation += $displayNameComponent
            } else {
                $shortLocation += $displayNameComponent -creplace '[^A-Z]'
            }
        }

        $customAzRegions += [PSCustomObject]@{
            'Display Name'        = $azRegion.DisplayName
            Region                = $azRegion.Location
            'Region Length'       = $azRegion.Location.Length
            'Short Region'        = $shortLocation.ToLower()
            'Short Region Length' = $shortLocation.Length
        }
    }

    $headers = $customAzRegions |
        Get-Member -MemberType NoteProperty |
        Select-Object -ExpandProperty Name

    $sbTable = [System.Text.StringBuilder]'|'

    $headerPadding = @{}

    foreach ($header in $headers) {
        $headerValueLengths = $customAzRegions.'Display Name' |
            Select-Object -ExpandProperty Length -Unique |
            Sort-Object -Descending

        if ($header.Length -gt $headerValueLengths[0]) {
            $headerPadding.$header = $header.Length
        } else {
            $headerPadding.$header = $headerValueLengths[0]
        }

        $null = $sbTable.Append((' {0} |' -f $header.PadRight($headerPadding.$header, ' ')))
    }

    $null = $sbTable.AppendLine('')
    $null = $sbTable.Append('|')

    foreach ($header in $headers) {
        $null = $sbTable.Append((' {0} |' -f ''.PadRight($headerPadding.$header, '-')))
    }

    $null = $sbTable.AppendLine('')

    foreach ($customAzRegion in $customAzRegions) {
        $null = $sbTable.Append('|')

        foreach ($header in $headers) {
            $null = $sbTable.Append((' {0} |' -f $customAzRegion.$header.ToString().PadRight($headerPadding.$header, ' ')))
        }

        $null = $sbTable.AppendLine('')
    }

    if ($Path) {
        $sbTable.ToString() |
            Out-File -FilePath $Path.FullName

        if (-not $NoInvoke) {
            Invoke-Item -Path $Path.FullName
        }
    } else {
        $sbTable.ToString()
    }
}
#EndRegion '.\Public\New-AzReportsRegion.ps1' 121
#Region '.\Public\New-AzReportsResources.ps1' 0
#requires -Modules ImportExcel

function New-AzReportsResources {
    <#
    .SYNOPSIS
        Creates an Excel spreadsheet report with the details for Azure Storage Accounts
    .DESCRIPTION
        Creates an Excel spreadsheet report with the details for Azure Storage Accounts
    .EXAMPLE
        PS C:\> New-AzReportsRgResources -Path .\temp\RgResources.xlsx -Force
 
        Creates a report of the Azure Storage Accounts and if the Path already exists it overwrites it.
    .INPUTS
        None
    .OUTPUTS
        Excel Spreadsheet
    #>

    [CmdletBinding()]
    param(
        # Path to create the Excel report. Must end with '.xlsx'.
        [Parameter(Mandatory)]
        [System.IO.FileInfo]
        $Path,

        # Do not automatically open the generated Excel spreadsheet.
        [switch]
        $NoInvoke,

        # Overwrite existing Excel spreadsheet.
        [switch]
        $Force
    )
    $InformationPreference = 'Continue'
    $env:SuppressAzurePowerShellBreakingChangeWarnings = 'true'

    try {
        CheckAzContext

        CheckPath -Path $Path -Extension '.xlsx' -Force:$Force -ErrorAction Stop

        $subscription = Get-AzSubscription -SubscriptionId (Get-AzContext).Subscription.Id

        $resources = Get-AzResource

        Write-Information "Resources Count: $( $resources.Count )"

        $report = @()

        for ($i = 0; $i -lt $resources.Count; $i++) {
            Write-Information "Getting Report Info for Resource: $( $i + 1 ) of $( $resources.Count )"

            $report += [PSCustomObject]@{
                'Subscription Id'     = $subscription.Id
                'Subscription Name'   = $subscription.Name
                'Resource Group Name' = $resources[$i].ResourceGroupName
                Type                  = $resources[$i].Type
                Name                  = $resources[$i].Name
                Location              = $resources[$i].Location
                Id                    = $resources[$i].Id
                ChangedTime           = $resources[$i].ChangedTime
                CreatedTime           = $resources[$i].CreatedTime
                ExtensionResourceName = $resources[$i].ExtensionResourceName
                ExtensionResourceType = $resources[$i].ExtensionResourceType
                Kind                  = $resources[$i].Kind
                ManagedBy             = $resources[$i].ManagedBy
                ParentResource        = $resources[$i].ParentResource
                Plan                  = $resources[$i].Plan
            }
        }

        $excelSplat = @{
            Path          = $Path
            WorksheetName = 'Resources'
            TableStyle    = 'Medium2'
            AutoSize      = $true
            FreezeTopRow  = $true
            Style         = $excelStyle
            PassThru      = $true
        }

        $excel = $report |
            Sort-Object -Property 'Subscription Name', 'Resource Group Name', Type, Name |
            Export-Excel @excelSplat

        $workSheet = $excel.Workbook.Worksheets[$excelSplat.WorksheetName]

        Set-ExcelRow -Worksheet $workSheet -Row 1 -Bold -HorizontalAlignment Center

        if ($NoInvoke) {
            Close-ExcelPackage -ExcelPackage $excel
        } else {
            Close-ExcelPackage -ExcelPackage $excel -Show
        }
    } catch {
        throw $PSItem
    }
}
#EndRegion '.\Public\New-AzReportsResources.ps1' 98
#Region '.\Public\New-AzReportsRgResources.ps1' 0
#requires -Modules ImportExcel

function New-AzReportsRgResources {
    <#
    .SYNOPSIS
        Creates an Excel spreadsheet report with the details for Azure Storage Accounts
    .DESCRIPTION
        Creates an Excel spreadsheet report with the details for Azure Storage Accounts
    .EXAMPLE
        PS C:\> New-AzReportsRgResources -Path .\temp\RgResources.xlsx -Force
 
        Creates a report of the Azure Storage Accounts and if the Path already exists it overwrites it.
    .INPUTS
        None
    .OUTPUTS
        Excel Spreadsheet
    #>

    [CmdletBinding()]
    param(
        # Path to create the Excel report. Must end with '.xlsx'.
        [Parameter(Mandatory)]
        [System.IO.FileInfo]
        $Path,

        # Name of the Resource Group.
        [Parameter(Mandatory)]
        [string]
        $ResourceGroupName,

        # Do not automatically open the generated Excel spreadsheet.
        [switch]
        $NoInvoke,

        # Overwrite existing Excel spreadsheet.
        [switch]
        $Force
    )
    $InformationPreference = 'Continue'
    $env:SuppressAzurePowerShellBreakingChangeWarnings = 'true'

    try {
        CheckAzContext

        CheckPath -Path $Path -Extension '.xlsx' -Force:$Force -ErrorAction Stop

        $subscription = Get-AzSubscription -SubscriptionId (Get-AzContext).Subscription.Id

        $null = Get-AzResourceGroup -Name $ResourceGroupName -ErrorAction Stop

        $resources = Get-AzResource -ResourceGroupName $ResourceGroupName

        Write-Information "Resources Count: $( $resources.Count )"

        $report = @()

        for ($i = 0; $i -lt $resources.Count; $i++) {
            Write-Information "Getting Report Info for Resource: $( $i + 1 ) of $( $resources.Count )"

            $report += [PSCustomObject]@{
                'Subscription Id'     = $subscription.Id
                'Subscription Name'   = $subscription.Name
                'Resource Group Name' = $resources[$i].ResourceGroupName
                Name                  = $resources[$i].Name
                Location              = $resources[$i].Location
                Type                  = $resources[$i].Type
                Id                    = $resources[$i].Id
                ChangedTime           = $resources[$i].ChangedTime
                CreatedTime           = $resources[$i].CreatedTime
                ExtensionResourceName = $resources[$i].ExtensionResourceName
                ExtensionResourceType = $resources[$i].ExtensionResourceType
                Kind                  = $resources[$i].Kind
                ManagedBy             = $resources[$i].ManagedBy
                ParentResource        = $resources[$i].ParentResource
                Plan                  = $resources[$i].Plan
            }
        }

        $excelSplat = @{
            Path          = $Path
            WorksheetName = $ResourceGroupName
            TableStyle    = 'Medium2'
            AutoSize      = $true
            FreezeTopRow  = $true
            Style         = $excelStyle
            PassThru      = $true
        }

        $excel = $report |
            Sort-Object -Property 'Subscription Name', 'Resource Group Name', Name |
            Export-Excel @excelSplat

        $workSheet = $excel.Workbook.Worksheets[$excelSplat.WorksheetName]

        Set-ExcelRow -Worksheet $workSheet -Row 1 -Bold -HorizontalAlignment Center

        if ($NoInvoke) {
            Close-ExcelPackage -ExcelPackage $excel
        } else {
            Close-ExcelPackage -ExcelPackage $excel -Show
        }
    } catch {
        throw $PSItem
    }
}
#EndRegion '.\Public\New-AzReportsRgResources.ps1' 105
#Region '.\Public\New-AzReportsRoleAssignment.ps1' 0
#requires -Modules ImportExcel

function New-AzReportsRoleAssignment {
    <#
    .SYNOPSIS
        Creates an Excel spreadsheet report with the details for Azure Role Assignments
    .DESCRIPTION
        Creates an Excel spreadsheet report with the details for Azure Role Assignments
    .EXAMPLE
        PS C:\> New-AzReportsRoleAssignment -Path .\temp\RoleAssignment.xlsx -Force
 
        Creates a report of the Azure Role Assignments and if the Path already exists it overwrites it.
    .INPUTS
        None
    .OUTPUTS
        Excel Spreadsheet
    #>

    [CmdletBinding()]
    param(
        # Path to create the Excel report. Must end with '.xlsx'.
        [Parameter(Mandatory)]
        [System.IO.FileInfo]
        $Path,

        # Only generate report for the current Azure Subscription.
        [switch]
        $Current,

        # Do not automatically open the generated Excel spreadsheet.
        [switch]
        $NoInvoke,

        # Overwrite existing Excel spreadsheet.
        [switch]
        $Force
    )
    $InformationPreference = 'Continue'
    $env:SuppressAzurePowerShellBreakingChangeWarnings = 'true'

    try {
        CheckAzContext

        CheckPath -Path $Path -Extension '.xlsx' -Force:$Force -ErrorAction Stop

        $currentSubscription = Get-AzSubscription -SubscriptionId (Get-AzContext).Subscription.Id

        if ($Current) {
            $subscriptions = $currentSubscription
        } else {
            $subscriptions = Get-AzSubscription
        }

        $rolesReport = @()

        foreach ($subscription in $subscriptions) {

            Write-Information "Setting Azure Context to Subscription: $( $subscription.Name )"
            $null = Set-AzContext -SubscriptionId $subscription.Id

            $assignments = Get-AzRoleAssignment

            foreach ($assignment in $assignments) {
                $customRole = (Get-AzRoleDefinition -Name $assignment.RoleDefinitionName).IsCustom

                $rolesReport += [PSCustomObject]@{
                    'Subscription Id'      = $subscription.Id
                    'Subscription Name'    = $subscription.Name
                    'Display Name'         = $assignment.DisplayName
                    'Sign-In Name'         = $assignment.SignInName
                    'Object Type'          = $assignment.ObjectType
                    'Role Definition Name' = $assignment.RoleDefinitionName
                    'Custom Role'          = $customRole
                    'Scope'                = $assignment.Scope
                }
            }
        }

        $excelSplat = @{
            Path          = $Path
            WorksheetName = 'RoleAssignments'
            TableStyle    = 'Medium2'
            AutoSize      = $true
            FreezeTopRow  = $true
            Style         = $excelStyle
            PassThru      = $true
        }

        $excel = $rolesReport |
            Sort-Object -Property 'Subscription Name', 'Display Name', 'Role Definition Name' |
            Export-Excel @excelSplat

        $workSheet = $excel.Workbook.Worksheets[$excelSplat.WorksheetName]

        Set-ExcelRow -Worksheet $workSheet -Row 1 -Bold -HorizontalAlignment Center

        Set-ExcelColumn -Worksheet $workSheet -Column 1 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 2 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 3 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 4 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 5 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 6 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 7 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 8 -AutoSize

        if ($NoInvoke) {
            Close-ExcelPackage -ExcelPackage $excel
        } else {
            Close-ExcelPackage -ExcelPackage $excel -Show
        }

        if ((Get-AzContext).Subscription.Id -ne $currentSubscription.Id) {
            Write-Information "Setting Azure Context to Subscription: $( $currentSubscription.Name )"
            $null = Set-AzContext -SubscriptionId $currentSubscription.Id
        }
    } catch {
        throw $PSItem
    }
}
#EndRegion '.\Public\New-AzReportsRoleAssignment.ps1' 119
#Region '.\Public\New-AzReportsStorageAccount.ps1' 0
#requires -Modules ImportExcel

function New-AzReportsStorageAccount {
    <#
    .SYNOPSIS
        Creates an Excel spreadsheet report with the details for Azure Storage Accounts
    .DESCRIPTION
        Creates an Excel spreadsheet report with the details for Azure Storage Accounts
    .EXAMPLE
        PS C:\> New-AzReportsStorageAccount -Path .\temp\StorageAccount.xlsx -Force
 
        Creates a report of the Azure Storage Accounts and if the Path already exists it overwrites it.
    .INPUTS
        None
    .OUTPUTS
        Excel Spreadsheet
    #>

    [CmdletBinding()]
    param(
        # Path to create the Excel report. Must end with '.xlsx'.
        [Parameter(Mandatory)]
        [System.IO.FileInfo]
        $Path,

        # Only generate report for the current Azure Subscription.
        [switch]
        $Current,

        # Do not automatically open the generated Excel spreadsheet.
        [switch]
        $NoInvoke,

        # Overwrite existing Excel spreadsheet.
        [switch]
        $Force
    )
    $InformationPreference = 'Continue'
    $env:SuppressAzurePowerShellBreakingChangeWarnings = 'true'

    try {
        CheckAzContext

        CheckPath -Path $Path -Extension '.xlsx' -Force:$Force -ErrorAction Stop

        $currentSubscription = Get-AzSubscription -SubscriptionId (Get-AzContext).Subscription.Id

        if ($Current) {
            $subscriptions = $currentSubscription
        } else {
            $subscriptions = Get-AzSubscription
        }

        $storageAccountReport = @()

        foreach ($subscription in $subscriptions) {

            Write-Information "Setting Azure Context to Subscription: $( $subscription.Name )"
            $null = Set-AzContext -SubscriptionId $subscription.Id

            $storageAccounts = Get-AzStorageAccount

            Write-Information "Storage Account Count: $( $storageAccounts.Count )"

            foreach ($storageAccount in $storageAccounts) {
                $storageAccountReport += [PSCustomObject]@{
                    'Subscription Id'                 = $subscription.Id
                    'Subscription Name'               = $subscription.Name
                    'Resource Group Name'             = $storageAccount.ResourceGroupName
                    Name                              = $storageAccount.StorageAccountName
                    Location                          = $storageAccount.Location
                    Kind                              = $storageAccount.Kind
                    Sku                               = $storageAccount.Sku.Name
                    AccessTier                        = $storageAccount.AccessTier
                    AllowBlobPublicAccess             = $storageAccount.AllowBlobPublicAccess
                    AllowCrossTenantReplication       = $storageAccount.AllowCrossTenantReplication
                    AllowSharedKeyAccess              = $storageAccount.AllowSharedKeyAccess
                    AzureFilesIdentityBasedAuth       = $storageAccount.AzureFilesIdentityBasedAuth
                    BlobRestoreStatus                 = $storageAccount.BlobRestoreStatus
                    CreationTime                      = $storageAccount.CreationTime
                    CustomDomain                      = $storageAccount.CustomDomain
                    EnableHierarchicalNamespace       = $storageAccount.EnableHierarchicalNamespace
                    EnableHttpsTrafficOnly            = $storageAccount.EnableHttpsTrafficOnly
                    EnableLocalUser                   = $storageAccount.EnableLocalUser
                    EnableNfsV3                       = $storageAccount.EnableNfsV3
                    EnableSftp                        = $storageAccount.EnableSftp
                    FailoverInProgress                = $storageAccount.FailoverInProgress
                    GeoReplicationStats               = $storageAccount.GeoReplicationStats
                    Identity                          = $storageAccount.Identity
                    ImmutableStorageWithVersioning    = $storageAccount.ImmutableStorageWithVersioning
                    Key1CreationTime                  = $storageAccount.KeyCreationTime.Key1
                    Key2CreationTime                  = $storageAccount.KeyCreationTime.Key2
                    KeyPolicy                         = $storageAccount.KeyPolicy
                    LargeFileSharesState              = $storageAccount.LargeFileSharesState
                    LastGeoFailoverTime               = $storageAccount.LastGeoFailoverTime
                    MinimumTlsVersion                 = $storageAccount.MinimumTlsVersion
                    PrimaryLocation                   = $storageAccount.PrimaryLocation
                    ProvisioningState                 = $storageAccount.ProvisioningState
                    PublicNetworkAccess               = $storageAccount.PublicNetworkAccess
                    RoutingPreference                 = $storageAccount.RoutingPreference
                    SasPolicy                         = $storageAccount.SasPolicy
                    SecondaryLocation                 = $storageAccount.SecondaryLocation
                    StatusOfPrimary                   = $storageAccount.StatusOfPrimary
                    StatusOfSecondary                 = $storageAccount.StatusOfSecondary
                    StorageAccountSkuConversionStatus = $storageAccount.StorageAccountSkuConversionStatus
                    ResourceId                        = $storageAccount.Id
                }
            }
        }

        $excelSplat = @{
            Path          = $Path
            WorksheetName = 'StorageAccount'
            TableStyle    = 'Medium2'
            AutoSize      = $true
            FreezeTopRow  = $true
            Style         = $excelStyle
            PassThru      = $true
        }

        $excel = $storageAccountReport |
            Sort-Object -Property 'Subscription Name', 'Resource Group Name', Name |
            Export-Excel @excelSplat

        $workSheet = $excel.Workbook.Worksheets[$excelSplat.WorksheetName]

        Set-ExcelRow -Worksheet $workSheet -Row 1 -Bold -HorizontalAlignment Center

        if ($NoInvoke) {
            Close-ExcelPackage -ExcelPackage $excel
        } else {
            Close-ExcelPackage -ExcelPackage $excel -Show
        }

        if ((Get-AzContext).Subscription.Id -ne $currentSubscription.Id) {
            Write-Information "Setting Azure Context to Subscription: $( $currentSubscription.Name )"
            $null = Set-AzContext -SubscriptionId $currentSubscription.Id
        }
    } catch {
        throw $PSItem
    }
}
#EndRegion '.\Public\New-AzReportsStorageAccount.ps1' 142
#Region '.\Public\New-AzReportsTrafficManager.ps1' 0
#requires -Modules ImportExcel

function New-AzReportsTrafficManager {
    <#
    .SYNOPSIS
        Creates an Excel spreadsheet report with the details for Azure Traffic Manager
    .DESCRIPTION
        Creates an Excel spreadsheet report with the details for Azure Traffic Manager
    .EXAMPLE
        PS C:\> New-AzReportsTrafficManager -Path .\temp\TrafficManager.xlsx -Force
 
        Creates a report of the Azure Traffic Manager and if the Path already exists it overwrites it.
    .INPUTS
        None
    .OUTPUTS
        Excel Spreadsheet
    #>

    [CmdletBinding()]
    param(
        # Path to create the Excel report. Must end with '.xlsx'.
        [Parameter(Mandatory)]
        [System.IO.FileInfo]
        $Path,

        # Do not automatically open the generated Excel spreadsheet.
        [switch]
        $NoInvoke,

        # Overwrite existing Excel spreadsheet.
        [switch]
        $Force
    )
    $InformationPreference = 'Continue'
    $env:SuppressAzurePowerShellBreakingChangeWarnings = 'true'

    try {
        CheckAzContext

        CheckPath -Path $Path -Extension '.xlsx' -Force:$Force -ErrorAction Stop

        $query = @'
resources
| where type == "microsoft.network/trafficmanagerprofiles"
| order by subscriptionId asc , resourceGroup asc , name asc
'@



        $queryResults = SearchAzGraph -Query $query

        $tmProfiles = [System.Collections.ArrayList]::new()
        $tmEndpoints = [System.Collections.ArrayList]::new()

        foreach ($queryResult in $queryResults) {
            $null = $tmProfiles.Add([PSCustomObject]@{
                    'Subscription Id'                      = $queryResult.subscriptionId
                    'Resource Group'                       = $queryResult.resourceGroup
                    Name                                   = $queryResult.name
                    Status                                 = $queryResult.properties.profileStatus
                    'Routing Method'                       = $queryResult.properties.TrafficRoutingMethod
                    'Max Return'                           = $queryResult.properties.MaxReturn
                    'Traffic View Enrollent'               = $queryResult.properties.trafficViewEnrollmentStatus
                    FQDN                                   = $queryResult.properties.dnsConfig.fqdn
                    'Relative DNS Name'                    = $queryResult.properties.dnsConfig.relativeName
                    TTL                                    = $queryResult.properties.dnsConfig.TTL
                    'Monitor Status'                       = $queryResult.properties.monitorConfig.profileMonitorStatus
                    'Monitor Protocol'                     = $queryResult.properties.monitorConfig.protocol
                    'Monitor Port'                         = $queryResult.properties.monitorConfig.port
                    'Monitor Path'                         = $queryResult.properties.monitorConfig.path
                    'Monitor Interval in Seconds'          = $queryResult.properties.monitorConfig.intervalInSeconds
                    'Monitor Tolerated Number of Failures' = $queryResult.properties.monitorConfig.toleratedNumberOfFailures
                    'Monitor Timeout in Seconds'           = $queryResult.properties.monitorConfig.timeoutInSeconds
                })

            foreach ($endpoint in $queryResult.properties.endpoints) {
                $null = $tmEndpoints.Add([PSCustomObject]@{
                        'Subscription Id'          = $queryResult.subscriptionId
                        'Resource Group'           = $queryResult.resourceGroup
                        'Profile Name'             = $queryResult.name
                        'Endpoint Name'            = $endpoint.name
                        Status                     = $endpoint.properties.endpointStatus
                        Target                     = $endpoint.properties.target
                        Priority                   = $endpoint.properties.priority
                        Weight                     = $endpoint.properties.weight
                        Location                   = $endpoint.properties.endpointLocation
                        'Min Child Endpoints'      = $endpoint.properties.minChildEndpoints
                        'Min Child Endpoints IPv4' = $endpoint.properties.minChildEndpointsIPv4
                        'Min Child Endpoints IPv6' = $endpoint.properties.minChildEndpointsIPv6

                    })
            }
        }

        $excelSplat = @{
            Path          = $Path
            WorksheetName = 'Profiles'
            TableStyle    = 'Medium2'
            AutoSize      = $true
            FreezeTopRow  = $true
            Style         = $excelStyle
            PassThru      = $true
        }

        $excel = $tmProfiles |
            Export-Excel @excelSplat

        $workSheet = $excel.Workbook.Worksheets[$excelSplat.WorksheetName]

        Set-ExcelRow -Worksheet $workSheet -Row 1 -Bold -HorizontalAlignment Center

        Set-ExcelColumn -Worksheet $workSheet -Column 1 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 2 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 3 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 4 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 5 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 6 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 7 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 8 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 9 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 10 -AutoSize -HorizontalAlignment Center
        Set-ExcelColumn -Worksheet $workSheet -Column 11 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 12 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 13 -AutoSize -HorizontalAlignment Center
        Set-ExcelColumn -Worksheet $workSheet -Column 14 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 15 -AutoSize -HorizontalAlignment Center
        Set-ExcelColumn -Worksheet $workSheet -Column 16 -AutoSize -HorizontalAlignment Center
        Set-ExcelColumn -Worksheet $workSheet -Column 17 -AutoSize -HorizontalAlignment Center

        $excelSplat = @{
            ExcelPackage  = $excel
            WorksheetName = 'Endpoints'
            TableStyle    = 'Medium2'
            AutoSize      = $true
            FreezeTopRow  = $true
            Style         = $excelStyle
            PassThru      = $true
        }

        $null = $tmEndpoints |
            Sort-Object -Property 'Subscription Id', 'Resource Group', 'Profile Name', 'Endpoint Name' |
            Export-Excel @excelSplat

        $workSheet = $excel.Workbook.Worksheets[$excelSplat.WorksheetName]

        Set-ExcelRow -Worksheet $workSheet -Row 1 -Bold -HorizontalAlignment Center

        Set-ExcelColumn -Worksheet $workSheet -Column 1 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 2 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 3 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 4 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 5 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 6 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 7 -AutoSize -HorizontalAlignment Center
        Set-ExcelColumn -Worksheet $workSheet -Column 8 -AutoSize -HorizontalAlignment Center
        Set-ExcelColumn -Worksheet $workSheet -Column 9 -AutoSize
        Set-ExcelColumn -Worksheet $workSheet -Column 10 -AutoSize -HorizontalAlignment Center
        Set-ExcelColumn -Worksheet $workSheet -Column 11 -AutoSize -HorizontalAlignment Center
        Set-ExcelColumn -Worksheet $workSheet -Column 12 -AutoSize -HorizontalAlignment Center

        if ($NoInvoke) {
            Close-ExcelPackage -ExcelPackage $excel
        } else {
            Close-ExcelPackage -ExcelPackage $excel -Show
        }
    } catch {
        throw $PSItem
    }
}
#EndRegion '.\Public\New-AzReportsTrafficManager.ps1' 168