Identifying Dialpad Users who aren't assigned to Coaching Teams


Coaching Teams in Dialpad help ensure that department leads have access to their teams statistics as well as help maintain uniform missed-call handling, call recording and other settings across teams.

It can sometimes be easy for users to get dropped or left out of coaching teams, however, and trying to figure out who isn't covered by a coaching team can be tough if you have hundreds of Dialpad users.

I use this Powershell script to inventory all of my users and search for any that don't have "Operator" status in any coaching team.

Powershell

Write-Host "Fetching Dialpad users that aren't assigned to a Coaching Team"

# Define the API endpoint and key
$apiUrlBase = 'https://dialpad.com/api/v2/users?limit=99&state=active'
$apiKey = Get-Secret -Name DialpadAPIKey -AsPlainText

# Define the office ID to office name mapping
$officeMapping = @{
    'YourOfficeID01' = 'Office01'
    'YourOfficeID02' = 'Office02'
    'YourOfficeID03' = 'Office03'
}

# Make the API request with pagination
$headers = @{
    'accept' = 'application/json'
    'Authorization' = "Bearer $apiKey"
}

$allUsers = @()
$cursor = $null  # Start with no cursor
$pageCount = 0

do {
    # Build the API URL for the current page
    $apiUrl = $apiUrlBase
    if ($cursor) {
        $apiUrl += "&cursor=$cursor"
    }

    # Fetch the response
    try {
        $response = Invoke-RestMethod -Uri $apiUrl -Method Get -Headers $headers
    } catch {
        Write-Error ('Failed to fetch user data on page {0}: {1}' -f $pageCount, $_.Exception.Message)
        break
    }

    # Add the fetched users to the collection
    if ($response.items) {
        $allUsers += $response.items
        Write-Host "Fetched $(($response.items).Count) users from page $pageCount."
    } else {
        Write-Warning "No items returned on page $pageCount."
    }

    # Update the cursor for the next page
    $cursor = if ($response.PSObject.Properties["cursor"]) { $response.cursor } else { $null }
    $pageCount++

} while ($cursor)  # Continue until no cursor is provided

# Filter user accounts
$usersNotInCoachingTeamAsOperator = $allUsers | Where-Object {
    # Check if any group details match the criteria
    $userGroups = $_.group_details
    $notInCoachingTeamAsOperator = $true
    foreach ($group in $userGroups) {
        if ($group.group_type -eq 'coachingteam' -and $group.role -eq 'operator') {
            $notInCoachingTeamAsOperator = $false
            break
        }
    }
    return $notInCoachingTeamAsOperator
}

# Collect filtered users with office name and sort
$sortedUsers = $usersNotInCoachingTeamAsOperator | ForEach-Object {
    # Create a custom object for each user with all necessary properties
    [PSCustomObject]@{
        Office    = if ($_.office_id -and $officeMapping.ContainsKey($_.office_id)) {
                        $officeMapping[$_.office_id]
                    } else {
                        'Unknown Office'
                    }
        Name      = "$($_.first_name) $($_.last_name)"
        Email     = ($_.emails -join ', ')
    }
} | Sort-Object Office  # Sort the custom objects by Office property

# Output the sorted users to console if you like...
# $sortedUsers | ForEach-Object {
#     Write-Host "Office: $($_.Office), Name: $($_.Name), Email: $($_.Email)"
# }

# Export the sorted users to CSV
$sortedUsers | Export-Csv -Path "UsersMissingCoachingTeams.csv" -NoTypeInformation
Write-Host "Users Missing Coaching Teams has been exported"
Write-Host "Fetching Dialpad users that aren't assigned to a Coaching Team"

# Define the API endpoint and key
$apiUrlBase = 'https://dialpad.com/api/v2/users?limit=99&state=active'
$apiKey = Get-Secret -Name DialpadAPIKey -AsPlainText

# Define the office ID to office name mapping
$officeMapping = @{
    'YourOfficeID01' = 'Office01'
    'YourOfficeID02' = 'Office02'
    'YourOfficeID03' = 'Office03'
}

# Make the API request with pagination
$headers = @{
    'accept' = 'application/json'
    'Authorization' = "Bearer $apiKey"
}

$allUsers = @()
$cursor = $null  # Start with no cursor
$pageCount = 0

do {
    # Build the API URL for the current page
    $apiUrl = $apiUrlBase
    if ($cursor) {
        $apiUrl += "&cursor=$cursor"
    }

    # Fetch the response
    try {
        $response = Invoke-RestMethod -Uri $apiUrl -Method Get -Headers $headers
    } catch {
        Write-Error ('Failed to fetch user data on page {0}: {1}' -f $pageCount, $_.Exception.Message)
        break
    }

    # Add the fetched users to the collection
    if ($response.items) {
        $allUsers += $response.items
        Write-Host "Fetched $(($response.items).Count) users from page $pageCount."
    } else {
        Write-Warning "No items returned on page $pageCount."
    }

    # Update the cursor for the next page
    $cursor = if ($response.PSObject.Properties["cursor"]) { $response.cursor } else { $null }
    $pageCount++

} while ($cursor)  # Continue until no cursor is provided

# Filter user accounts
$usersNotInCoachingTeamAsOperator = $allUsers | Where-Object {
    # Check if any group details match the criteria
    $userGroups = $_.group_details
    $notInCoachingTeamAsOperator = $true
    foreach ($group in $userGroups) {
        if ($group.group_type -eq 'coachingteam' -and $group.role -eq 'operator') {
            $notInCoachingTeamAsOperator = $false
            break
        }
    }
    return $notInCoachingTeamAsOperator
}

# Collect filtered users with office name and sort
$sortedUsers = $usersNotInCoachingTeamAsOperator | ForEach-Object {
    # Create a custom object for each user with all necessary properties
    [PSCustomObject]@{
        Office    = if ($_.office_id -and $officeMapping.ContainsKey($_.office_id)) {
                        $officeMapping[$_.office_id]
                    } else {
                        'Unknown Office'
                    }
        Name      = "$($_.first_name) $($_.last_name)"
        Email     = ($_.emails -join ', ')
    }
} | Sort-Object Office  # Sort the custom objects by Office property

# Output the sorted users to console if you like...
# $sortedUsers | ForEach-Object {
#     Write-Host "Office: $($_.Office), Name: $($_.Name), Email: $($_.Email)"
# }

# Export the sorted users to CSV
$sortedUsers | Export-Csv -Path "UsersMissingCoachingTeams.csv" -NoTypeInformation
Write-Host "Users Missing Coaching Teams has been exported"