Public/ServicePointApiEndpoints.ps1

function Get-SNChangeRequestBrief {
    param(
        [Parameter(Mandatory = $true)]
        [string]$changeNumber
    )
}

function Get-SNChangeRequestDetailed {
    param(
        [Parameter(Mandatory = $true)]
        [string]$changeNumber
    )
}

function New-SNStandardVeryLowRiskChange {
    param(
        [Parameter(Mandatory = $true)]
        [string]$standardChangeTemplate,
        [Parameter(Mandatory = $true)]
        [string]$shortDescription,
        [Parameter(Mandatory = $true)]
        [string]$description,
        [Parameter(Mandatory = $true)]
        [string]$requestedBy,
        [Parameter(Mandatory = $true)]
        [string]$category,
        [Parameter(Mandatory = $true)]
        [string]$subcategory,
        [Parameter(Mandatory = $true)]
        [string]$configurationItem,
        [Parameter(Mandatory = $true)]
        [string]$impact,
        [bool]$corporateSystems,
        [string]$onBehalfDivision,
        [Parameter(Mandatory = $true)]
        [string]$assignmentGroup,
        [Parameter(Mandatory = $true)]
        [string]$environment,
        [Parameter(Mandatory = $true)]
        [bool]$codeChange,
        [Parameter(Mandatory = $true)]
        [bool]$updateDR,
        [string]$relatedProject,
        [string]$businessReason,
        [string]$changeExecutionPlan,
        [string]$backoutRollForwardPlan,
        [string]$backoutPlan,
        [string]$backoutPlanDuration,
        [string]$rollForwardPlan,
        [string]$validationPlan,
        [string]$clientPostImplValidation,
        [string]$escalationContact,
        [string]$functionalityImpact,
        [Parameter(Mandatory = $true)]
        [string]$validationScheduledStartDate,
        [Parameter(Mandatory = $true)]
        [string]$validationScheduledEndDate,
        [Parameter(Mandatory = $true)]
        [string]$validationDataCenter,
        [Parameter(Mandatory = $true)]
        [string]$validationMaintenanceWindow,
        [Parameter(Mandatory = $true)]
        [string]$validationShortDescription,
        [string]$validationDescription,
        [Parameter(Mandatory = $true)]
        [string]$validationAssignmentGroup,
        [Parameter(Mandatory = $true)]
        [string]$validationAcceptanceCriteria,
        [string[]]$affectedCIs
    )
}

<#
.SYNOPSIS
Creates a Standard Low Risk change request.

.DESCRIPTION
Creates a Standard Low Risk change request based on the ServicePoint Change Management
API playbook design details. The document notes that this endpoint is not developed and
is included as design documentation only.

The standard change template is applied last, so values supplied to the API do not override
values defined in the approved standard change template.

.PARAMETER standardChangeTemplate
Name of the standard change template. If blank, template validation does not apply. If
provided, the exact name must exist in the Standard Change Catalog.

.PARAMETER shortDescription
Short description of the change request.

.PARAMETER description
Detailed description of the change request.

.PARAMETER requestedBy
Email address of the associate requesting the change.

.PARAMETER category
Change category. The document says to use fetchChangeCategories for valid values.

.PARAMETER subcategory
Change subcategory. The document says to use fetchChangeSubCategories for valid values.

.PARAMETER configurationItem
Configuration Item name for the change.

.PARAMETER impact
Impact value. The document lists these values: 1 - High, 2 - Medium, 3 - Low.

.PARAMETER corporateSystems
Boolean flag indicating whether the change is related to corporate systems.

.PARAMETER onBehalfDivision
Division reference. The document says to use fetchDivisions for the reference list.

.PARAMETER assignmentGroup
Assignment group reference for the change.

.PARAMETER environment
Environment value. The document lists these values: Production, Development, DR, Testing,
Prod/DR, Cert, and LowerCorp.

.PARAMETER codeChange
Boolean flag indicating whether this is a code change.

.PARAMETER updateDR
Boolean flag indicating whether disaster recovery documentation or configuration should be updated.

.PARAMETER relatedProject
Related project name or identifier.

.PARAMETER businessReason
Business reason for the change.

.PARAMETER changeExecutionPlan
Execution plan for implementing the change.

.PARAMETER backoutRollForwardPlan
Indicates whether the recovery approach is Backout plan or Roll forward plan.

.PARAMETER backoutPlan
Backout plan text. Required when backoutRollForwardPlan is set to Backout plan.

.PARAMETER backoutPlanDuration
Duration of the backout plan. Required when backoutRollForwardPlan is set to Backout plan.

.PARAMETER rollForwardPlan
Roll forward plan text. Required when backoutRollForwardPlan is set to Roll forward plan.

.PARAMETER validationPlan
Validation plan for the change.

.PARAMETER clientPostImplValidation
Client post-implementation validation value. The document says this is only used when the
category is Application and lists: None, Yes - Inside Maintenance Window,
No - Outside Maintenance Window, No - Internal Validation Only.

.PARAMETER escalationContact
Escalation contact details. The document recommends including name, email, and voice number.

.PARAMETER functionalityImpact
Description of the functionality impact.

.PARAMETER validationScheduledStartDate
Validation task scheduled start date and time in YYYY-MM-DD HH:MM format, in GMT.

.PARAMETER validationScheduledEndDate
Validation task scheduled end date and time in YYYY-MM-DD HH:MM format, in GMT.

.PARAMETER validationDataCenter
Validation task data center reference. The document says to use fetchDataCenters for valid values.

.PARAMETER validationMaintenanceWindow
Validation task maintenance window reference. The document says to use fetchMaintenanceWindows
for valid values.

.PARAMETER validationShortDescription
Short description for the validation task.

.PARAMETER validationDescription
Detailed description for the validation task.

.PARAMETER validationAssignmentGroup
Assignment group for the validation task. The document says to use fetchGroups for valid values.

.PARAMETER validationAcceptanceCriteria
Acceptance criteria for the validation task.

.PARAMETER affectedCIs
Comma-separated list of affected CI names. The document states only CIs in a managed class
are accepted and duplicate names are ignored after the first occurrence.

.EXAMPLE
New-SNStandardLowRiskChange `
    -standardChangeTemplate 'Windows Monthly Patch Template' `
    -shortDescription 'Monthly patching for payroll application servers' `
    -description 'Apply approved monthly patches to production payroll application servers.' `
    -requestedBy 'owner@contoso.com' `
    -category 'Application' `
    -subcategory 'Patch' `
    -configurationItem 'prd-payroll-app-01' `
    -impact '2 - Medium' `
    -assignmentGroup 'Enterprise Application Support' `
    -environment 'Production' `
    -codeChange $false `
    -updateDR $false `
    -validationScheduledStartDate '2026-03-28 01:00' `
    -validationScheduledEndDate '2026-03-28 02:00' `
    -validationDataCenter 'Primary DC' `
    -validationMaintenanceWindow 'Saturday 01:00-03:00 UTC' `
    -validationShortDescription 'Validate payroll application after patching' `
    -validationAssignmentGroup 'Enterprise Application Support' `
    -validationAcceptanceCriteria 'Users can log in and complete payroll processing.' `
    -affectedCIs 'prd-payroll-app-01','prd-payroll-app-02'

Shows a representative Standard Low Risk change request using a template and two affected CIs.

.EXAMPLE
New-SNStandardLowRiskChange `
    -standardChangeTemplate 'Database Maintenance Template' `
    -shortDescription 'Quarterly database maintenance for finance reporting' `
    -description 'Perform index maintenance and statistics updates for the finance reporting database.' `
    -requestedBy 'dba.lead@contoso.com' `
    -category 'Database' `
    -subcategory 'Maintenance' `
    -configurationItem 'prd-finance-sql-01' `
    -impact '3 - Low' `
    -corporateSystems $true `
    -assignmentGroup 'Database Operations' `
    -environment 'Production' `
    -codeChange $false `
    -updateDR $true `
    -backoutRollForwardPlan 'Backout plan' `
    -backoutPlan 'Restore the pre-maintenance backup and revert maintenance changes.' `
    -backoutPlanDuration '00:30' `
    -validationPlan 'Confirm scheduled jobs complete and reporting queries succeed.' `
    -validationScheduledStartDate '2026-04-05 03:00' `
    -validationScheduledEndDate '2026-04-05 04:00' `
    -validationDataCenter 'Primary DC' `
    -validationMaintenanceWindow 'Sunday 03:00-05:00 UTC' `
    -validationShortDescription 'Validate database health after maintenance' `
    -validationDescription 'Run health checks and verify reporting functionality.' `
    -validationAssignmentGroup 'Database Operations' `
    -validationAcceptanceCriteria 'Database health checks pass and reporting is available.' `
    -affectedCIs 'prd-finance-sql-01'

Shows a Standard Low Risk change that uses a backout plan and a validation task description.
#>

function New-SNStandardLowRiskChange {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true)]
        [string]$standardChangeTemplate,
        [Parameter(Mandatory = $true)]
        [string]$shortDescription,
        [Parameter(Mandatory = $true)]
        [string]$description,
        [Parameter(Mandatory = $true)]
        [string]$requestedBy,
        [Parameter(Mandatory = $true)]
        [string]$category,
        [Parameter(Mandatory = $true)]
        [string]$subcategory,
        [Parameter(Mandatory = $true)]
        [string]$configurationItem,
        [Parameter(Mandatory = $true)]
        [string]$impact,
        [bool]$corporateSystems,
        [string]$onBehalfDivision,
        [Parameter(Mandatory = $true)]
        [string]$assignmentGroup,
        [Parameter(Mandatory = $true)]
        [string]$environment,
        [Parameter(Mandatory = $true)]
        [bool]$codeChange,
        [Parameter(Mandatory = $true)]
        [bool]$updateDR,
        [string]$relatedProject,
        [string]$businessReason,
        [string]$changeExecutionPlan,
        [string]$backoutRollForwardPlan,
        [string]$backoutPlan,
        [string]$backoutPlanDuration,
        [string]$rollForwardPlan,
        [string]$validationPlan,
        [string]$clientPostImplValidation,
        [string]$escalationContact,
        [string]$functionalityImpact,
        [Parameter(Mandatory = $true)]
        [string]$validationScheduledStartDate,
        [Parameter(Mandatory = $true)]
        [string]$validationScheduledEndDate,
        [Parameter(Mandatory = $true)]
        [string]$validationDataCenter,
        [Parameter(Mandatory = $true)]
        [string]$validationMaintenanceWindow,
        [Parameter(Mandatory = $true)]
        [string]$validationShortDescription,
        [string]$validationDescription,
        [Parameter(Mandatory = $true)]
        [string]$validationAssignmentGroup,
        [Parameter(Mandatory = $true)]
        [string]$validationAcceptanceCriteria,
        [string[]]$affectedCIs,
        [string]$Server,
        [pscredential]$Credential,
        [string]$SessionName = 'Default',
        [string]$EndpointPath = '/createStandardLowRiskChange',
        [string]$Uri,
        [switch]$AllowInsecureSSL,
        [int]$TimeoutSec = 60
    )

    begin {
        $authenticationPath = Join-Path -Path $PSScriptRoot -ChildPath 'Authentication.ps1'
        if (-not (Get-Command -Name Invoke-SNRequest -ErrorAction SilentlyContinue)) {
            if (-not (Test-Path -Path $authenticationPath -PathType Leaf)) {
                throw "Authentication helper file not found: $authenticationPath"
            }

            . $authenticationPath
        }
    }

    process {
        if ($backoutRollForwardPlan -eq 'Backout plan') {
            if ([string]::IsNullOrWhiteSpace($backoutPlan) -or [string]::IsNullOrWhiteSpace($backoutPlanDuration)) {
                throw 'When backoutRollForwardPlan is "Backout plan", both backoutPlan and backoutPlanDuration are required.'
            }
        }

        if ($backoutRollForwardPlan -eq 'Roll forward plan' -and [string]::IsNullOrWhiteSpace($rollForwardPlan)) {
            throw 'When backoutRollForwardPlan is "Roll forward plan", rollForwardPlan is required.'
        }

        $requestBody = [ordered]@{
            standardChangeTemplate       = $standardChangeTemplate
            shortDescription             = $shortDescription
            description                  = $description
            requestedBy                  = $requestedBy
            category                     = $category
            subcategory                  = $subcategory
            configurationItem            = $configurationItem
            impact                       = $impact
            corporateSystems             = $corporateSystems
            onBehalfDivision             = $onBehalfDivision
            assignmentGroup              = $assignmentGroup
            environment                  = $environment
            codeChange                   = $codeChange
            updateDR                     = $updateDR
            relatedProject               = $relatedProject
            businessReason               = $businessReason
            changeExecutionPlan          = $changeExecutionPlan
            backoutRollForwardPlan       = $backoutRollForwardPlan
            backoutPlan                  = $backoutPlan
            backoutPlanDuration          = $backoutPlanDuration
            rollForwardPlan              = $rollForwardPlan
            validationPlan               = $validationPlan
            clientPostImplValidation     = $clientPostImplValidation
            escalationContact            = $escalationContact
            functionalityImpact          = $functionalityImpact
            validationScheduledStartDate = $validationScheduledStartDate
            validationScheduledEndDate   = $validationScheduledEndDate
            validationDataCenter         = $validationDataCenter
            validationMaintenanceWindow  = $validationMaintenanceWindow
            validationShortDescription   = $validationShortDescription
            validationDescription        = $validationDescription
            validationAssignmentGroup    = $validationAssignmentGroup
            validationAcceptanceCriteria = $validationAcceptanceCriteria
            affectedCIs                  = $affectedCIs
        }

        foreach ($key in @($requestBody.Keys)) {
            $value = $requestBody[$key]
            if ($null -eq $value) {
                $requestBody.Remove($key)
                continue
            }

            if ($value -is [string] -and [string]::IsNullOrWhiteSpace($value)) {
                $requestBody.Remove($key)
                continue
            }

            if ($value -is [array] -and $value.Count -eq 0) {
                $requestBody.Remove($key)
            }
        }

        if (-not $Uri) {
            $session = Get-SNSession -Name $SessionName -Server $Server -Credential $Credential
            if (-not $session) {
                if (-not $Server -or -not $Credential) {
                    throw 'Provide -Uri directly, or provide -Server and -Credential so a reusable ServicePoint session can be created.'
                }

                $session = New-SNSession -Name $SessionName -Server $Server -Credential $Credential -AllowInsecureSSL:$AllowInsecureSSL -PassThru
            }

            $targetUri = '{0}/{1}' -f $session.Server.TrimEnd('/'), $EndpointPath.TrimStart('/')
        } else {
            $targetUri = $Uri
        }

        $response = Invoke-SNRequest -Method POST -Uri $targetUri -Body $requestBody -SessionName $SessionName -Server $Server -Credential $Credential -AllowInsecureSSL:$AllowInsecureSSL -TimeoutSec $TimeoutSec

        if ($response.Status -eq 'failure') {
            return [pscustomobject]@{
                Status         = 'failure'
                HttpStatusCode = $response.HttpStatusCode
                ErrorCode      = $response.ErrorCode
                Message        = $response.Message
                Detail         = $response.Detail
                Body           = $response.Body
            }
        }

        $body = $response.Body
        $changeNumber = $body.changeNumber
        $changeTaskNumbers = $body.changeTaskNumbers

        if (-not $changeNumber -and $body.result) {
            $changeNumber = $body.result.changeNumber
            $changeTaskNumbers = $body.result.changeTaskNumbers
        }

        return [pscustomobject]@{
            Status            = 'success'
            HttpStatusCode    = $response.HttpStatusCode
            ChangeNumber      = $changeNumber
            ChangeTaskNumbers = $changeTaskNumbers
            Body              = $body
        }
    }
}

function New-SNChangeTask {
    param(
        [string]$changeTaskTemplate,
        [Parameter(Mandatory = $true)]
        [string]$changeNumber,
        [string]$changeTaskType,
        [Parameter(Mandatory = $true)]
        [string]$scheduledStartDate,
        [Parameter(Mandatory = $true)]
        [string]$scheduledEndDate,
        [string]$autoCM_Endevor_IPL,
        [Parameter(Mandatory = $true)]
        [string]$datacenter,
        [Parameter(Mandatory = $true)]
        [string]$maintenanceWindow,
        [Parameter(Mandatory = $true)]
        [string]$environment,
        [string]$validation,
        [string]$rescheduleReason,
        [Parameter(Mandatory = $true)]
        [string]$assignmentGroup,
        [string]$assignedTo,
        [string]$rollOut,
        [string]$rollBack,
        [Parameter(Mandatory = $true)]
        [string]$shortDescription,
        [Parameter(Mandatory = $true)]
        [string]$description,
        [Parameter(Mandatory = $true)]
        [string]$acceptanceCriteria
    )
}

function Add-SNChangeWorkNote {
    param(
        [Parameter(Mandatory = $true)]
        [string]$changeNumber,
        [Parameter(Mandatory = $true)]
        [string]$workNote
    )
}

function Add-SNChangeTaskWorkNote {
    param(
        [Parameter(Mandatory = $true)]
        [string]$changeTaskNumber,
        [Parameter(Mandatory = $true)]
        [string]$workNote
    )
}

function Add-SNAffectedCIs {
    param(
        [Parameter(Mandatory = $true)]
        [string]$changeNumber,
        [Parameter(Mandatory = $true)]
        [string[]]$affectedCIs
    )
}

function Remove-SNAffectedCIs {
    param(
        [Parameter(Mandatory = $true)]
        [string]$changeNumber,
        [Parameter(Mandatory = $true)]
        [string[]]$affectedCIs
    )
}

function Close-SNChangeTask {
    param(
        [string]$changeTaskNumber,
        [Parameter(Mandatory = $true)]
        [string]$closureCode,
        [Parameter(Mandatory = $true)]
        [string]$workNote
    )
}

function Cancel-SNChange {
    param(
        [Parameter(Mandatory = $true)]
        [string]$changeNumber,
        [Parameter(Mandatory = $true)]
        [string]$workNote
    )
}

function Review-SNChange {
    param(
        [Parameter(Mandatory = $true)]
        [string]$changeNumber,
        [string]$closeCode,
        [Parameter(Mandatory = $true)]
        [string]$workNote
    )
}

function New-SNStandardVeryLowRiskChangeAsync {
    param(
        [Parameter(Mandatory = $true)]
        [string]$standardChangeTemplate,
        [Parameter(Mandatory = $true)]
        [string]$shortDescription,
        [Parameter(Mandatory = $true)]
        [string]$description,
        [Parameter(Mandatory = $true)]
        [string]$requestedBy,
        [Parameter(Mandatory = $true)]
        [string]$category,
        [Parameter(Mandatory = $true)]
        [string]$subcategory,
        [Parameter(Mandatory = $true)]
        [string]$configurationItem,
        [Parameter(Mandatory = $true)]
        [string]$impact,
        [bool]$corporateSystems,
        [string]$onBehalfDivision,
        [Parameter(Mandatory = $true)]
        [string]$assignmentGroup,
        [Parameter(Mandatory = $true)]
        [string]$environment,
        [Parameter(Mandatory = $true)]
        [bool]$codeChange,
        [Parameter(Mandatory = $true)]
        [bool]$updateDR,
        [string]$relatedProject,
        [string]$businessReason,
        [string]$changeExecutionPlan,
        [string]$backoutRollForwardPlan,
        [string]$backoutPlan,
        [string]$backoutPlanDuration,
        [string]$rollForwardPlan,
        [string]$validationPlan,
        [string]$clientPostImplValidation,
        [string]$escalationContact,
        [string]$functionalityImpact,
        [Parameter(Mandatory = $true)]
        [string]$validationScheduledStartDate,
        [Parameter(Mandatory = $true)]
        [string]$validationScheduledEndDate,
        [Parameter(Mandatory = $true)]
        [string]$validationDataCenter,
        [Parameter(Mandatory = $true)]
        [string]$validationMaintenanceWindow,
        [Parameter(Mandatory = $true)]
        [string]$validationShortDescription,
        [string]$validationDescription,
        [Parameter(Mandatory = $true)]
        [string]$validationAssignmentGroup,
        [Parameter(Mandatory = $true)]
        [string]$validationAcceptanceCriteria,
        [string[]]$affectedCIs
    )
}

function Get-SNChangeRequestsByQuery {
    param(
        [string]$sysparm_query
    )
}

function Get-SNCatalogNumbers {
    param(
        [string]$catalogDesc
    )
}

function Get-SNChangeCategories {
    param(
        [string]$categoryDesc
    )
}

function Get-SNChangeSubCategories {
    param(
        [string]$category,
        [string]$subCategoryDesc
    )
}

function Get-SNCIs {
    param(
        [string]$cIName
    )
}

function Get-SNDataCenters {
    param(
        [string]$dataCenterName
    )
}

function Get-SNDivisions {
    param()
}

function Get-SNEnvironments {
    param(
        [string]$environmentName
    )
}

function Get-SNGroups {
    param(
        [string]$groupName
    )
}

function Get-SNImpacts {
    param(
        [string]$impactDesc
    )
}

function Get-SNMaintenanceWindows {
    param(
        [string]$maintWindowDesc
    )
}

function Get-SNPITEs {
    param(
        [string]$pITEDesc
    )
}

function Get-SNTransaction {
    param(
        [string]$TransactionID
    )
}