Back to script library
Entra / Microsoft 365 · Teams

Populate Teams directory SharePoint list (Graph)

Populate a SharePoint list with Teams directory data using the Microsoft Graph PowerShell SDK.

Connect & set up

Run these once per session. All scopes are read-only unless the script makes changes.

Connect-MgGraph -Scopes Sites.ReadWrite.All, Sites.Manage.All -NoWelcome

Run it

The main script. Copy it, or download the .ps1 and run it from your console.

param(
[string] $SiteSearch = "Office 365 for IT Pros Communications"
)
$CSVFile = 'C:\temp\ListofTeams.csv'
If (!(Get-Item -Path $CSVFile)) {
Write-Host ("Can't load Teams directory data from {0}" -f $CSVFile)
Break
}
Write-Host "Connecting to the Graph..."
Connect-MgGraph -Scopes Sites.ReadWrite.All, Sites.Manage.All -NoWelcome
$ListName = "Teams Directory - Graph"
# Get target site
Write-Host "Fetching details of the target site and list..."
$Site = Get-MgSite -Search $SiteSearch
# Get List
$List = Get-MgSiteList -SiteId $Site.Id -Filter "displayName eq 'Teams Directory - Graph'"
If ($List) {
# Delete the list
Write-Host ("Removing previous version of list {0}" -f $List.DisplayName)
Remove-MgSiteList -SiteId $Site.Id -ListId $List.Id
}
# Define parameters for the new list
Write-Host "Defining the new list"
$Uri = ("https://graph.microsoft.com/v1.0/sites/{0}/Lists" -f $Site.Id)
$ListDetails = '{
"displayName": "Teams Directory - Graph",
"description": "Discover teams to join in Office 365 for IT Pros",
"columns": [
{
"name": "Deeplink",
"description": "Link to access the team",
"text": { }
},{
"name": "Description",
"description": "Purpose of the team",
"text": { }
},
{
"name": "Owner",
"description": "Team owner",
"text": { }
},
{
"name": "OwnerSMTP",
"description": "Primary SMTP address for owner",
"text": { }
},
{
"name": "Members",
"description": "Number of tenant menbers",
"number": { }
},
{
"name": "ExternalGuests",
"description": "Number of external guest menbers",
"number": { }
},
{
"name": "Access",
"description": "Public or Private access",
"text": { }
},
],
}'
Invoke-MgGraphRequest -Uri $Uri -Method Post -Body $ListDetails | Out-Null
# Rename the Notes column that's inherited from the Links template
$List = Get-MgSiteList -SiteId $Site.Id -Filter "displayName eq 'Teams Directory - Graph'"
$ColumnId = (Get-MgSiteListColumn -SiteId $Site.Id -ListId $List.Id | `
Where-Object {$_.Name -eq 'Title'}).Id
Update-MgSiteListColumn -ColumnDefinitionId $ColumnId -SiteId $Site.Id -ListId $List.Id `
-Description 'Name of the team' -DisplayName 'Team Name' -Name 'TeamName' | Out-Null
# Add records to the list
Write-Host ("Populating the {0} list with data extracted from Teams" -f $ListName)
[array]$TeamsData = Import-CSV -Path $CSVFile
[int]$i = 0
$Uri = ("https://graph.microsoft.com/v1.0/sites/{0}/lists/{1}/items" -f $Site.Id, $List.Id)
ForEach ($Team in $TeamsData) {
Write-Host ("Adding directory record for team {0} {1}/{2}" -f $Team.Team, $i, $TeamsData.Count)
$i++
# Note that the Title field inherited from the blank template retains its name even if
# it has a display name of 'Team Name'
$FieldsDataObject = [PSCustomObject] @{
Title = $Team.Team
Deeplink = $Team.Deeplink
Description = $Team.Description
Owner = $Team.Owner
OwnerSMTP = $Team.OwnerSMTP
Members = $Team.Members
ExternalGuests = $Team.ExternalGuests
Access = $Team.Access
}
$NewItem = [PSCustomObject] @{
fields = $FieldsDataObject
}
$NewItem = $NewItem | ConvertTo-Json
$Status = Invoke-MgGraphRequest -Method POST -Uri $Uri -Body $NewItem
If ($Status.Id) {
Write-Host ("Record added to list with id {0}" -f $Status.Id)
}
}
Write-Host "All done"

Parameters

ParameterDefaultNotes
-SiteSearchMicrosoft 365 for IT Pros CommunicationsSharePoint site search term used to locate the organizational contacts list.
Attribution