Src/Private/Get-AbrFgtFortiCare.ps1


function Get-AbrFgtForticare {
    <#
    .SYNOPSIS
        Used by As Built Report to returns FortiCare settings.
    .DESCRIPTION
        Documents the configuration of Fortinet FortiGate in Word/HTML/Text formats using PScribo.
    .NOTES
        Version: 0.1.0
        Author: Alexis La Goutte
        Twitter: @alagoutte
        Github: alagoutte
        Credits: Iain Brighton (@iainbrighton) - PScribo module
 
    .LINK
        https://github.com/AsBuiltReport/AsBuiltReport.Fortinet.FortiGate
    #>

    [CmdletBinding()]
    param (

    )

    begin {
        Write-PScriboMessage "Discovering FortiCare settings information from $System."
    }

    process {

        $LicenseStatus = Get-FGTMonitorLicenseStatus
        if ($LicenseStatus -and $InfoLevel.Forticare -ge 1) {

            $FortiGuardservicesDescriptions = @{
                "forticare"                   = "FortiCare Support Services"
                "forticloud"                  = "FortiCloud Management"
                "security_rating"             = "Security Fabric Rating and Compliance Service"
                "antivirus"                   = "Antivirus Service"
                "mobile_malware"              = "Mobile Malware Service"
                "ai_malware_detection"        = "AI-based Inline Malware Prevention"
                "ips"                         = "Intrusion Prevention System (IPS)"
                "industrial_db"               = "OT Industrial Signatures Database"
                "appctrl"                     = "Application Control"
                "internet_service_db"         = "Internet Service (SaaS) Database"
                "device_os_id"                = "Device/OS Detection"
                "botnet_ip"                   = "Botnet IP Reputation Service"
                "botnet_domain"               = "Botnet Domain Reputation Service"
                "psirt_security_rating"       = "Attack Surface Security Rating"
                "outbreak_security_rating"    = "Outbreak Security Rating Service"
                "icdb"                        = "OT Industrial Signatures Database"
                "inline_casb"                 = "Inline SaaS Application Security (CASB)"
                "local_in_virtual_patching"   = "OT Virtual Patching"
                "malicious_urls"              = "Malicious URL Database"
                "blacklisted_certificates"    = "Blacklisted Certificates Service"
                "firmware_updates"            = "Firmware Updates"
                "web_filtering"               = "Web Filtering Service"
                "outbreak_prevention"         = "Outbreak Prevention"
                "antispam"                    = "Antispam Service"
                "iot_detection"               = "IoT Detection Service"
                "ot_detection"                = "OT Detection Service"
                "forticloud_sandbox"          = "FortiCloud Sandbox"
                "forticonverter"              = "FortiConverter Service"
                "fortiguard"                  = "FortiGuard Services"
                "data_leak_prevention"        = "Data Leak Prevention"
                "sdwan_network_monitor"       = "SD-WAN Network Monitor"
                "forticloud_logging"          = "FortiCloud Logging"
                "fortianalyzer_cloud"         = "FortiAnalyzer Cloud"
                "fortianalyzer_cloud_premium" = "FortiAnalyzer Cloud Premium"
                "fortimanager_cloud"          = "FortiManager Cloud"
                "fortisandbox_cloud"          = "FortiSandbox Cloud"
                "fortiguard_ai_based_sandbox" = "FortiGuard AI-based Sandbox"
                "sdwan_overlay_aas"           = "SD-WAN Overlay-as-a-Service"
                "fortisase_private_access"    = "FortiSASE Private Access"
                "fortisase_lan_extension"     = "FortiSASE LAN Extension"
                "fortiems_cloud"              = "FortiEMS Cloud"
                "fortimanager_cloud_alci"     = "FortiManager Cloud ALCI"
                "fortisandbox_cloud_alci"     = "FortiSandbox Cloud ALCI"
                "vdom"                        = "Virtual Domains (platform capability)"
                "sms"                         = "SMS Service"
            }
            $licenseSummary = @()

            $typeDescriptions = @{
                downloaded_fds_object   = 'Update Feed'
                live_fortiguard_service = 'Real-time Services'
                live_cloud_service      = 'Cloud Services'
                functionality_enabling  = 'Feature'
            }

            $excludeServices = @(
                'fortiguard', 'forticare', 'forticloud', 'sms', 'vdom',
                'forticloud_logging', 'fortianalyzer_cloud', 'fortianalyzer_cloud_premium',
                'fortimanager_cloud', 'fortisandbox_cloud', 'fortiguard_ai_based_sandbox',
                'forticonverter', 'fortiems_cloud', 'fortimanager_cloud_alci', 'fortisandbox_cloud_alci'
            )

            $FortiGuardSvcOrder = @(
                'internet_service_db', 'device_os_id', 'firmware_updates', 'ips',
                'blacklisted_certificates', 'appctrl', 'antivirus', 'botnet_ip', 'botnet_domain',
                'mobile_malware', 'antispam', 'outbreak_prevention', 'forticloud_sandbox',
                'ai_malware_detection', 'web_filtering', 'malicious_urls', 'security_rating',
                'psirt_security_rating', 'outbreak_security_rating', 'inline_casb',
                'data_leak_prevention', 'ot_detection', 'iot_detection', 'local_in_virtual_patching',
                'industrial_db', 'icdb', 'sdwan_network_monitor', 'sdwan_overlay_aas',
                'fortisase_private_access', 'fortisase_lan_extension'
            )

            $licenseSummaryUnordered = @()

            foreach ($property in $LicenseStatus.PSObject.Properties) {
                if ($excludeServices -contains $property.Name) {
                    continue
                }

                $feature = $property.Value
                $status = $feature.status
                $description = $FortiGuardservicesDescriptions[$property.Name]
                if ($null -ne $feature.expires) {
                    $expires = (Get-Date '01/01/1970').AddSeconds($feature.expires) | Get-Date -Format "dd/MM/yyyy"
                }
                else {
                    $expires = $null
                }
                $type = $feature.type
                $entitlement = $feature.entitlement
                $typeDescription = $typeDescriptions[$type]

                $licenseSummaryUnordered += [PSCustomObject]@{
                    name            = $property.Name
                    description     = $description
                    status          = $status
                    expiration      = $expires
                    type            = $type
                    typeDescription = $typeDescription
                    entitlement     = $entitlement
                }
            }

            # Ordering $licenseSummary based on the specified order
            $licenseSummary = $FortiGuardSvcOrder | ForEach-Object {
                $serviceName = $_
                $licenseSummaryUnordered | Where-Object { $_.Name -eq $serviceName }
            }

            $Forticare = $LicenseStatus.forticare
            Section -Style Heading2 'FortiCare' {
                Paragraph "The following table details FortiCare settings configured on FortiGate."
                BlankLine

                $OutObj = @()

                $Serial = $DefaultFGTConnection.serial

                $OutObj = [pscustomobject]@{
                    "Model"   = $Model
                    "Serial"  = $Serial
                    "Status"  = $Forticare.status
                    "Account" = $Forticare.account.ToLower()
                    "Company" = $Forticare.company
                }

                $TableParams = @{
                    Name         = "FortiCare"
                    List         = $true
                    ColumnWidths = 50, 50
                }

                if ($Report.ShowTableCaptions) {
                    $TableParams['Caption'] = "- $($TableParams.Name)"
                }

                $OutObj | Table @TableParams


                Paragraph "The following table details FortiGuard subscriptions and services on FortiGate."
                BlankLine

                $OutObj = @()
                foreach ($license in $licenseSummary) {
                    if ($license.status -eq 'licensed') {
                        $licenseStatus = 'Licensed'
                    }
                    else {
                        $licenseStatus = 'Unlicensed'
                    }
                    $OutObj += [pscustomobject]@{
                        "Name"       = $license.description
                        "Type"       = $license.typeDescription
                        "Status"     = $licenseStatus
                        "Expiration" = $license.expiration
                    }
                }

                $TableParams = @{
                    Name         = "FortiGuard Services"
                    List         = $false
                    ColumnWidths = 50, 20, 15, 15
                }

                if ($Report.ShowTableCaptions) {
                    $TableParams['Caption'] = "- $($TableParams.Name)"
                }

                $OutObj | Table @TableParams


                Paragraph "The following section details support settings configured on FortiGate."
                BlankLine
                $ExpiresHW = (($Forticare | Select-Object -ExpandProperty support).hardware).expires
                $SupportHW = [pscustomobject]@{
                    "Type"            = "Hardware"
                    "Level"           = $Forticare.support.hardware.support_level
                    "Status"          = $Forticare.support.hardware.status
                    "Expiration Date" = (Get-Date 01.01.1970) + ([System.TimeSpan]::fromseconds($ExpiresHW)) | Get-Date -Format dd/MM/yyyy
                }
                $ExpiresEn = (($Forticare | Select-Object -ExpandProperty support).enhanced).expires
                $SupportEn = [pscustomobject]@{
                    "Type"            = "Enhanced"
                    "Level"           = $Forticare.support.enhanced.support_level
                    "Status"          = $Forticare.support.enhanced.status
                    "Expiration Date" = (Get-Date 01.01.1970) + ([System.TimeSpan]::fromseconds($ExpiresEn)) | Get-Date -Format dd/MM/yyyy
                }

                $TableParams = @{
                    Name         = "Support"
                    List         = $false
                    ColumnWidths = 25, 25, 25, 25
                }

                if ($Report.ShowTableCaptions) {
                    $TableParams['Caption'] = "- $($TableParams.Name)"
                }

                $Support = @()
                $Support += $SupportHW
                $Support += $SupportEn
                $Support | Table @TableParams
            }

        }

        $firmware = Get-FGTMonitorSystemFirmware
        try {
            $firmware_upgrade_paths = Get-FGTMonitorSystemFirmware -upgrade_paths
        }
        catch {
            $firmware_upgrade_paths = $null
        }


        if ($firmware -and $firmware_upgrade_paths -and $InfoLevel.Forticare -ge 1) {
            Paragraph "The following section details firmware information on FortiGate."
            BlankLine

            $FortiOS = $firmware.current
            $CurrentVersion = [version]"$($firmware.current.major).$($firmware.current.minor).$($firmware.current.patch)"

            $FullUpdate = $firmware.available | Select-Object version -First 1
            if ($FullUpdate) {

                $FullUpdateVersion = [version]"$(($firmware.available | Select-Object -First 1).major).$(($firmware.available | Select-Object -First 1).minor).$(($firmware.available | Select-Object -First 1).patch)"

                #Same (or greater) version, No Update Available
                if ($CurrentVersion -ge $FullUpdateVersion) {
                    $tab_upgradePath = [pscustomobject]@{
                        "Installed"    = $($FortiOS.version)
                        "Update"       = "No Update Available"
                        "Upgrade Path" = "N/A"
                    }
                }
                else {
                    <# Search only last firmware on the same Branch
                $BranchUpdate = $firmware.available | Where-Object { $_.major -eq $CurrentVersion.Major -and $_.minor -eq $CurrentVersion.Minor } | Select-Object version -First 1
                if ($CurrentVersion -lt $BranchUpdateVersion) {
                    $upgradePath = "v$($CurrentVersion.Major).$($CurrentVersion.Minor).$($CurrentVersion.Build)"
                    $major = $CurrentVersion.Major
                    $minor = $CurrentVersion.Minor
                    $patch = $CurrentVersion.Build
                    Do {
                        $nextFirmware = $firmware_upgrade_paths | Where-Object { $_.from.major -eq $major -and $_.from.minor -eq $minor -and $_.from.patch -eq $patch -and $_.to.major -eq $BranchUpdateVersion.Major -and $_.to.minor -eq $BranchUpdateVersion.Minor } | Select-Object -First 1
                        $major = $nextFirmware.to.major
                        $minor = $nextFirmware.to.minor
                        $patch = $nextFirmware.to.patch
                        $upgradePath = $upgradePath + " -> v$($major).$($minor).$($patch)"
                    }Until($major -eq $BranchUpdateVersion.Major -and $minor -eq $BranchUpdateVersion.Minor -and $patch -eq $BranchUpdateVersion.Build)
                    $tab_upgradePath = [pscustomobject]@{
                        "Installed" = $($FortiOS.version)
                        "Update" = $($BranchUpdate.version)
                        "Upgrade Path" = $upgradePath
                    }
                }
                #>

                    #$BranchUpdateVersion = [version]"$(($firmware.available | Where-Object { $_.major -eq $CurrentVersion.Major -and $_.minor -eq $CurrentVersion.Minor } | Select-Object -First 1).major).$(($firmware.available | Where-Object { $_.major -eq $CurrentVersion.Major -and $_.minor -eq $CurrentVersion.Minor } | Select-Object -First 1).minor).$(($firmware.available | Where-Object { $_.major -eq $CurrentVersion.Major -and $_.minor -eq $CurrentVersion.Minor } | Select-Object -First 1).patch)"
                    #if (($CurrentVersion -lt $FullUpdateVersion)) {
                    $upgradePath = "v$($CurrentVersion.Major).$($CurrentVersion.Minor).$($CurrentVersion.Build)"
                    $major = $CurrentVersion.Major
                    $minor = $CurrentVersion.Minor
                    $patch = $CurrentVersion.Build
                    Do {
                        $nextFirmware = $firmware_upgrade_paths | Where-Object { $_.from.major -eq $major -and $_.from.minor -eq $minor -and $_.from.patch -eq $patch } | Select-Object -First 1
                        $major = $nextFirmware.to.major
                        $minor = $nextFirmware.to.minor
                        $patch = $nextFirmware.to.patch
                        $upgradePath = $upgradePath + " -> v$($major).$($minor).$($patch)"
                    }Until($major -eq $FullUpdateVersion.Major -and $minor -eq $FullUpdateVersion.Minor -and $patch -eq $FullUpdateVersion.Build)
                    $tab_upgradePath = [pscustomobject]@{
                        "Installed"    = $($FortiOS.version)
                        "Update"       = $($FullUpdate.version)
                        "Upgrade Path" = $upgradePath
                    }
                    #}
                }
            }
            else {

                #No $firmware.available info (no FortiCare/FortiGuard ?)
                $tab_upgradePath = [pscustomobject]@{
                    "Installed"    = $($FortiOS.version)
                    "Update"       = "N/A"
                    "Upgrade Path" = "N/A"
                }
            }

            $TableParams = @{
                Name         = "Firmware"
                List         = $true
                ColumnWidths = 50, 50
            }

            if ($Report.ShowTableCaptions) {
                $TableParams['Caption'] = "- $($TableParams.Name)"
            }

            $tab_upgradePath | Table @TableParams
        }

    }

    end {

    }

}