IONModule.psm1

#Region './Private/Connect-API.ps1' -1

<#
.SYNOPSIS
Connects to the API using a refresh token.

.DESCRIPTION
The Connect-API function is used to establish a connection to the API by providing a refresh token. It retrieves an access token from the API server and sets the necessary variables for authentication.

.PARAMETER RefreshToken
The refresh token to be used for obtaining the access token. If not provided, the function will use the value stored in the $Script:RefreshToken variable.

.EXAMPLE
Connect-API -RefreshToken "xxxxxxxxxxxx"

This example connects to the API using the specified refresh token.

#>

function Connect-API {
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory = $false)]
        [string]$RefreshToken = $Script:RefreshToken
    )

    $Script:formData = @{
        grant_type = "refresh_token"
        refresh_token = $refreshToken
    }

    $url = $script:baseurl + "/oauth/token"
    
    $token = Invoke-RestMethod -Uri $url -Method Post -Form $Script:formData -ContentType "application/x-www-form-urlencoded"

    $script:AuthHeader = @{ Authorization = "Bearer $($token.access_token)" }
    $script:TokenAcquiredTime = Get-Date
    $script:ExpiresIn = $token.expires_in

}
#EndRegion './Private/Connect-API.ps1' 38
#Region './Private/Get-TokenExpiry.ps1' -1

<#
.SYNOPSIS
Calculates the expiry date and time for a token.

.DESCRIPTION
The Get-TokenExpiry function calculates the expiry date and time for a token based on the token's expiration time in seconds.

.PARAMETER ExpiresIn
Specifies the expiration time of the token in seconds. If not provided, the function uses the value stored in the $script:ExpiresIn variable.

.OUTPUTS
System.DateTime
The calculated expiry date and time for the token.

.EXAMPLE
Get-TokenExpiry -ExpiresIn 3600
Calculates the expiry date and time for a token that expires in 3600 seconds (1 hour).

.NOTES
This function requires the $script:TokenAcquiredTime and $script:ExpiresIn variables to be set before calling the function.
#>


function Get-TokenExpiry {
    [CmdletBinding()]
    [OutputType([DateTime])]
    param (
        [Parameter(Mandatory = $false)]
        [int64]$ExpiresIn = $script:ExpiresIn
    )
    if ($script:ExpiresIn -eq $null) {
        return
    } else {
        $Script:ExpiryDateTime = $script:TokenAcquiredTime.AddSeconds($script:ExpiresIn)
        Write-Verbose "Calculated token expiry as $Script:ExpiryDateTime"
    }
}
#EndRegion './Private/Get-TokenExpiry.ps1' 37
#Region './Private/Invoke-PreFlightCheck.ps1' -1

<#
.SYNOPSIS
    Invokes a pre-flight check before connecting to the API.

.DESCRIPTION
    This function performs a pre-flight check before connecting to the API. It checks if the RefreshToken information is available and if the token has expired. If the RefreshToken information is not found or the token has expired, it connects to the API.

.PARAMETER None
    This function does not accept any parameters.

.EXAMPLE
    Invoke-PreFlightCheck

    This example invokes a pre-flight check before connecting to the API.
#>


function Invoke-PreFlightCheck {
    [CmdletBinding()]
    param ()

    if ($null -eq $Script:refreshToken) {
        throw "Cannot continue: RefreshToken information not found. Please run Set-APIDetails before connecting to the API."
        break
    }

    Get-TokenExpiry

    if ((-not $Script:ExpiryDateTime) -or ($script:ExpiryDateTime -lt (Get-Date))) {
        write-Verbose "Token expired or not found. Connecting to CIPP"
        #$request = @{
        # refresh_token = $script:refreshToken
        # grant_type = "refresh_token"
        #}

        Connect-API
    }
}
#EndRegion './Private/Invoke-PreFlightCheck.ps1' 38
#Region './Public/Get-Requests/Get-AccessTokenExpiry.ps1' -1

<#
.SYNOPSIS
Retrieves the expiry time of an access token.

.DESCRIPTION
The Get-AccessTokenExpiry function is used to retrieve the expiry time of an access token by making a request to the "/oauth/validateAccess" endpoint.

.PARAMETER None
This function does not have any parameters.

.EXAMPLE
Get-AccessTokenExpiry

This example gets the expiry time of an access token.

#>


function Get-AccessTokenExpiry {
    [CmdletBinding()]
    param (
    )

    $Endpoint = "/oauth/validateAccess"

    Invoke-TDRestMethod -Endpoint $Endpoint
}
#EndRegion './Public/Get-Requests/Get-AccessTokenExpiry.ps1' 27
#Region './Public/Get-Requests/Get-AllClients.ps1' -1

<#
.SYNOPSIS
Retrieves a list of clients based on specified filters.

.DESCRIPTION
The Get-AllClients function retrieves a list of clients from the specified API endpoint. It allows you to filter the results based on various parameters such as page size, customer email, customer domain, customer status, and customer name.

.PARAMETER PageSize
Specifies the maximum number of clients to retrieve per page. The default value is 1000.

.PARAMETER CustomerEmail
Specifies the email address of the customer to filter the results. This parameter is optional.

.PARAMETER CustomerDomain
Specifies the domain of the customer to filter the results. This parameter is optional.

.PARAMETER CustomerStatus
Specifies the status of the customer to filter the results. Valid values are "ACTIVE", "INACTIVE", and "CUSTOMER_STATUS_UNSPECIFIED". The default value is "CUSTOMER_STATUS_UNSPECIFIED".

.PARAMETER CustomerName
Specifies the name of the customer to filter the results. This parameter is optional.

.EXAMPLE
Get-AllClients -PageSize 500 -CustomerEmail "example@example.com" -CustomerStatus "ACTIVE"

This example retrieves a list of active clients with a page size of 500 and filters the results based on the customer email address.

#>


function Get-AllClients {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $false)]
        [string]$PageSize = 1000,
        [Parameter(Mandatory = $false)]
        [string]$CustomerEmail,
        [Parameter(Mandatory = $false)]
        [string]$CustomerDomain,
        [Parameter(Mandatory = $false)]
        [ValidateSet(
            "ACTIVE",
            "INACTIVE",
            "CUSTOMER_STATUS_UNSPECIFIED")]
        [string]$CustomerStatus = "CUSTOMER_STATUS_UNSPECIFIED",
        [Parameter(Mandatory = $false)]
        [string]$CustomerName
    )

    $Endpoint = "/api/v3/accounts/$script:AccountID/customers"

    $Params = @{
        pageSize                  = $PageSize
        'filter.customerEmail'    = $CustomerEmail
        'filter.customerDomain'   = $CustomerDomain
        'filter.customerStatus'   = $CustomerStatus
        'filter.customerName'     = $CustomerName
    }

    Invoke-TDRestMethod -Endpoint $Endpoint -params $Params
}
#EndRegion './Public/Get-Requests/Get-AllClients.ps1' 61
#Region './Public/Get-Requests/Get-Client.ps1' -1

<#
.SYNOPSIS
Retrieves client information based on the provided CustomerID.

.DESCRIPTION
The Get-Client function retrieves client information from an API endpoint based on the provided CustomerID. It requires the CustomerID parameter to be specified.

.PARAMETER CustomerID
Specifies the ID of the customer for which to retrieve information.

.EXAMPLE
Get-Client -CustomerID "12345"
Retrieves client information for the customer with ID "12345".

#>

function Get-Client {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true)]
        [string]$CustomerID
    )

    $Endpoint = "/api/v3/accounts/$script:AccountID/customers/$CustomerID"

    Invoke-TDRestMethod -Endpoint $Endpoint
}
#EndRegion './Public/Get-Requests/Get-Client.ps1' 27
#Region './Public/Get-Requests/Get-CustomerOrders.ps1' -1

<#
.SYNOPSIS
Retrieves customer orders from the API.

.DESCRIPTION
The Get-CustomerOrders function retrieves customer orders from the API based on the provided parameters. It sends a request to the specified endpoint and returns the response.

.PARAMETER CustomerID
The ID of the customer for which to retrieve orders. This parameter is mandatory.

.PARAMETER SubscriptionStatus
The status of the subscriptions to filter the orders. This parameter is optional.

.PARAMETER PageSize
The maximum number of orders to retrieve per page. The default value is 1000.

.EXAMPLE
Get-CustomerOrders -CustomerID "12345" -SubscriptionStatus "Active" -PageSize 500

This example retrieves active orders for the customer with ID "12345" and sets the page size to 500.

#>


function Get-CustomerOrders {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true)]
        [string]$CustomerID,
        [Parameter(Mandatory = $false)]
        [string]$SubscriptionStatus,
        [Parameter(Mandatory = $false)]
        [int]$PageSize = 1000

    )

    $Endpoint = "/api/v3/accounts/$script:AccountID/customers/$CustomerID/orders"

    $Params = @{
        pageSize                            = $PageSize
        status                              = $SubscriptionStatus
    }

    Invoke-TDRestMethod -Endpoint $Endpoint -params $Params

}
#EndRegion './Public/Get-Requests/Get-CustomerOrders.ps1' 46
#Region './Public/Get-Requests/Get-CustomerSubscriptions.ps1' -1

<#
.SYNOPSIS
Retrieves customer subscriptions based on specified parameters.

.DESCRIPTION
The Get-Subscriptions function retrieves customer subscriptions based on the specified parameters. It sends a request to the specified API endpoint with the provided parameters and returns the response.

.PARAMETER CustomerID
The ID of the customer for which to retrieve subscriptions. This parameter is mandatory.

.PARAMETER SubscriptionID
The ID of the specific subscription to retrieve. This parameter is optional.

.PARAMETER ResellerID
The ID of the reseller associated with the subscriptions. This parameter is optional.

.PARAMETER ProviderID
The ID of the provider associated with the subscriptions. This parameter is optional.

.PARAMETER SubscriptionStatus
The status of the subscriptions to retrieve. Valid values are: ACCEPTED, ACTIVE, AVAILABLE, CANCELLED, COMPLETE, CONFIRMED, DELETED, DISABLED, ENABLED, ERROR, EXPIRED, FAILED, IN_PROGRESS, PAUSED, PENDING, RUNNING, STOPPED, SUSPENDED. This parameter is optional.

.PARAMETER Range
The date range for which to retrieve subscriptions. Valid values are: TODAY, MONTH_TO_DATE, QUARTER_TO_DATE, YEAR_TO_DATE, LAST_MONTH, LAST_365_DAYS, LAST_QUARTER, LAST_YEAR, LATEST_MONTH, WEEK_TO_DATE, LAST_WEEK, TWO_MONTHS_AGO. This parameter is optional.

.PARAMETER Term
The billing term of the subscriptions. Valid values are: MONTHLY, ANNUAL. This parameter is optional.

.PARAMETER BillingCycle
The billing cycle of the subscriptions. Valid values are: MONTHLY, ANNUAL. This parameter is optional.

.PARAMETER CustomerName
The name of the customer for which to retrieve subscriptions. This parameter is optional.

.EXAMPLE
Get-Subscriptions -CustomerID "12345" -SubscriptionStatus "ACTIVE" -Range "LAST_MONTH"
Retrieves all active subscriptions for the customer with ID "12345" that were created in the last month.

#>


function Get-Subscriptions {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true)]
        [string]$CustomerID,
        [Parameter(Mandatory = $false)]
        [guid]$SubscriptionID,
        [Parameter(Mandatory = $false)]
        [string]$ResellerID,
        [Parameter(Mandatory = $false)]
        [string]$ProviderID,
        [Parameter(Mandatory = $false)]
        [ValidateSet(
            "ACCEPTED",
            "ACTIVE",
            "AVAILABLE",
            "CANCELLED",
            "COMPLETE",
            "CONFIRMED",
            "DELETED",
            "DISABLED",
            "ENABLED",
            "ERROR",
            "EXPIRED",
            "FAILED",
            "IN_PROGRESS",
            "PAUSED",
            "PENDING",
            "RUNNING",
            "STOPPED",
            "SUSPENDED"
            )]
        [string]$SubscriptionStatus,
        [Parameter(Mandatory = $false)]
        [ValidateSet(
            "TODAY",
            "MONTH_TO_DATE",
            "QUARTER_TO_DATE",
            "YEAR_TO_DATE",
            "LAST_MONTH",
            "LAST_365_DAYS",
            "LAST_QUARTER",
            "LAST_YEAR",
            "LATEST_MONTH",
            "WEEK_TO_DATE",
            "LAST_WEEK",
            "TWO_MONTHS_AGO"
            )]
        [string]$Range,
        [Parameter(Mandatory = $false)]
        [ValidateSet(
            "MONTHLY",
            "ANNUAL"
            )]
        [string]$Term,
        [Parameter(Mandatory = $false)]
        [ValidateSet(
            "MONTHLY",
            "ANNUAL"
            )]
        [string]$BillingCycle,
        [Parameter(Mandatory = $false)]
        [string]$CustomerName
    )

    $Endpoint = "/api/v3/accounts/$script:AccountID/subscriptions"

    $Params = @{
        customerId                          = $CustomerID
        subscription_id                     = $SubscriptionID
        resellerId                          = $ResellerID
        providerId                          = $ProviderID 
        subscriptionStatus                  = $SubscriptionStatus
        'startDateRange.relativeDateRange'  = $Range
        billingTerm                         = $Term
        billingCycle                        = $BillingCycle
        customerName                        = $CustomerName
    }

    Invoke-TDRestMethod -Endpoint $Endpoint -params $Params
}

#EndRegion './Public/Get-Requests/Get-CustomerSubscriptions.ps1' 123
#Region './Public/Get-Requests/Get-ProvisioningTemplate.ps1' -1

<#
.SYNOPSIS
Retrieves a provisioning template from the specified vendor.

.DESCRIPTION
The Get-ProvisioningTemplate function retrieves a provisioning template from the specified vendor using the specified parameters. It makes a REST API call to the specified endpoint and returns the response.

.PARAMETER vendor
Specifies the vendor from which to retrieve the provisioning template. Valid values are "MICROSOFT", "GOOGLE", "IBM", and "SOPHOS". The default value is "MICROSOFT".

.PARAMETER Provider
Specifies the provider for the provisioning template. This parameter is optional.

.PARAMETER Action
Specifies the action to perform with the provisioning template. Valid values are "CREATE", "UPDATE", and "ACTION_NOT_SPECIFIED". The default value is "ACTION_NOT_SPECIFIED".

.EXAMPLE
Get-ProvisioningTemplate -vendor "MICROSOFT"
Retrieves a provisioning template from MICROSOFT Cloud Platform with the default provider and action.

#>


function Get-ProvisioningTemplate {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $false)]
        [ValidateSet(
            "MICROSOFT",
            "GOOGLE",
            "IBM",
            "SOPHOS"
        )]
        [string]$vendor = "MICROSOFT",
        [Parameter(Mandatory = $false)]
        [string]$Provider,
        [Parameter(Mandatory = $false)]
        [ValidateSet(
            "CREATE",
            "UPDATE",
            "ACTION_NOT_SPECIFIED"
        )]
        [string]$Action = "ACTION_NOT_SPECIFIED"
    )

    $Endpoint = "/api/v3/accounts/$script:AccountID/provisionTemplates"

    $Params = @{
        vendor = $vendor
        provider = $Provider
        action = $Action
    }

    Invoke-TDRestMethod -Endpoint $Endpoint -params $Params

}
#EndRegion './Public/Get-Requests/Get-ProvisioningTemplate.ps1' 56
#Region './Public/Invoke-TDRestMethod.ps1' -1

function Invoke-TDRestMethod {
    param (
        [string]$Endpoint,
        [hashtable]$Params = @{},
        [string]$Method = 'GET',
        [hashtable]$Body = @{},
        [string]$ContentType = 'application/json'
    )

    try {
        Invoke-PreFlightCheck
    } catch {
        Write-Error "$($_.Exception.Message)"
        break
    }

    # Assemble parameters
    $ParamCollection = [System.Web.HttpUtility]::ParseQueryString([String]::Empty)

    $Params.GetEnumerator() | ForEach-Object {
        $ParamCollection.Add($_.Key, $_.Value)
    }
    $Request = $ParamCollection.ToString()

    $UriBuilder = [System.UriBuilder]('{0}{1}' -f $script:baseUrl, $Endpoint)
    $UriBuilder.Query = $Request

    $BodyJson = $Body | ConvertTo-Json -Depth 10

    $Request = @{
        Uri         = $UriBuilder.ToString()
        Method      = $Method
        Headers     = $script:AuthHeader
        ContentType = $ContentType
    }

    if ($Body.Count -gt 0) {
        $Request.Add('Body', $BodyJson)
    }
    
    Write-Verbose "$Method [ $($UriBuilder.ToString()) ]"
    
    $response = Invoke-RestMethod @Request
    return $response

}
#EndRegion './Public/Invoke-TDRestMethod.ps1' 47
#Region './Public/Post-Requests/Set-Renewal.ps1' -1

<#
.SYNOPSIS
Sets the renewal settings for a subscription.

.DESCRIPTION
The Set-Renewal function is used to update the renewal settings for a subscription in an API. It takes in various parameters such as customer ID, product ID, SKU ID, plan ID, subscription ID, quantity, auto-renew setting, and subscription name. It then constructs the necessary API endpoint and request body to update the subscription's renewal settings.

.PARAMETER customerID
The ID of the customer associated with the subscription.

.PARAMETER ProductId
The ID of the product associated with the subscription.

.PARAMETER SkuID
The ID of the SKU associated with the subscription. (ccpSkuId)

.PARAMETER PlanID
The ID of the plan associated with the subscription. (ccpPlanId)

.PARAMETER SubscriptionID
The ID of the subscription to be updated.

.PARAMETER Quantity
The quantity of the subscription.

.PARAMETER AutoRenew
The auto-renew setting for the subscription. Valid values are "auto-off" and "auto-on".

.PARAMETER SubscriptionName
The display name of the subscription.

.EXAMPLE
Set-Renewal -customerID "12345" -ProductId "Microsoft365EandFNCE-uknce" -SkuID "USCFQ7TTC0LH180001" -PlanID "Microsoft-365-Business-Basic" -SubscriptionID "b9bd9b30-6ae3-4d15-c438-f3cde89888ea" -Quantity 1 -AutoRenew "auto-on" -SubscriptionName "Microsoft 365 Business Basic"
#>


function Set-Renewal {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true)]
        [string]$customerID,
        [Parameter(Mandatory = $true)]
        [string]$ProductId,
        [Parameter(Mandatory = $true)]
        [string]$SkuID,
        [Parameter(Mandatory = $true)]
        [string]$PlanID,
        [Parameter(Mandatory = $true)]
        [string]$SubscriptionID,
        [Parameter(Mandatory = $true)]
        [int]$Quantity,
        [Parameter(Mandatory = $true)]
        [validateset(
            "auto-off",
            "auto-on"
            )]
        [string]$AutoRenew,
        [Parameter(Mandatory = $true)]
        [string]$SubscriptionName
    )

    $Endpoint = "/api/v3/accounts/$script:AccountID/customers/$CustomerID/orders"

    $Body = @{
        displayName = $SubscriptionName
        orderItems = @(
            @{
                productId = $ProductId
                skuId = $SkuID
                planId = $PlanID
                action = "UPDATE"
                quantity = $Quantity
                resourceId = $SubscriptionID
                attributes = @(
                    @{
                        name = "operations"
                        value = "updatesubscription"
                    }
                    @{
                        name = "renewalSetting"
                        value = $AutoRenew
                    }
                )
            }
        )
    }

    Invoke-TDRestMethod -Endpoint $Endpoint -Body $Body -Method 'POST'
}

#EndRegion './Public/Post-Requests/Set-Renewal.ps1' 90
#Region './Public/Set-APIDetails.ps1' -1

<#
.SYNOPSIS
Sets the API details for the module.

.DESCRIPTION
The Set-APIDetails function is used to set the API details required for the script to interact with the API.

.PARAMETER refreshToken
The refresh token required for authentication.

.PARAMETER AccountID
The account ID associated with the API.

.EXAMPLE
Set-APIDetails -refreshToken "your_refresh_token" -AccountID "your_account_id"

This example sets the API details using the provided refresh token and account ID.

#>

function Set-APIDetails {
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory = $true)]
        [string]$refreshToken,
        [Parameter(Mandatory = $true)]
        [string]$AccountID
    )
    write-Verbose "Setting API Info"
    $script:refreshToken = $refreshToken
    $script:baseurl = "https://ion.tdsynnex.com"
    $Script:AccountID = $AccountID
}
#EndRegion './Public/Set-APIDetails.ps1' 33