Functions/Public/NCXReporting.ps1

# NCX cloud reporting functions

Function Connect-NCXCloud {
    <#
        .SYNOPSIS
        Connects to Nectar CX cloud and store the credentials for later use.
 
        .DESCRIPTION
        Connects to Nectar CX cloud and store the credentials for later use.
         
        .PARAMETER CloudFQDN
        The FQDN of the Nectar CX cloud.
 
        .PARAMETER TenantName
        The name of a Nectar DXP cloud tenant to connect to and use for subsequent commands. Only useful for multi-tenant deployments
         
        .PARAMETER Credential
        The credentials used to access the Nectar DXP UI. Normally in username@domain.com format
         
        .PARAMETER StoredCredentialTarget
        Use stored credentials saved via New-StoredCredential. Requires prior installation of CredentialManager module via Install-Module CredentialManager, and running:
        Get-Credential | New-StoredCredential -Target MyCXCreds -Persist LocalMachine
         
        .PARAMETER EnvFromFile
        Use a CSV file called NCXEnvList.csv located in the user's default Documents folder to show a list of environments to select from. Run [Environment]::GetFolderPath("MyDocuments") to find your default document folder.
        This parameter is only available if N10EnvList.csv is found in the user's default Documents folder (ie: C:\Users\username\Documents)
        Also sets the default stored credential target to use for the selected environment. Requires prior installation and configuration of CredentialManager PS add-in.
        N10EnvList.csv must have a header with three columns defined as "Environment, DefaultTenant, StoredCredentialTarget".
        Each environment and StoredCredentialTarget (if used) should be on their own separate lines
         
        .EXAMPLE
        $Cred = Get-Credential
        Connect-NCX -Credential $cred -CloudFQDN contoso.nectar.services
        Connects to the contoso.nectar.services Nectar CX cloud using the credentials supplied to the Get-Credential command
         
        .EXAMPLE
        Connect-NCX-CloudFQDN contoso.nectar.services -StoredCredentialTarget MyCXCreds
        Connects to contoso.nectar.services Nectar CX cloud using previously stored credentials called MyCXCreds
         
        .NOTES
        Version 1.0
    #>

    
    Param (
        [Parameter(ValueFromPipeline, Mandatory=$False)]
        [ValidateScript ({
            If ($_ -Match "^(?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\(\)\*\+,;=.]+$") {
                $True
            } 
            Else {
                Throw "ERROR: Nectar CX cloud name must be in FQDN format."
            }
        })]
        [string]$CloudFQDN,
        [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)]
        [string]$TenantName,
        [Parameter(ValueFromPipelineByPropertyName)]
        [System.Management.Automation.Credential()]
        [PSCredential]$Credential,
        [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)]
        [string]$StoredCredentialTarget
    )
    DynamicParam {
        $DefaultDocPath = [Environment]::GetFolderPath("MyDocuments")
        $EnvPath = "$DefaultDocPath\CXEnvList.csv"
        If (Test-Path $EnvPath -PathType Leaf) {
            # Set the dynamic parameters' name
            $ParameterName = 'EnvFromFile'
            
            # Create the dictionary
            $RuntimeParameterDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary
         
            # Create the collection of attributes
            $AttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]
                    
            # Create and set the parameters' attributes
            $ParameterAttribute = New-Object System.Management.Automation.ParameterAttribute
            $ParameterAttribute.Mandatory = $False
            $ParameterAttribute.Position = 1
         
            # Add the attributes to the attributes collection
            $AttributeCollection.Add($ParameterAttribute)
         
            # Generate and set the ValidateSet
            $EnvSet = Import-Csv -Path $EnvPath
            $ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($EnvSet.Environment)
         
            # Add the ValidateSet to the attributes collection
            $AttributeCollection.Add($ValidateSetAttribute)
         
            # Create and return the dynamic parameter
            $RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($ParameterName, [string], $AttributeCollection)
            $RuntimeParameterDictionary.Add($ParameterName, $RuntimeParameter)
            Return $RuntimeParameterDictionary
        }
    }
    
    Begin {
        # Bind the dynamic parameter to a friendly variable
        If (Test-Path $EnvPath -PathType Leaf) {
            If ($PsBoundParameters[$ParameterName]) {
                $CloudFQDN = $PsBoundParameters[$ParameterName]
                Write-Verbose "CloudFQDN: $CloudFQDN"
                
                # Get the array position of the selected environment
                $EnvPos = $EnvSet.Environment.IndexOf($CloudFQDN)
                
                # Check for default tenant in N10EnvList.csv and use if available, but don't override if user explicitly set the TenantName
                If (!$PsBoundParameters['TenantName']) {
                    $TenantName = $EnvSet[$EnvPos].DefaultTenant
                    Write-Verbose "DefaultTenant: $TenantName"
                }
                
                # Check for stored credential target in N10EnvList.csv and use if available
                $StoredCredentialTarget = $EnvSet[$EnvPos].StoredCredentialTarget
                Write-Verbose "StoredCredentialTarget: $StoredCredentialTarget"
            }
        }
    }
    Process {
        # Need to force TLS 1.2, if not already set
        If ([Net.ServicePointManager]::SecurityProtocol -ne 'Tls12') { [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 }
        
        # Ask for the tenant name if global Nectar tenant variable not available and not entered on command line
        If ((-not $Global:NCXCloud) -And (-not $CloudFQDN)) {
            $CloudFQDN = Read-Host "Enter the Nectar DXP cloud FQDN"
        }
        ElseIf (($Global:NCXCloud) -And (-not $CloudFQDN)) {
            $CloudFQDN = $Global:NCXCloud
        }
        
        $RegEx = "^(?:http(s)?:\/\/)?([\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\(\)\*\+,;=.]+)$"
        $FQDNMatch = Select-String -Pattern $Regex -InputObject $CloudFQDN
        $CloudFQDN = $FQDNMatch.Matches.Groups[2].Value
        
        # Ask for credentials if global Nectar creds aren't available
        If (((-not $Global:NCXCred) -And (-not $Credential)) -Or (($Global:NCXCloud -ne $CloudFQDN) -And (-Not $Credential)) -And (-Not $StoredCredentialTarget)) {
            $Credential = Get-Credential
        }
        ElseIf ($Global:NCXCred -And (-not $Credential)) {
            $Credential = $Global:NCXCred
        }
        
        # Pull stored credentials if specified
        If ($StoredCredentialTarget) {
            Try {
                $Credential = Get-StoredCredential -Target $StoredCredentialTarget
            }
            Catch {
                Write-Error "Cannot find stored credential for target: $($StoredCredentialTarget). $($_.Exception.Message)"
            }
        }
        
        If ((-not $Global:NCXCred) -Or (-not $Global:NCXCloud) -Or ($Global:NCXCloud -ne $CloudFQDN)) {
            # First check and notify if updated Nectar PS module available
            [string]$InstalledNectarPSVer = (Get-InstalledModule -Name Nectar10 -ErrorAction SilentlyContinue).Version
            
            If ($InstalledNectarPSVer -gt 0) {
                [string]$LatestNectarPSVer = (Find-Module Nectar10).Version
                If ($LatestNectarPSVer -gt $InstalledNectarPSVer) {
                    Write-Host "=============== Nectar PowerShell module version $LatestN10Ver available ===============" -ForegroundColor Yellow
                    Write-Host "You are running version $InstalledNectarPSVer. Type " -ForegroundColor Yellow -NoNewLine
                    Write-Host 'Update-Module Nectar10' -ForegroundColor Green -NoNewLine
                    Write-Host ' to update.' -ForegroundColor Yellow
                }
            }
            
            # Attempt connection to tenant
            $URI = "https://$CloudFQDN/cyclone-portlet/api/organisation/"
            Write-Verbose $URI

            $WebRequest = Invoke-WebRequest -Uri $URI -Method GET -Credential $Credential -UseBasicParsing -SessionVariable NectarSession
            
            If ($WebRequest.StatusCode -ne 200) {
                Write-Error "Could not connect to $CloudFQDN using $($Credential.UserName)"
            }
            Else {
                Write-Host -ForegroundColor Green "Successful connection to " -NoNewLine
                Write-Host -ForegroundColor Yellow "https://$CloudFQDN" -NoNewLine
                Write-Host -ForegroundColor Green " using " -NoNewLine
                Write-Host -ForegroundColor Yellow ($Credential).UserName
                $Global:NCXCloud = $CloudFQDN
                $Global:NCXCred = $Credential
                $Global:NCXSession = $NectarSession
                
                # If there is only one available tenant, assign that to the NCXTenantName global variable
                $TenantList = $WebRequest | ConvertFrom-Json
                If ($TenantList.Count -eq 1) { 
                    $Global:NCXTenantName = $TenantList.name 
                    $Global:NCXOrgID = $TenantList.ID
                }            
            }
        }
        
        # Check to see if tenant name was entered and set global variable, if valid.
        If ($TenantName) {
            $URI = "https://$Global:NCXCloud/cyclone-portlet/api/organisation/"
            Write-Verbose $URI

            $TenantList = Invoke-RestMethod -Method GET -Credential $Global:NCXCred -URI $URI
            Try {
                If ($TenantList.name -Contains $TenantName) {
                    $Global:NCXTenantName = ($TenantList | Where-Object {$_.name -eq $TenantName}).name
                    $Global:NCXOrgID = ($TenantList | Where-Object {$_.name -eq $TenantName}).id
                    Write-Host -ForegroundColor Green "Successsfully set the tenant name to " -NoNewLine
                    Write-Host -ForegroundColor Yellow $Global:NCXTenantName -NoNewLine
                    Write-Host -ForegroundColor Green " (OrgID=" -NoNewLine
                    Write-Host -ForegroundColor Yellow $Global:NCXOrgID -NoNewLine 
                    Write-Host -ForegroundColor Green "). This tenantname will be used in all subsequent commands."
                }
                Else {
                    $TenantList | ForEach-Object{ $TList += ($(If($TList){", "}) + $_.name) }
                    Write-Error "Could not find a tenant with the name $TenantName on https://$Global:NCXCloud. Select one of $TList"
                }
            }
            Catch {
                Write-Error "Invalid tenant name on https://$Global:NCXCloud"
            }
        }
        ElseIf ($PSBoundParameters.ContainsKey('TenantName')) { # Remove the NCXTenantName global variable only if TenantName is explicitly set to NULL
            Remove-Variable NCXTenantName -Scope Global -ErrorAction:SilentlyContinue
            Remove-Variable NCXOrgID -Scope Global -ErrorAction:SilentlyContinue
        }
    }
}


Function Disconnect-NCXCloud {
    <#
        .SYNOPSIS
        Disconnects from any active Nectar CX connection
         
        .DESCRIPTION
        Essentially deletes any stored credentials and FQDN from global variables
 
        .EXAMPLE
        Disconnect-NCXCloud
        Disconnects from all active connections to Nectar DXP tenants
 
        .NOTES
        Version 1.0
    #>

    [Alias("dnc")]
    [cmdletbinding()]
    param ()
    
    Remove-Variable NCXCred -Scope Global -ErrorAction:SilentlyContinue
    Remove-Variable NCXCloud -Scope Global -ErrorAction:SilentlyContinue
    Remove-Variable NCXSession -Scope Global -ErrorAction:SilentlyContinue
    Remove-Variable NCXTenantName -Scope Global -ErrorAction:SilentlyContinue
    Remove-Variable NCXOrgID -Scope Global -ErrorAction:SilentlyContinue

    Write-Verbose "Successfully disconnected from Nectar CX cloud"
}


Function Get-NCXCloudInfo {
    <#
        .SYNOPSIS
        Shows information about the active Nectar CX connection
         
        .DESCRIPTION
        Shows information about the active Nectar CX connection
 
        .EXAMPLE
        Get-NCXCloud
 
        .NOTES
        Version 1.0
    #>

    
    [cmdletbinding()]
    param ()
    
    $CloudInfo = "" | Select-Object -Property CloudFQDN, Credential
    $CloudInfo.CloudFQDN = $Global:NCXCloud
    $CloudInfo.Credential = ($Global:NCXCred).UserName
    $CloudInfo | Add-Member -TypeName 'Nectar.CloudInfo'
    
    Try {
        $TenantCount = Get-NCXTenantNames
        If ($TenantCount.Count -gt 1) {
            If ($Global:NCXTenantName) {
                $CloudInfo | Add-Member -NotePropertyName 'TenantName' -NotePropertyValue $Global:NCXTenantName
                $CloudInfo | Add-Member -NotePropertyName 'OrgID' -NotePropertyValue $Global:NCXOrgID
            }
            Else {
                $CloudInfo | Add-Member -NotePropertyName 'TenantName' -NotePropertyValue '<Not Set>'
                $CloudInfo | Add-Member -NotePropertyName 'OrgID' -NotePropertyValue '<Not Set>'
            }
        }
    }
    Catch {
    }
    
    Return $CloudInfo
}




#################################################################################################################################################
# #
# Other CX Functions #
# #


Function Get-NCXTenantNames {
    <#
        .SYNOPSIS
        Shows all the available Nectar CX tenants on the cloud host.
         
        .DESCRIPTION
        Shows all the available Nectar CX tenants on the cloud host. Only available for multi-tenant deployments.
 
        .EXAMPLE
        Get-NCXTenantNames
 
        .NOTES
        Version 1.0
    #>

    
    [cmdletbinding()]
    [alias('Get-NCXOrganization')]
    param ()
    
    Begin {
        Connect-NCXCloud
    }
    Process {
        Try {
            $URI = "https://$Global:NCXCloud/cyclone-portlet/api/organisation/"
            Write-Verbose $URI
            $JSON = Invoke-RestMethod -Method GET -WebSession $Global:NCXSession -URI $URI
            Return $JSON
        }
        Catch {
            Write-Error "No data found or insufficient permissions. $($_.Exception.Message)"
            If ($PSCmdlet.MyInvocation.BoundParameters["ErrorAction"] -ne "SilentlyContinue") { Get-JSONErrorStream -JSONResponse $_ }
        }
    }
}


Function Get-NCXCampaign {
    <#
        .SYNOPSIS
        Shows all Nectar CX campaigns
         
        .DESCRIPTION
        Shows all Nectar CX campaigns
 
        .EXAMPLE
        Get-NCXCampaign
 
        .NOTES
        Version 1.0
    #>

    
    [cmdletbinding()]
    param (
        [Parameter(Mandatory=$True)]
        [ValidateSet('RADAR', 'EXPRESS', 'VORTEX', 'CYCLONE', 'INBOUND', IgnoreCase=$True)]
        [string]$PlanType
    )
    
    Begin {
        Connect-NCXCloud
    }
    Process {
        Try {
            $URI = "https://$Global:NCXCloud/cyclone-portlet/api/campaigns/getCampaigns/$Global:NCXOrgID/$PlanType"
            Write-Verbose $URI
            $JSON = Invoke-RestMethod -Method GET -WebSession $Global:NCXSession -URI $URI
            Return $JSON
        }
        Catch {
            Write-Error "No data or insufficient permissions. $($_.Exception.Message)"
            If ($PSCmdlet.MyInvocation.BoundParameters["ErrorAction"] -ne "SilentlyContinue") { Get-JSONErrorStream -JSONResponse $_ }
        }
    }
}


Function Get-NCXTestCase {
    <#
        .SYNOPSIS
        Shows all Nectar CX test cases within the tenant
         
        .DESCRIPTION
        Shows all Nectar CX test cases within the tenant
 
        .EXAMPLE
        Get-NCXTestCase
 
        .NOTES
        Version 1.0
    #>

    
    [cmdletbinding()]
    param (
        [Parameter(Mandatory=$True)]
        [ValidateSet('RADAR', 'EXPRESS', 'VORTEX', 'CYCLONE', 'INBOUND', IgnoreCase=$True)]
        [string]$PlanType
    )
    
    Begin {
        Connect-NCXCloud
    }
    Process {
        Try {
            $URI = "https://$Global:NCXCloud/cyclone-portlet/api/testCases/getTestCases/$Global:NCXOrgID/$PlanType"
            Write-Verbose $URI
            $JSON = Invoke-RestMethod -Method GET -WebSession $Global:NCXSession -URI $URI
            Return $JSON
        }
        Catch {
            Write-Error "No data or insufficient permissions. $($_.Exception.Message)"
            If ($PSCmdlet.MyInvocation.BoundParameters["ErrorAction"] -ne "SilentlyContinue") { Get-JSONErrorStream -JSONResponse $_ }
        }
    }
}


Function Get-NCXAlarm {
    <#
        .SYNOPSIS
        Shows NCX alarms
         
        .DESCRIPTION
        Shows NCX alarms
 
        .EXAMPLE
        Get-NCXAlarm
 
        .NOTES
        Version 1.0
    #>

    
    [CmdletBinding(PositionalBinding=$False, DefaultParameterSetName = 'Summary')]
    Param (
        [Parameter(Mandatory=$True, ParameterSetName = 'Summary', Position = 0)]
        [Parameter(Mandatory=$True, ParameterSetName = 'SummaryTime', Position = 0)]
        [ValidateSet('Organization', 'TestCase', 'CalledNumber', 'TestSuite', IgnoreCase=$True)]
        [string]$AlarmType,
        [Parameter(Mandatory=$False, ParameterSetName = 'Summary')]
        [ValidateSet('LAST_1HR', 'LAST_4HR', 'LAST_12HR', 'LAST_24HR', 'CURRENT_WEEK', 'CURRENT_MONTH', 'LAST_30DAYS', IgnoreCase=$True)]
        [string]$TimePeriod,
        [Parameter(Mandatory=$True, ParameterSetName = 'SummaryTime')]
        [DateTime]$TimePeriodFrom,
        [Parameter(Mandatory=$True, ParameterSetName = 'SummaryTime')]
        [DateTime]$TimePeriodTo
    )
    DynamicParam {
        $ParamDictionary = New-Object -Type System.Management.Automation.RuntimeDefinedParameterDictionary
        Switch ($AlarmType) {
            {$_ -in 'Organization', 'CalledNumber'} {
                # Define parameter attributes for PlanType attribute
                $ParamAttributes = New-Object -Type System.Management.Automation.ParameterAttribute
                $ParamAttributes.Mandatory = $True
                $ParamAttributes.Position = 1
                $ValidateSetAttributes = New-Object System.Management.Automation.ValidateSetAttribute('RADAR', 'EXPRESS', 'VORTEX', 'CYCLONE', 'INBOUND')
                $ParamAttributesCollect = New-Object -Type System.Collections.ObjectModel.Collection[System.Attribute]
                $ParamAttributesCollect.Add($ParamAttributes)
                $ParamAttributesCollect.Add($ValidateSetAttributes)
                $DynParam1 = New-Object -Type System.Management.Automation.RuntimeDefinedParameter('PlanType', [string], $ParamAttributesCollect)
                $ParamDictionary.Add('PlanType', $DynParam1)
            }
            'TestCase' {
                # Define parameter attributes for TestCaseID attribute
                $ParamAttributes = New-Object -Type System.Management.Automation.ParameterAttribute
                $ParamAttributes.Mandatory = $True
                $ParamAttributes.Position = 1
                $ParamAttributesCollect = New-Object -Type System.Collections.ObjectModel.Collection[System.Attribute]
                $ParamAttributesCollect.Add($ParamAttributes)
                $DynParam1 = New-Object -Type System.Management.Automation.RuntimeDefinedParameter('TestCaseID', [string], $ParamAttributesCollect)
                $ParamDictionary.Add('TestCaseID', $DynParam1)
            }
            'CalledNumber' {
                # Define parameter attributes for CalledNumber attribute
                $ParamAttributes = New-Object -Type System.Management.Automation.ParameterAttribute
                $ParamAttributes.Mandatory = $True
                $ParamAttributes.Position = 2
                $ParamAttributesCollect = New-Object -Type System.Collections.ObjectModel.Collection[System.Attribute]
                $ParamAttributesCollect.Add($ParamAttributes)
                $DynParam1 = New-Object -Type System.Management.Automation.RuntimeDefinedParameter('CalledNumber', [string], $ParamAttributesCollect)
                $ParamDictionary.Add('CalledNumber', $DynParam1)
            }            
            'TestSuite' {
                # Define parameter attributes for TestSuiteID attribute
                $ParamAttributes = New-Object -Type System.Management.Automation.ParameterAttribute
                $ParamAttributes.Mandatory = $True
                $ParamAttributes.Position = 2
                $ParamAttributesCollect = New-Object -Type System.Collections.ObjectModel.Collection[System.Attribute]
                $ParamAttributesCollect.Add($ParamAttributes)
                $DynParam1 = New-Object -Type System.Management.Automation.RuntimeDefinedParameter('TestSuiteID', [string], $ParamAttributesCollect)
                $ParamDictionary.Add('TestSuiteID', $DynParam1)
            }
        }
        Return $ParamDictionary
    }
    
    Begin {
        Connect-NCXCloud
    }
    Process {
        $Body = @{}
        Try {
            Switch ($AlarmType) {
                'Organization' { $URI = "https://$Global:NCXCloud/cyclone-portlet/api/email-notification/result/organization/$Global:NCXOrgID/$($PSBoundParameters['PlanType'])"; Break }
                'TestCase' { $URI = "https://$Global:NCXCloud/cyclone-portlet/api/email-notification/result/test-case/$($PSBoundParameters['TestCaseID'])"; Break }
                'CalledNumber' { $URI = "https://$Global:NCXCloud/cyclone-portlet/api/email-notification/result/called-number/$($PSBoundParameters['CalledNumber'])/$($PSBoundParameters['PlanType'])"; Break }
                'TestSuite' { $URI = "https://$Global:NCXCloud/cyclone-portlet/api/email-notification/result/test-suite/$($PSBoundParameters['TestSuiteID'])" }
            }
            Write-Verbose $URI
            
            If ($TimePeriod) { $Body.Add('duration', $TimePeriod) }
            If ($TimePeriodFrom) { 
                $Body.Add('startDate', $TimePeriodFrom.ToString('dd-MM-yyyy'))
                $Body.Add('endDate', $TimePeriodTo.ToString('dd-MM-yyyy'))
            }

            $JSON = Invoke-RestMethod -Method GET -WebSession $Global:NCXSession -URI $URI -Body $Body        
            Return $JSON
        }
        Catch {
            Write-Error "No data or insufficient permissions. $($_.Exception.Message)"
            If ($PSCmdlet.MyInvocation.BoundParameters["ErrorAction"] -ne "SilentlyContinue") { Get-JSONErrorStream -JSONResponse $_ }
        }
    }
}


Function Get-NCXHistoricalReport {
    <#
        .SYNOPSIS
        Shows NCX historical reports
         
        .DESCRIPTION
        Shows NCX historical reports
 
        .EXAMPLE
        Get-NCXHistoricalReports
 
        .NOTES
        Version 1.0
    #>

    
    [CmdletBinding(PositionalBinding=$False, DefaultParameterSetName = 'Summary')]
    Param (
        [Parameter(Mandatory=$True, ParameterSetName = 'Summary', Position = 0)]
        [Parameter(Mandatory=$True, ParameterSetName = 'SummaryTime', Position = 0)]
        [ValidateSet('Organization', 'SingleCampaignRun', 'AllCampaignRun', 'Campaign', IgnoreCase=$True)]
        [string]$ReportType,
        [Parameter(Mandatory=$False, ParameterSetName = 'Summary')]
        [ValidateSet('LAST_1HR', 'LAST_4HR', 'LAST_12HR', 'LAST_24HR', 'CURRENT_WEEK', 'CURRENT_MONTH', 'LAST_30DAYS', IgnoreCase=$True)]
        [string]$TimePeriod,
        [Parameter(Mandatory=$True, ParameterSetName = 'SummaryTime')]
        [DateTime]$TimePeriodFrom,
        [Parameter(Mandatory=$True, ParameterSetName = 'SummaryTime')]
        [DateTime]$TimePeriodTo
    )
    DynamicParam {
        $ParamDictionary = New-Object -Type System.Management.Automation.RuntimeDefinedParameterDictionary
        Switch ($ReportType) {
            'Organization' {
                # Define parameter attributes for PlanType attribute
                $ParamAttributes = New-Object -Type System.Management.Automation.ParameterAttribute
                $ParamAttributes.Mandatory = $True
                $ParamAttributes.Position = 1
                $ValidateSetAttributes = New-Object System.Management.Automation.ValidateSetAttribute('RADAR', 'EXPRESS', 'VORTEX', 'CYCLONE', 'INBOUND')
                $ParamAttributesCollect = New-Object -Type System.Collections.ObjectModel.Collection[System.Attribute]
                $ParamAttributesCollect.Add($ParamAttributes)
                $ParamAttributesCollect.Add($ValidateSetAttributes)
                $DynParam1 = New-Object -Type System.Management.Automation.RuntimeDefinedParameter('PlanType', [string], $ParamAttributesCollect)
                $ParamDictionary.Add('PlanType', $DynParam1)
                Break
            }
            {$_ -like '*CampaignRun'} {
                # Define parameter attributes for TestCaseID attribute
                $ParamAttributes = New-Object -Type System.Management.Automation.ParameterAttribute
                $ParamAttributes.Mandatory = $True
                $ParamAttributes.Position = 1
                $ParamAttributesCollect = New-Object -Type System.Collections.ObjectModel.Collection[System.Attribute]
                $ParamAttributesCollect.Add($ParamAttributes)
                $DynParam1 = New-Object -Type System.Management.Automation.RuntimeDefinedParameter('TestSuiteRunResultID', [string], $ParamAttributesCollect)
                $ParamDictionary.Add('TestSuiteRunResultID', $DynParam1)
                Break
            }
            'Campaign' {
                # Define parameter attributes for CalledNumber attribute
                $ParamAttributes = New-Object -Type System.Management.Automation.ParameterAttribute
                $ParamAttributes.Mandatory = $True
                $ParamAttributes.Position = 2
                $ParamAttributesCollect = New-Object -Type System.Collections.ObjectModel.Collection[System.Attribute]
                $ParamAttributesCollect.Add($ParamAttributes)
                $DynParam1 = New-Object -Type System.Management.Automation.RuntimeDefinedParameter('CampaignID', [string], $ParamAttributesCollect)
                $ParamDictionary.Add('CampaignID', $DynParam1)
            }            
        }
        Return $ParamDictionary
    }
    
    Begin {
        Connect-NCXCloud
    }
    Process {
        $Body = @{}
        Try {
            Switch ($ReportType) {
                'Organization' { $URI = "https://$Global:NCXCloud/cyclone-portlet/api/test-suite-run-result/organisation/$Global:NCXOrgID/$($PSBoundParameters['PlanType'])"; Break }
                'SingleCampaignRun' { $URI = "https://$Global:NCXCloud/cyclone-portlet/api/test-suite-run-result/summary/$($PSBoundParameters['TestSuiteRunResultID'])"; Break }
                'AllCampaignRun' { $URI = "https://$Global:NCXCloud/cyclone-portlet/api/test-suite-run-result/test-case-result/$($PSBoundParameters['TestSuiteRunResultID'])"; Break }
                'Campaign' { $URI = "https://$Global:NCXCloud/cyclone-portlet/api/test-suite-run-result/test-case-run-result/$($PSBoundParameters['CampaignID'])" }
            }

            Write-Verbose $URI
            
            If ($TimePeriod) { $Body.Add('duration', $TimePeriod) }
            If ($TimePeriodFrom) { 
                $Body.Add('startDate', $TimePeriodFrom.ToString('dd-MM-yyyy'))
                $Body.Add('endDate', $TimePeriodTo.ToString('dd-MM-yyyy'))
            }

            $JSON = Invoke-RestMethod -Method GET -WebSession $Global:NCXSession -URI $URI -Body $Body        
            Return $JSON.data
        }
        Catch {
            Write-Error "No data or insufficient permissions. $($_.Exception.Message)"
            If ($PSCmdlet.MyInvocation.BoundParameters["ErrorAction"] -ne "SilentlyContinue") { Get-JSONErrorStream -JSONResponse $_ }
        }
    }
}


Function Get-NCXLiveReport {
    <#
        .SYNOPSIS
        Shows CX live report information.
         
        .DESCRIPTION
        Shows CX live report information.
 
        .EXAMPLE
        Get-NCXLiveReport
 
        .NOTES
        Version 1.0
    #>

    
    [CmdletBinding(PositionalBinding=$False, DefaultParameterSetName = 'Summary')]
    Param (
        [Parameter(Mandatory=$True, ParameterSetName = 'Summary')]
        [ValidateSet('RADAR', 'EXPRESS', 'VORTEX', 'CYCLONE', 'INBOUND', IgnoreCase=$True)]
        [string]$PlanType,
        [Parameter(Mandatory=$True, ParameterSetName = 'Detail')]
        [ValidateSet('Voice', 'PESQ', 'MOS', IgnoreCase=$True)]
        [string]$ReportType,
        [Parameter(ValueFromPipelineByPropertyName, Mandatory=$True, ParameterSetName = 'Detail')]
        [Alias("id")]
        [string]$DashboardID    
    )
    
    Begin {
        Connect-NCXCloud
    }
    Process {
        Try {
            Switch ($ReportType) {
                'Voice' { $URI = "https://$Global:NCXCloud/cyclone-portlet/api/dashboard/realtime-voice-channel/$DashboardID"; Break }
                'PESQ' { $URI = "https://$Global:NCXCloud/cyclone-portlet/api/dashboard/realtime-pesq/$DashboardID"; Break }
                'MOS' { $URI = "https://$Global:NCXCloud/cyclone-portlet/api/dashboard/realtime-mos/$DashboardID"; Break }
                default { $URI = "https://$Global:NCXCloud/cyclone-portlet/api/dashboard/$Global:NCXOrgID/$PlanType"}
            }
            Write-Verbose $URI
            $JSON = Invoke-RestMethod -Method GET -WebSession $Global:NCXSession -URI $URI
            Return $JSON
        }
        Catch {
            Write-Error "No data or insufficient permissions. $($_.Exception.Message)"
            If ($PSCmdlet.MyInvocation.BoundParameters["ErrorAction"] -ne "SilentlyContinue") { Get-JSONErrorStream -JSONResponse $_ }
        }
    }
}


Function Get-NCXAlarmConfig {
    <#
        .SYNOPSIS
        Shows CX email alarm configuration.
         
        .DESCRIPTION
        Shows CX email alarm configuration.
 
        .EXAMPLE
        Get-NCXAlarmConfig
 
        .NOTES
        Version 1.0
    #>

    
    [CmdletBinding(PositionalBinding=$False, DefaultParameterSetName = 'Summary')]
    Param (
        [Parameter(Mandatory=$True, ParameterSetName = 'Summary')]
        [ValidateSet('RADAR', 'EXPRESS', 'VORTEX', 'CYCLONE', 'INBOUND', IgnoreCase=$True)]
        [string]$PlanType,
        [Parameter(Mandatory=$True, ParameterSetName = 'Detail')]
        [ValidateSet('TestCase', 'CalledNumber', 'TestSuite', IgnoreCase=$True)]
        [string]$AlarmType,
        [Parameter(ValueFromPipelineByPropertyName, Mandatory=$True, ParameterSetName = 'Detail')]
        [Alias('TestCaseID')]
        [string]$ID    
    )
    
    Begin {
        Connect-NCXCloud
    }
    Process {
        Try {
            Switch ($ReportType) {
                'TestCase' { $URI = "https://$Global:NCXCloud/cyclone-portlet/api/email-alarm/test-case/$ID"; Break }
                'CalledNumber' { $URI = "https://$Global:NCXCloud/cyclone-portlet/api/email-alarm/called-number/$ID"; Break }
                'TestSuite' { $URI = "https://$Global:NCXCloud/cyclone-portlet/api/email-alarm/test-suite/$ID"; Break }
                default { $URI = "https://$Global:NCXCloud/cyclone-portlet/api/email-alarm/organization/$Global:NCXOrgID/$PlanType"}
            }
            Write-Verbose $URI
            $JSON = Invoke-RestMethod -Method GET -WebSession $Global:NCXSession -URI $URI
            Return $JSON
        }
        Catch {
            Write-Error "No data or insufficient permissions. $($_.Exception.Message)"
            If ($PSCmdlet.MyInvocation.BoundParameters["ErrorAction"] -ne "SilentlyContinue") { Get-JSONErrorStream -JSONResponse $_ }
        }
    }
}