PSSymantecCloud.psm1

#Region '.\Private\GetConfigurationPath.ps1' 0
function GetConfigurationPath {
    <#
    .SYNOPSIS
        returns hashtable object with the BaseURL, SepCloudCreds, SepCloudToken full path
    .DESCRIPTION
    .INPUTS
        None
    .OUTPUTS
        Hashtable
    #>


    @{
        BaseUrl       = "api.sep.securitycloud.symantec.com"
        SepCloudCreds = "$env:TEMP\SepCloudOAuthCredentials.xml"
        SepCloudToken = "$env:TEMP\SepCloudToken.xml"
    }

}
#EndRegion '.\Private\GetConfigurationPath.ps1' 19
#Region '.\Public\Export-SepCloudPolicyToExcel.ps1' 0
function Export-SepCloudPolicyToExcel {
    <# TODO fill description
    .SYNOPSIS
        Export an Allow List policy object to excel
    .DESCRIPTION
        Takes an allow list policy object as input and exports it to an Excel file, with one tab per allow type (filename/file hash/directory etc...)
    .EXAMPLE
        Get-SepCloudPolicyDetails -Name "My Policy" | Export-SepCloudPolicyToExcel -Path "allow_list.xlsx"
        Gathers policy in an object, pipes the output to Export-SepCloudPolicyToExcel
    #>


    param (
        # Path of Export
        [Parameter()]
        [string]
        $Path,

        # Policy Obj to work with
        [Parameter(
            ValueFromPipeline,
            Mandatory
        )]
        [pscustomobject]
        $obj_policy
    )
    <#
    Using as a template the following command
    $allow_list | ConvertTo-Json -Depth 100 | Out-File -FilePath "C:\Users\Douda\Documents\Amcor\Servers - Amcor Core Allow List Policy_v69.json"
    Get-SepCloudPolicyDetails -Policy_UUID "5e867f84-5e23-421c-adfd-XXXXXXXXXXXX" -Policy_version 9 | Convert-SepCloudPolicyToExcel -Path "C:\Amcor_local\test5.xlsx"
    Parsing the custom object to get the list of
    $obj_policy.features.configuration.applications
    $obj_policy.features.configuration.applications.processfile
    $obj_policy.features.configuration.applications.processfile.name
    $obj_policy.features.configuration.applications.processfile.sha2
    $obj_policy.features.configuration.certificates
    $obj_policy.features.configuration.webdomains
    $obj_policy.features.configuration.ips_hosts
    $obj_policy.features.configuration.extensions
    $obj_policy.features.configuration.extensions.names
    $obj_policy.features.configuration.windows.files
    $obj_policy.features.configuration.windows.directories
    #>

    $Applications = $obj_policy.features.configuration.applications.processfile
    $Certificates = $obj_policy.features.configuration.certificates
    $Webdomains = $obj_policy.features.configuration.webdomains
    $Ips_Hosts = $obj_policy.features.configuration.ips_hosts
    $Extensions = $obj_policy.features.configuration.extensions.names
    $Files = $obj_policy.features.configuration.windows.files
    $Directories = $obj_policy.features.configuration.windows.directories

    Import-Module -Name ImportExcel
    $Applications | Export-Excel $Path -WorksheetName "Applications" -ClearSheet -BoldTopRow -AutoSize -FreezeTopRow -AutoFilter
    $Certificates | Export-Excel $Path -WorksheetName "Certificates" -ClearSheet -BoldTopRow -AutoSize -FreezeTopRow -AutoFilter
    $Webdomains | Export-Excel $Path -WorksheetName "Webdomains" -ClearSheet -BoldTopRow -AutoSize -FreezeTopRow -AutoFilter
    $Ips_Hosts | Export-Excel $Path -WorksheetName "Ips_Hosts" -ClearSheet -BoldTopRow -AutoSize -FreezeTopRow -AutoFilter
    $Extensions | Export-Excel $Path -WorksheetName "Extensions" -ClearSheet -BoldTopRow -AutoSize -FreezeTopRow -AutoFilter
    $Files | Export-Excel $Path -WorksheetName "Files" -ClearSheet -BoldTopRow -AutoSize -FreezeTopRow -AutoFilter
    $Directories | Export-Excel $Path -WorksheetName "Directories" -ClearSheet -BoldTopRow -AutoSize -FreezeTopRow -AutoFilter
}
#EndRegion '.\Public\Export-SepCloudPolicyToExcel.ps1' 60
#Region '.\Public\Get-SepCloudDeviceInfo.ps1' 0
function Get-SepCloudDeviceInfo {
    param (
        # Mandatory device_ID parameter
        [Parameter(mandatory)]
        [string]
        $Device_ID
    )

    # Init
    $BaseURL = (GetConfigurationPath).BaseUrl
    $URI_Tokens = 'https://' + $BaseURL + "/v1/devices/$Device_ID"
    # Get token
    $Token = Get-SEPCloudToken  

    if ($null -ne $Token) {
        # HTTP body content containing all the queries
        $Body = @{}
        $Headers = @{
            Host          = $BaseURL
            Accept        = "application/json"
            Authorization = $Token
            Body          = $Body
        }
        $Response = Invoke-RestMethod -Method GET -Uri $URI_Tokens -Headers $Headers -Body $Body -UseBasicParsing 
        return $Response
    }
}
#EndRegion '.\Public\Get-SepCloudDeviceInfo.ps1' 28
#Region '.\Public\Get-SepCloudDeviceList.ps1' 0
function Get-SepCloudDeviceList {
    <# TODO fill up description
    .SYNOPSIS
        Gathers list of devices from the SEP Cloud console
    .DESCRIPTION
        A longer description of the function, its purpose, common use cases, etc.
 
    .PARAMETER Computername
    Specify one or many computer names. Accepts pipeline (up to 10 devices per query)
    Supports partial match
 
    .PARAMETER is_online
    Switch to lookup only online machines
 
    .PARAMETER Device_status
    Lookup devices per security status. Accepts only "SECURE", "AT_RISK", "COMPROMISED", "NOT_COMPUTED"
 
    .EXAMPLE
    Get-SepCloudDeviceList
 
    .EXAMPLE
    Get-SepCloudDeviceList -Computername MyComputer
     
    .EXAMPLE
    Get-SepCloudDeviceList -is_online -Device_status AT_RISK
        #>


    [CmdletBinding()]
    param (
        <# Optional ComputerName parameter
        TODO work to allow multiple values from Computername
        More info https://apidocs.securitycloud.symantec.com/#
        name query name of the device. [NOTE] Provide comma seperated values in case of multiple name search
        Note : seems to be limited to 10 values max
        #>

        [Parameter(
            ValueFromPipeline = $true
        )]
        [string]
        $Computername,

        # Optional Is_Online parameter
        [Parameter()]
        [Alias("Online")]
        [switch]
        $is_online,

        # Optional include_details parameter
        [Parameter()]
        [Alias("Details")]
        [switch]
        $include_details,

        # Device Group
        [Parameter()]
        [Alias("Group")]
        [string]
        $Device_group,

        # Optional Device_Status parameter
        [Parameter()]
        [Alias("DeviceStatus")]
        [ValidateSet("SECURE", "AT_RISK", "COMPROMISED", "NOT_COMPUTED")]
        $Device_status
    )
        
    # Init
    $BaseURL = (GetConfigurationPath).BaseUrl
    $URI_Tokens = 'https://' + $BaseURL + "/v1/devices"
    # Get token
    $Token = Get-SEPCloudToken  
        
    if ($null -ne $Token ) {
        # HTTP body content containing all the queries
        $Body = @{}
        
        # Iterating through all parameter and add them to the HTTP body
        if ($Computername -ne "") {
            $Body.Add("name", "$Computername") 
        }
        if ($is_online -eq $true ) {
            $body.add("is_online", "true")
        }
        if ($include_details -eq $true) {
            $Body.Add("include_details", "true")
        }
        if ($Device_status -ne "") {
            $Body.Add("device_status", "$Device_status")
        }
        if ($Device_group -ne "") {
            $Body.Add("device_group", "$Device_group")
        }

        $Headers = @{
            Host          = $BaseURL
            Accept        = "application/json"
            Authorization = $Token
            Body          = $Body
        }

        try {
            $Response = Invoke-RestMethod -Method GET -Uri $URI_Tokens -Headers $Headers -Body $Body -UseBasicParsing 
            return $Response
        } catch {
            $StatusCode = $_.Exception.Response.StatusCode
            Write-Warning "Query error - Expected HTTP 200, got $([int]$StatusCode)"
        }
    }
}
#EndRegion '.\Public\Get-SepCloudDeviceList.ps1' 110
#Region '.\Public\Get-SepCloudEvents.ps1' 0
function Get-SepCloudEvents {
    <# TODO fill description for Get-SepCloudEvents
    .SYNOPSIS
        Get list of SEP Cloud Events. By default, every events for the past 30 days
    .DESCRIPTION
        A longer description of the function, its purpose, common use cases, etc.
    .PARAMETER FileDetection
        Runs the following query under the hood "feature_name:MALWARE_PROTECTION AND ( type_id:8031 OR type_id:8032 OR type_id:8033 OR type_id:8027 OR type_id:8028 ) AND ( id:12 OR id:11 AND type_id:8031 )"
    .LINK
        https://github.com/Douda/PSSymantecCloud
    .EXAMPLE
        Get-SepCloudEvents -FileDetection
    .EXAMPLE
        Get-SepCloudEvents - Query "type_id:8031 OR type_id:8032 OR type_id:8033"
    #>


    param (
        # file Detection
        [Parameter()]
        [switch]
        $FileDetection,

        # Custom query to run
        [Parameter()]
        [string]
        $Query
    )

    begin {
        # Init
        $BaseURL = (GetConfigurationPath).BaseUrl
        $URI_Tokens = 'https://' + $BaseURL + "/v1/event-search"
        $ArrayResponse = @()
    }

    process {
        # Get token
        $Token = Get-SEPCloudToken

        if ($null -ne $Token) {
            # HTTP body content containing all mandatory info to start a query
            $Body = @{
                "product"      = "SAEP"
                "feature_name" = "ALL"
            }
            <# Setting dates for the query Date Format required : -UFormat "%Y-%m-%dT%T.000+00:00"
            Example :
            "start_date": "2022-10-16T00:00:00.000+00:00",
            "end_date": "2022-11-16T00:00:00.000+00:00" #>


            $end_date = Get-Date -Format "yyyy-MM-ddTHH:mm:ss.fffK"
            $start_date = ((Get-Date).addDays(-29) | Get-Date -Format "yyyy-MM-ddTHH:mm:ss.fffK")
            $Body.Add("start_date", $start_date)
            $Body.Add("end_date", $end_date)

            # Iterating through all parameter and adding them to the HTTP body
            switch ($PSBoundParameters.Keys) {
                'FileDetection' {
                    $Body.Add("query", '( feature_name:MALWARE_PROTECTION AND ( type_id:8031 OR type_id:8032 OR type_id:8033 OR type_id:8027 OR type_id:8028 ) AND ( id:12 OR id:11 AND type_id:8031 ) )')
                }
                'Query' {
                    $Body.Add("query", "$Query")
                }
                Default {
                }
            }

            # Convert body to Json after adding potential query with parameters
            $Body_Json = ConvertTo-Json $Body

            $Headers = @{
                Host           = $BaseURL
                Accept         = "application/json"
                "Content-Type" = "application/json"
                Authorization  = $Token
            }

            try {
                $Response = Invoke-RestMethod -Method POST -Uri $URI_Tokens -Headers $Headers -Body $Body_Json -UseBasicParsing
                $ArrayResponse += $Response
                if ($null -ne $Response.next) {
                    <# If pagination #>
                    do {
                        # change the "next" offset for next query
                        $Body.Remove("next")
                        $Body.Add("next", $Response.next)
                        $Body_Json = ConvertTo-Json $Body
                        # Run query & add it to the array
                        $Response = Invoke-RestMethod -Method POST -Uri $URI_Tokens -Headers $Headers -Body $Body_Json -UseBasicParsing
                        $ArrayResponse += $Response
                    } until (
                        ($null -eq $Response.next)
                    )
                }
            } catch {
                $StatusCode = $_
                $StatusCode
            }
        }
    }

    end {
        return $ArrayResponse.events
    }
}
#EndRegion '.\Public\Get-SepCloudEvents.ps1' 106
#Region '.\Public\Get-SepCloudFeatureList.ps1' 0
function Get-SepCloudFeatureList {
    <# TODO : fill in description Get-SepCloudFeatureList
    .SYNOPSIS
        A short one-line action-based description, e.g. 'Tests if a function is valid'
    .DESCRIPTION
        A longer description of the function, its purpose, common use cases, etc.
    .NOTES
        Information or caveats about the function e.g. 'This function is not supported in Linux'
    .LINK
        Specify a URI to a help page, this will show when Get-Help -Online is used.
    .EXAMPLE
        Test-MyTestFunction -Verbose
        Explanation of the function or its result. You can include multiple examples with additional .EXAMPLE lines
    #>

    
    param (
    )
    
    # Init
    $BaseURL = (GetConfigurationPath).BaseUrl
    $URI_Tokens = 'https://' + $BaseURL + "/v1/devices/enums"
    # Get token
    $Token = Get-SEPCloudToken  

    if ($null -ne $Token) {
        # HTTP body content containing all the queries
        $Body = @{}
        $Headers = @{
            Host          = $BaseURL
            Accept        = "application/json"
            Authorization = $Token
            Body          = $Body
        }
        $Response = Invoke-RestMethod -Method GET -Uri $URI_Tokens -Headers $Headers -Body $Body -UseBasicParsing 
        return $Response
    }
}
#EndRegion '.\Public\Get-SepCloudFeatureList.ps1' 38
#Region '.\Public\Get-SepCloudIncidents.ps1' 0
function Get-SepCloudIncidents {

    <# TODO fill description for Get-SepCloudIncidents
    .SYNOPSIS
        Get list of SEP Cloud incidents. By default, shows opened incidents
    .DESCRIPTION
        Get list of SEP Cloud incidents. Using the LUCENE query syntax, you can customize which incidents to gather. More information : https://techdocs.broadcom.com/us/en/symantec-security-software/endpoint-security-and-management/endpoint-security/sescloud/Endpoint-Detection-and-Response/investigation-page-overview-v134374740-d38e87486/Cloud-Database-Search/query-and-filter-operators-by-data-type-v134689952-d38e88796.html
    .PARAMETER Open
        filters only opened incidents. Simulates a query "state_id: [0 TO 3]" which represents incidents with the following states <0 Unknown | 1 New | 2 In Progress | 3 On Hold>
    .PARAMETER Include_events
        Includes every events that both are part of the context & triggered incident events
    .PARAMETER Query
        Type your customer Lucene query to pass to the API
    .OUTPUTS
        PSObject containing all SEP incidents
    .EXAMPLE
        Get-SepCloudIncidents -Open -Include_Events
    .EXAMPLE
        Get-SepCloudIncidents -Query "state_id: [0 TO 5]"
        This query a list of every possible incidents (opened, closed and with "Unknown" status)
    .LINK
        https://github.com/Douda/PSSymantecCloud
    #>

    [CmdletBinding(DefaultParameterSetName = 'QueryOpen')]
    param (
        # Opened incidents
        [Parameter(
            ParameterSetName = "QueryOpen"
        )]
        [switch]
        $Open,

        # Include events
        [Parameter()]
        [switch]
        $Include_events,

        # Custom query to run
        [Parameter(
            ParameterSetName = "QueryCustom"
        )]
        [string]
        $Query

    )
    begin {
        # Init
        $BaseURL = (GetConfigurationPath).BaseUrl
        $URI_Tokens = 'https://' + $BaseURL + "/v1/incidents"
        $ArrayResponse = @()
    }

    process {
        # Get token
        $Token = Get-SEPCloudToken

        if ($null -ne $Token) {
            # HTTP body content containing all the queries
            $Body = @{}

            # Settings dates
            $end_date = Get-Date -Format "yyyy-MM-ddTHH:mm:ss.fffK"
            $start_date = ((Get-Date).addDays(-29)  | Get-Date -Format "yyyy-MM-ddTHH:mm:ss.fffK")
            $Body.Add("start_date", $start_date)
            $Body.Add("end_date", $end_date)
            $Body_Json = ConvertTo-Json $Body

            # Iterating through all parameter and adding them to the HTTP body
            switch ($PSBoundParameters.Keys) {
                'Query' {
                    $Body.Add("query", "$Query")
                }
                'Open' {
                    $Body.Add("query", "state_id: [0 TO 3]")
                }
                'Include_events' {
                    $Body.Add("include_events", "true")
                }
                Default {
                }
            }

            $Headers = @{
                Host           = $BaseURL
                Accept         = "application/json"
                "Content-Type" = "application/json"
                Authorization  = $Token
            }

            try {
                $Response = Invoke-RestMethod -Method POST -Uri $URI_Tokens -Headers $Headers -Body $Body_Json -UseBasicParsing
                $ArrayResponse += $Response
                if ($null -ne $Response.next) {
                    <# If pagination #>
                    do {
                        # change the "next" offset for next query
                        $Body.Remove("next")
                        $Body.Add("next", $Response.next)
                        $Body_Json = ConvertTo-Json $Body
                        # Run query & add it to the array
                        $Response = Invoke-RestMethod -Method POST -Uri $URI_Tokens -Headers $Headers -Body $Body_Json -UseBasicParsing
                        $ArrayResponse += $Response
                    } until (
                        ($null -eq $Response.next)
                    )
                }
            } catch {
                $StatusCode = $_
                $StatusCode
            }
        }
    }
    end {
        return $ArrayResponse.incidents
    }
}
#EndRegion '.\Public\Get-SepCloudIncidents.ps1' 117
#Region '.\Public\Get-SepCloudPolices.ps1' 0
function Get-SepCloudPolices {
    # TODO to finish; test cmd-let
    param (   
        # Policy UUID
        [Parameter()]
        [string]
        $Policy_UUID
    
    )

    # Init
    $BaseURL = (GetConfigurationPath).BaseUrl
    $URI_Tokens = 'https://' + $BaseURL + "/v1/policies"
    # Get token
    $Token = Get-SEPCloudToken  

    if ($null -ne $Token) {
        # HTTP body content containing all the queries
        $Body = @{}
        $Headers = @{
            Host          = $BaseURL
            Accept        = "application/json"
            Authorization = $Token
            Body          = $Body
        }
        $Response = Invoke-RestMethod -Method GET -Uri $URI_Tokens -Headers $Headers -Body $Body -UseBasicParsing 
        return $Response
    }
    
}
#EndRegion '.\Public\Get-SepCloudPolices.ps1' 31
#Region '.\Public\Get-SepCloudPolicyDetails.ps1' 0
function Get-SepCloudPolicyDetails {

    <# TODO finish Get-SepCloudPolicyDetails description
    .SYNOPSIS
        A short one-line action-based description, e.g. 'Tests if a function is valid'
    .DESCRIPTION
        A longer description of the function, its purpose, common use cases, etc.
    .NOTES
        Information or caveats about the function e.g. 'This function is not supported in Linux'
    .LINK
        Specify a URI to a help page, this will show when Get-Help -Online is used.
    .EXAMPLE
        Test-MyTestFunction -Verbose
        Explanation of the function or its result. You can include multiple examples with additional .EXAMPLE lines
    #>



    param (
        # Policy UUID
        [Parameter()]
        [string]
        $Policy_UUID,

        # Policy version
        [Parameter()]
        [string]
        [Alias("Version")]
        $Policy_Version,

        # Exact policy name
        [Parameter(
            ValueFromPipeline,
            Mandatory
        )]
        [string[]]
        [Alias("Name")]
        $Policy_Name
    )

    begin {
        # Init
        $array_resp = @()
    }

    process {
        # iterating through policy_name list if more than one obj
        foreach ($p in $Policy_Name) {
            # Get list of all SEP Cloud policies
            $obj_policies = (Get-SepCloudPolices).policies
            $obj_policy = ($obj_policies | Where-Object { $_.name -eq "$p" })

            # Use specific version or by default latest
            if ($Policy_version -ne "") {
                $obj_policy = $obj_policy | Where-Object {
                    $_.name -eq "$p" -and $_.policy_version -eq $Policy_Version
                }
            } else {
                $obj_policy = ($obj_policy | Sort-Object -Property policy_version -Descending | Select-Object -First 1)
            }

            $Policy_UUID = ($obj_policy).policy_uid
            $Policy_Version = ($obj_policy).policy_version
            $BaseURL = (GetConfigurationPath).BaseUrl
            $URI = 'https://' + $BaseURL + "/v1/policies/$Policy_UUID/versions/$Policy_Version"
            # Get token
            $Token = Get-SEPCloudToken

            if ($null -ne $Token) {
                $Body = @{}
                $Headers = @{
                    Host          = $BaseURL
                    Accept        = "application/json"
                    Authorization = $Token
                    Body          = $Body
                }
                $Resp = Invoke-RestMethod -Method GET -Uri $URI -Headers $Headers -Body $Body -UseBasicParsing
                $array_resp += $Resp
            }
        }
    }

    end {
        return $array_resp
    }
}
#EndRegion '.\Public\Get-SepCloudPolicyDetails.ps1' 86
#Region '.\Public\Get-SEPCloudToken.ps1' 0
function Get-SEPCloudToken {
    <#
    .SYNOPSIS
    Generates an authenticated Token from the SEP Cloud API
 
    .DESCRIPTION
    Gathers Bearer Token from the SEP Cloud console to interact with the authenticated API
    Securely stores credentials or valid token locally (By default on TEMP location)
    Connection information available here : https://sep.securitycloud.symantec.com/v2/integration/client-applications
 
    .PARAMETER ClientID
    ClientID parameter required to generate a token
 
    .PARAMETER Secret
    Secret parameter required in combinaison to ClientID to generate a token
 
    .EXAMPLE
    Get-SEPCloudToken
 
    .EXAMPLE
    Get-SEPCloudToken(ClientID,Secret)
 
    .NOTES
    Function logic
    1. Test locally stored encrypted token
    2. Test locally stored encrypted Client/Secret to generate a token
    3. Requests Client/Secret to generate token
    #>


    [CmdletBinding()]
    param (
        # ClientID from SEP Cloud Connection App
        [Parameter()]
        [string]
        $ClientID,

        # Secret from SEP Cloud Connection App
        [Parameter()]
        [string]
        $Secret
    )

    # init
    $BaseURL = (GetConfigurationPath).BaseUrl
    $SepCloudCreds = (GetConfigurationPath).SepCloudCreds
    $SepCloudToken = (GetConfigurationPath).SepCloudToken
    $URI_Tokens = 'https://' + $BaseURL + '/v1/oauth2/tokens'
    $URI_Features = 'https://' + $BaseURL + '/v1/devices/enums'

    # Test if we have a token locally stored
    if (Test-Path -Path $SepCloudToken) {
        <# If true, test it against the API #>
        $Token = Import-Clixml -Path $SepCloudToken
        $Headers = @{
            Host          = $BaseURL
            Accept        = "application/json"
            Authorization = $Token
        }

        try {
            $response = Invoke-RestMethod -Method POST -Uri $URI_Features -Headers $Headers
            # Valid token, returning it
            Write-Verbose "Local token - valid"
            return $Token
        } catch {
            $StatusCode = $_.Exception.Response.StatusCode
            Write-Verbose "Authentication error - From locally stored token - Expected HTTP 200, got $([int]$StatusCode) - Continue ..."
            # Invalid token, deleting local token file
            Remove-Item $SepCloudToken
        }
    }

    # Test if OAuth cred present on the disk
    if (Test-Path -Path "$SepCloudCreds") {
        <# If true, Attempt to get a token #>
        $OAuth = Import-Clixml -Path $SepCloudCreds
        $OAuth_Basic = "Basic " + $OAuth
        $Headers = @{
            Host          = $BaseURL
            Accept        = "application/json"
            Authorization = $OAuth_Basic
        }

        try {
            $response = Invoke-RestMethod -Method POST -Uri $URI_Tokens -Headers $Headers

            # Get the auth token from the response & store it locally
            Write-Verbose "Valid credentials - returning valid token"
            $null = $Bearer_Token = "Bearer " + $response.access_token
            $Bearer_Token | Export-Clixml -Path $SepCloudToken
            return $Bearer_Token

        } catch {
            $StatusCode = $_.Exception.Response.StatusCode
            Write-Verbose "Authentication error - From locally stored credentials - Expected HTTP 200, got $([int]$StatusCode) - Continue..."
            # Invalid Credentials, deleting local credentials file
            Remove-Item $SepCloudCreds
        }
    }


    <# If no token nor OAuth creds available locally
    # Encode ClientID and Secret to create Basic Auth string
    # Authentication requires the following "Basic + encoded CliendID:ClientSecret" #>

    if ($clientID -eq "" -or $Secret -eq "") {
        Write-Host "No local credentials found"
        $ClientID = Read-Host -Prompt "Enter ClientID"
        $Secret = Read-Host -Prompt "Enter Secret"
    }
    $Encoded_Creds = [convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(($ClientID + ':' + $Secret)))
    $Encoded_Creds | Export-Clixml -Path $SepCloudCreds

    # Create Basic Auth string
    $BasicAuth = "Basic " + $Encoded_Creds
    $Headers = @{
        Host          = $BaseURL
        Accept        = "application/json"
        Authorization = $BasicAuth
    }
    $Response = Invoke-RestMethod -Method POST -Uri $URI_Tokens -Headers $Headers -UseBasicParsing

    # Get the auth token from the response and store it
    $Bearer_Token = "Bearer " + $Response.access_token
    $Bearer_Token | Export-Clixml -Path $SepCloudToken
    return $Bearer_Token
}
#EndRegion '.\Public\Get-SEPCloudToken.ps1' 127
#Region '.\Public\Test-SepCloudConnectivity.ps1' 0
function Test-SepCloudConnectivity {
    param (

    )
    if (Get-SEPCloudToken) {
        Write-Host "Authentication OK"
        return $true
        else {
            Write-Host "Authentication failed"
            return false
        }
    }
}
#EndRegion '.\Public\Test-SepCloudConnectivity.ps1' 14