PowerShellを使ってテナント内のチームを一覧取得してCSVに出力する（＋ チームに紐づくSPOサイトの容量も取得）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/357828/3937d288-b3ba-d373-11d1-a884a1ee2435.png)

#最初に
この投稿は Office 365 Advent Calendar 2021 に参加して記載したものです。

https://adventar.org/calendars/6679

#主旨
掲題の通り、テナント内のチームを一覧取得します。チームを一覧取得するのはコマンドの実行で終わってしまうので、その応用として各チームに紐づくSharePointサイトのURLと容量を合わせてCSVに出力したいと思います。

#きっかけ
今日TwitterでHiroさんのこんな投稿をTLで見かけたためです。テナント内のチームを一覧取得は色んな場面で需要がありそうです。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">パブリックなチームの一覧を取得するにはどうするのがいいだろう。。なおチーム数は1万以上テナントにあるものとする</p>&mdash; Hiro (@mofumofu_dance) <a href="https://twitter.com/mofumofu_dance/status/1466687387493597188?ref_src=twsrc%5Etfw">December 3, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

#パターン1（チームの一覧を取得する）
テナント内のチームの一覧を取得します。SharePointサイトの情報は取得しない版のPowerShellです。

##出力イメージ
CSVへの出力イメージです。
DisplayNameはチームの表示名です。Visibilityが「パブリック」もしくは「プライベート」を表します。Archivedはアーカイブされたチームであるかどうかを表します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/357828/2fd43ce2-426f-1f38-1611-ed3cb3ecbb29.png)

##前提条件
チームの一覧取得のみの場合に必要な条件は以下の通りです。
・PowerShellの実行ユーザーが以下の役割を持っていること
　・Teams管理者
・以下のモジュールがPC端末にインストールされていること
　・Microsoft Teams モジュール

チームの一覧取得は「Microsoft Teams モジュール」にある Get-Team を使います。このコマンドは一般ユーザーが実行すると自分が所属するチームを取得しますが、Teams管理者が実行した場合は、テナント内のすべてのチームを取得します。

##ソースコード
```powershell:チームを一覧取得
#-------------------------------------------------
#認証情報
#-------------------------------------------------
$user = "xxx"
$pass = "xxx" | ConvertTo-SecureString -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential($user,$pass) 

#-------------------------------------------------
#前準備：チームをすべて取得
#-------------------------------------------------
Connect-MicrosoftTeams -Credential $credential

$allTeams = Get-Team

#-------------------------------------------------
#主処理：チームの情報をCSVに出力する
#-------------------------------------------------
$outputFile = ".\output.csv"

foreach($team in $allTeams)
{
    #チームの情報をCSVに出力
    $obj = New-Object PSObject
    $obj | Add-Member -MemberType NoteProperty -Name DisplayName -Value $team.DisplayName
    $obj | Add-Member -MemberType NoteProperty -Name Visibility  -Value $team.Visibility
    $obj | Add-Member -MemberType NoteProperty -Name Archived    -Value $team.Archived

    $obj | Export-Csv -Path $outputFile -Encoding UTF8 -NoTypeInformation -Append
}
```
#パターン2（チームの一覧＋SPOサイトの容量を取得する）
パターン1で取得するCSVにSharePointサイトの容量を追加します。

##出力イメージ
CSVへの出力イメージです。
パターン1の内容にSharePointサイトのURLと容量の列を追加します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/357828/0bad1dd5-e6ab-03d7-19f0-b779ff01509b.png)

##前提条件
チームの一覧取得のみの場合に必要な条件は以下の通りです。
・PowerShellの実行ユーザーが以下の役割を持っていること
　・Teams管理者
　・SharePoint管理者
　・Exchange Online管理者
・以下のモジュールがPC端末にインストールされていること
　・Microsoft Teams モジュール
　・PnP.PoweShell モジュール
　・Exchange Online 管理モジュール V2

Exchange Online管理者の役割が必要なのは、SharePointサイトのURLを取得するために、Microsoft365グループを経由しているためです。

##ソースコード
```powershell:チームを一覧取得（＋SPOサイトの容量も取得）
#-------------------------------------------------
#認証情報
#-------------------------------------------------
$user = "xxx"
$pass = "xxx" | ConvertTo-SecureString -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential($user,$pass) 

#-------------------------------------------------
#前準備：チームをすべて取得
#-------------------------------------------------
Connect-MicrosoftTeams -Credential $credential

$allTeams = Get-Team

#-------------------------------------------------
#前準備：Microsoft365グループをすべて取得
#-------------------------------------------------
Connect-ExchangeOnline -Credential $credential

$allGroups = Get-UnifiedGroup -ResultSize Unlimited

#-------------------------------------------------
#前準備：SharePointサイトをすべて取得
#-------------------------------------------------
$SPOAdminCenter = "https://m365x794640-admin.sharepoint.com/"
Connect-PnPOnline -Url $SPOAdminCenter -Credential $credential

$allSite = Get-PnPTenantSite | select Url,StorageUsageCurrent

#-------------------------------------------------
#主処理：チームの情報をCSVに出力する
#-------------------------------------------------
$outputFile = ".\output.csv"

foreach($team in $allTeams)
{
    #SharePointサイトの容量を取得
    $group = $allGroups | where ExternalDirectoryObjectId -eq $team.GroupId
    $site  = $allSite   | where Url -EQ $group.SharePointSiteUrl
    $sharePointSiteSizeMB = $site.StorageUsageCurrent

    #チームの情報をCSVに出力
    $obj = New-Object PSObject
    $obj | Add-Member -MemberType NoteProperty -Name DisplayName -Value $team.DisplayName
    $obj | Add-Member -MemberType NoteProperty -Name Visibility  -Value $team.Visibility
    $obj | Add-Member -MemberType NoteProperty -Name Archived    -Value $team.Archived
    $obj | Add-Member -MemberType NoteProperty -Name SiteURL     -Value $group.SharePointSiteUrl
    $obj | Add-Member -MemberType NoteProperty -Name SiteSizeMB  -Value $sharePointSiteSizeMB

    $obj | Export-Csv -Path $outputFile -Encoding UTF8 -NoTypeInformation -Append
}
```
#最後に
これらのスクリプトでは情報を取得するときにはそのシステムの管理者権限を持つことを前提としています。（例：チームの一覧取得ならTeams管理者）

ですが、実際に運用で使う場合は、「一覧取得するためだけに管理者権限を会社に申請するのはちょっと。。」となることがあるかと思います。
なので、「一覧取得で最低限必要なのはこの権限」というのが分かると助かる場面は多そうですね。