Microsoft Teams PowerShell: Get-CsOnlineLisCivicAddress Returns “-1” for VoiceUsers and Phone Numbers

If you have ever tried auditing Emergency Addresses in Microsoft Teams PowerShell using Get-CsOnlineLisCivicAddress or Get-CsOnlineLisLocation, You may have noticed something frustrating:

The properties:

  • NumberOfVoiceUsers
  • NumberOfTelephoneNumbers

always return -1.

Even using:

-PopulateNumberOfVoiceUsers
-PopulateNumberOfTelephoneNumbers

does not actually populate the values.

This is a common issue in Microsoft Teams PowerShell, especially in larger tenants managing E911 and Location Information Server (LIS) data.

In this guide, you’ll learn:

  • Why Teams PowerShell returns -1
  • Why the Teams Admin Center shows accurate counts
  • How to reliably identify unused LIS emergency addresses
  • How to build a scalable PowerShell script for cleanup automation
  • How to avoid the hidden 500-result limitation in Get-CsPhoneNumberAssignment
You may also like how to Set Up PSTN Calling in Microsoft Teams

Why Get-CsOnlineLisCivicAddress Returns “-1”

The NumberOfVoiceUsers and NumberOfTelephoneNumbers properties are effectively placeholder values in many cloud-only Microsoft Teams environments.

Although the cmdlets expose these properties, the backend service does not always populate them dynamically because of processing overhead and service-side optimization.

Example:

Get-CsOnlineLisCivicAddress

returns:

NumberOfVoiceUsers       : -1
NumberOfTelephoneNumbers : -1

even when users and numbers are actually assigned.

The Teams Admin Center export works differently because it queries backend assignment databases directly.

The Real Solution: Correlate LIS Data with Phone Number Assignments

Instead of relying on the broken counters, the best approach is:

  1. Pull all LIS Civic Addresses
  2. Pull all assigned phone numbers
  3. Match them using CivicAddressId
  4. Identify locations with zero assignments

This produces results that closely match the Teams Admin Center export.

Install the Microsoft Teams PowerShell Module

Before running the script, install and import the Teams module.

Install-Module -Name MicrosoftTeams -Force -AllowClobber

Get-Module -ListAvailable MicrosoftTeams

Import-Module MicrosoftTeams

Then connect:

Connect-MicrosoftTeams

Fully Working PowerShell Script to Find Empty Teams LIS Sites

This improved version includes pagination handling for environments with more than 500 phone number assignments.

# Connect to Microsoft Teams
Connect-MicrosoftTeams

# Retrieve all Civic Addresses
Write-Host "Fetching all Civic Addresses..." -ForegroundColor Cyan
$allAddresses = Get-CsOnlineLisCivicAddress

# Retrieve assigned phone numbers
Write-Host "Fetching phone number assignments..." -ForegroundColor Cyan

# Initial fetch
$temp_numbers = Get-CsPhoneNumberAssignment |
    Where-Object { $_.CivicAddressId -ne $null }

$assignedNumbers = $temp_numbers

# Handle pagination beyond 500 results
$skip_count = 0

if ($temp_numbers.Count -gt 0) {

    while ($temp_numbers.Count -ne 0) {

        $skip_count += 500

        $temp_numbers = Get-CsPhoneNumberAssignment -Skip $skip_count |
            Where-Object { $_.CivicAddressId -ne $null }

        $assignedNumbers += $temp_numbers
    }
}

# Build report
Write-Host "Analyzing assignments per site..." -ForegroundColor Cyan

$siteReport = foreach ($address in $allAddresses) {

    $currentSiteNumbers = $assignedNumbers |
        Where-Object {
            $_.CivicAddressId -eq $address.CivicAddressId
        }

    $numberCount = ($currentSiteNumbers).Count

    [PSCustomObject]@{
        AddressDescription = $address.Description
        City               = $address.City
        CivicAddressId     = $address.CivicAddressId
        AssignedNumbers    = $numberCount
    }
}

# Find empty sites
$emptySites = $siteReport |
    Where-Object { $_.AssignedNumbers -eq 0 }

# Display results
Write-Host "`nSites with 0 assigned numbers/users:" -ForegroundColor Yellow

$emptySites | Format-Table -AutoSize

Important Discovery: Get-CsPhoneNumberAssignment Has a 500-Result Limit

One major issue many admins overlook:

Get-CsPhoneNumberAssignment

only returns the first 500 results by default.

If your tenant has thousands of users or numbers, your report will incorrectly show many sites as empty unless you paginate using:

-Skip 500

That is why the loop above is essential in enterprise environments.

Without pagination:

  • empty site reports become inaccurate
  • LIS cleanup becomes risky
  • valid emergency locations may appear unused

How to Remove Unused Teams LIS Civic Addresses

Once you verify the results, you can automate cleanup.

foreach ($site in $emptySites) {

    Write-Host "Removing empty site: $($site.AddressDescription)" `
        -ForegroundColor Red

    Remove-CsOnlineLisCivicAddress `
        -CivicAddressId $site.CivicAddressId
}

Always test carefully before bulk deletion.

Why This Method Works Better Than the Built-In Counters

This approach is more reliable because it uses actual assignment data instead of metadata placeholders.

You are effectively:

  • querying real phone number assignments
  • matching them against LIS locations
  • recreating the Teams Admin Center logic manually

For large Microsoft Teams Phone deployments, this is currently the most accurate PowerShell-based auditing method available.

You may also like how to How to Fix AADSTS90023 Error in Microsoft Teams Guest Sign-In Issues on Mobile App

Best Practices for Teams LIS Cleanup

1. Always Export Before Deleting

Before removing addresses:

$siteReport | Export-Csv .\LIS_Report.csv -NoTypeInformation

2. Validate Dynamic Emergency Locations

Some locations may appear unused temporarily because of:

  • hybrid calling setups
  • recently unassigned users
  • delayed synchronization

3. Automate Monthly Audits

Unused LIS entries accumulate over time from:

  • employee departures
  • office closures
  • phone number migrations
  • Direct Routing changes

A scheduled cleanup script can help maintain accuracy.

Frequently Asked Questions

Why does NumberOfVoiceUsers return -1?

Because Microsoft Teams PowerShell often does not dynamically populate those counters in cloud-only tenants. The values are effectively placeholders.

Does -PopulateNumberOfVoiceUsers actually work?

In many environments, no. The parameter exists, but the backend service frequently still returns -1.

Why does Teams Admin Center show correct values?

The Teams Admin Center queries backend assignment databases directly instead of relying on the PowerShell property values.

How do I find unused emergency addresses in Teams?

Use Get-CsPhoneNumberAssignment and correlate results with Get-CsOnlineLisCivicAddress using CivicAddressId.

Is Get-CsPhoneNumberAssignment limited to 500 results?

Yes. You must paginate with:

-Skip 500

for larger tenants.

Can I safely delete unused LIS addresses?

Yes, but only after verifying that no users, numbers, or emergency policies still reference them.

Complete Fix - Google Calendar and Microsoft Teams: Why You Can’t Add Co-Organizers 

Final Thoughts

If Get-CsOnlineLisCivicAddress or Get-CsOnlineLisLocation keeps returning -1. For assignment counts, the issue is not your script — it is a limitation of the Microsoft Teams PowerShell module itself.

The most reliable workaround is to:

  • retrieve real phone number assignments
  • paginate beyond the 500-result limit
  • correlate by CivicAddressId
  • build your own usage report

For Teams administrators managing large E911 environments, this method provides far more accurate cleanup visibility than the built-in counters currently available in PowerShell.

Leave a Comment