Public/New-iPilotTeamsUserAssignment.ps1

Function New-iPilotTeamsUserAssignment {
    <#
        .Synopsis
        Provisions a new user in iPilot

        .Description
        Provisions a user principal name to an iPilot telephone number with optional First Name and Last Name

        .Parameter FirstName
        User's First Name.

        .Parameter LastName
        User's Last Name.

        .Parameter TelephoneNumber
        TelephoneNumber (10-digits).

        .Parameter UserPrincipalName
        User's User Principal Name.

        .Parameter ByNote
        User's Note field value

        .Parameter ApiVersion
        Version of the NuWave iPilot to use. Defaults to v1.

        .Parameter iPilotDomain
        iPilot Domain Name.

        .Parameter Credential
        Credentials for iPilot API

        .Example
        # Get avilable numbers with the status set to Ported using API Version v1 in the contoso.com iPilot domain
        New-iPilotTeamsUserAssignment -UserPrincipalName jdoe@contoso.com -TelephoneNumber 1235551234 -iPilotDomain contoso.com -ApiVersion = "v1"
    #>

    Param (
        [System.String] [Parameter(Mandatory = $true)] 
            $UserPrincipalName,
        [System.Int64] [ValidatePattern('\d{5,15}$')] [Parameter(Mandatory = $true, HelpMessage = 'Provide telephone number in E.164 format without the + character. Ex. 12223334444')]
            $TelephoneNumber,
        [System.String]
            $FirstName,
        [System.String]
            $LastName,
        [System.String]
            $Note,
        [Switch]
            $Wait,
        [System.String]
            $ApiUrl = "https://api.nuwave.com", 
        [System.String]
            $ApiVersion = "v1",
        [System.String]
            $ApiKey,
        [System.String] 
            $iPilotDomain,
        [System.Management.Automation.PSCredential] 
            $Credential
     )

    Begin {
        # UserPrincipalName validation
        If ($UserPrincipalName -and $UserPrincipalName -notlike "*@*.*") {
            throw "Check the formatting of the user's User Principal Name. Format should be jdoe@contoso.com"
        }

        # Set iPilot Domain
        if (!$global:IP_iPilotDomain -and !$iPilotDomain) {
            throw "Run Get-iPilotTeamsDomain or provide domain using -iPilotDomain"
        } elseif (!$iPilotDomain) {
            $iPilotDomain = $global:IP_iPilotDomain
            Write-Verbose "iPilot Domain: $iPilotDomain"
        } # else use passed in iPilotDomain
    }

    Process {
        # Verbose Switch
        if($PSBoundParameters.containskey("Verbose")) {
            $PreviousVerbosePreference = $VerbosePreference
            $VerbosePreference = "continue"
        }

        # Debug Switch
        if($PSBoundParameters.containskey("Debug")) {
            $PreviousDebugPreference = $DebugPreference
            $DebugPreference = "continue"
        }

        # Get/re-use OAuth Token
        $InitializeiPilotSessionSplat = @{
            ApiUrl = $ApiUrl
            ApiVersion = $ApiVersion
            ApiKey = $ApiKey
            Credential = $Credential
        }
        if ($global:IP_Instance) {
            $InitializeiPilotSessionSplat += @{
                Instance = $global:IP_Instance
            }
        }
        if ($VerbosePreference -eq "Continue") {
            $InitializeiPilotSessionSplat += @{
                Verbose = $true
            }
        }
        if ($DebugPreference -eq "Continue") {
            $InitializeiPilotSessionSplat += @{
                Debug = $true
            }
        }
        Initialize-iPilotSession @InitializeiPilotSessionSplat

        # Build iPilot API Request
        $NewiPilotUserRequestUri = "$ApiUrl/$ApiVersion/msteams/$iPilotDomain/users" 
        if ($Instance) {
            $NewiPilotUserRequestUri += "?instance=$Instance"
        }
        Write-Verbose "NewiPilotUserRequestUri:$NewiPilotUserRequestUri"
        
        #region Build Request Body

            Write-Verbose "Request Uri: $NewiPilotUserRequestUri"
            Write-Verbose "Request Method: Post"

            # Add UPN and TelephoneNumber to Body
            $NewiPilotUserRequestBody = @{
                upn = $UserPrincipalName
                telephoneNumber = "$TelephoneNumber"
            }

            # Add First Name to Body
            if ($FirstName) {
                $NewiPilotUserRequestBody += @{
                    firstName = $FirstName
                }
            }

            # Add Last Name to Body
            if ($LastName) {
                $NewiPilotUserRequestBody += @{
                    lastName = $LastName
                }
            }

            # Add Note to Body
            if ($Note) {
                $NewiPilotUserRequestBody += @{
                    note = $Note
                }
            }

            # Add all values under User property
            $NewiPilotUserRequestUserBody = @{
                user = $NewiPilotUserRequestBody
            }
        
        #endregion Build Request Body

        # Splat Invoke-RestMethod Parameters
        $NewiPilotUserInvokeParams = @{
            Uri = $NewiPilotUserRequestUri
            Method = "Post"
            ContentType = "application/json"
            Headers = @{
                "X-Access-Token" = $global:IP_iPilotOAuthToken.access_token
                "x-api-key"      = $global:IP_iPilotApiKey
            }
            Body = $NewiPilotUserRequestUserBody | ConvertTo-Json
        }
        Write-Debug "NewiPilotUserInvokeParams(JSON):$($NewiPilotUserInvokeParams | ConvertTo-Json)"

        # Execute the REST API
        Try {
            $NewiPilotUserResponse = Invoke-RestMethod @NewiPilotUserInvokeParams -ErrorAction Stop
        } Catch {
            Write-Error "Failed to provision $UserPrincipalName to $TelephoneNumber`n`nURL: $($NewiPilotUserRequestUri)`nBody: $($NewiPilotUserRequestBody | Format-Table | Out-String)`n Error: $($_.Exception.Message)"
            break
        }

        # Return User object
        if ($NewiPilotUserResponse.statuscode -eq 200) {
            Write-Output "Successfully provisioned iPilot User.`nUPN: $UserPrincipalName`nTelephoneNumber: $TelephoneNumber)"

            # Wait for user to be configured, else return User object immediately
            if ($Wait.IsPresent) {
                Do {
                    $User = Get-iPilotTeamsUser -FilterByUserPrincipalName $UserPrincipalName
                    if ($User.Status -like "Pending*" -or $User.Status -eq "Queued") {
                        Write-Verbose "User status is $($User.Status), waiting 30 seconds to refresh status"
                        Start-Sleep -Seconds 30
                    }
                } While ($User.Status -like "Pending*" -or $User.Status -eq "Queued")
                return $User
            } else {
                return $User
            }
        } else {
            Write-Error "Failed to provision iPilot User.`nUPN: $UserPrincipalName`nTelephoneNumber: $TelephoneNumber."
        }

        # Verbose Switch
        if($PSBoundParameters.containskey("Verbose")) {
            $VerbosePreference = $PreviousVerbosePreference
        }

        # Debug Switch
        if($PSBoundParameters.containskey("Debug")) {
            $DebugPreference = $PreviousDebugPreference
        }
    }
}