SharePoint Onlineサイトのうち外部共有が有効かつ現在ゲストがいないサイトをPowerShellを使ってCSVに出力する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/357828/2458bb05-7af9-f343-e963-7cc9d4fc4f25.png)

このPowerShellスクリプトの目的は外部ユーザーと共有しているSharePointサイトの棚卸です。下記の投稿に載せているチームの棚卸と合わせて作成しました。

https://qiita.com/wataruf01/items/81fe866dd34ac0bb4414

#スクリプトの目的と出力内容
このスクリプトでは掲題の通り、「外部共有が有効」かつ「<font color="Red">現在ゲストがいないサイト</font>」を検知することを目的にしています。

このPowerShellスクリプトでは以下の３つの条件にすべて合致しているSharePointサイトをCSVに出力します。サイトテンプレートの種類等は要件によってソースコードの該当箇所を変更してください。

【条件】
1. コミュニケーションサイトである
 （サイトテンプレートが「SITEPAGEPUBLISHING#0」）
2. 外部共有が有効である
3. 指定したSharePointグループにメンバーがいない
 （グループ名が「○○閲覧者」もしくは「○○Visitors」）

CSVへの出力内容は「サイト名」「サイトURL」「サイトID」の3つです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/357828/ff22911e-283d-e4c3-439d-3c82772cfc8f.png)

#使い方
スクリプトを実行するために必要なモジュールをPCにインストールします。管理者権限で下記コマンドを実行してください。

```powershell:モジュールのインストールコマンド
Install-Module -Name Microsoft.Online.SharePoint.PowerShell
```

スクリプトは以下の通りです。

```powershell:ゲストユーザーを有効にしているサイトの棚卸
#-------------------------------------------------
#実行アカウント
#-------------------------------------------------
#$user     = "XXX@XXX.onmicrosoft.com"
#$password = "XXX" | ConvertTo-SecureString -AsPlainText -Force

$credential = New-Object System.Management.Automation.PSCredential($user,$password)

#-------------------------------------------------
#変数の設定
#-------------------------------------------------
#出力するCSVのパス
$now = (Get-Date).ToString("yyyyMMdd_HHmm")
$CSVFilePath = ".\InventorySharePointSite_" + $now + ".csv"

#SharePoint管理センターのURL
$SharePointAdminCenterUrl = "https://m365xxxxxxx-admin.sharepoint.com/"

#-------------------------------------------------
#主処理
#-------------------------------------------------
#SharePoint Onlineに接続する
Connect-SPOService -Url $SharePointAdminCenterUrl -Credential $credential

#テナントを取得する
$ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SharePointAdminCenterUrl)
$ctx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($user,$password)
$tenant = New-Object Microsoft.Online.SharePoint.TenantAdministration.Tenant($ctx) 

#SharePointサイトをすべて取得する
$sites = Get-SPOSite -Limit All

#条件に合致するサイトをCSVに出力する
foreach($site in $sites)
{
    #コミュニケーションサイトでなければスキップする
    if($site.Template -ne "SITEPAGEPUBLISHING#0")
    {
        continue
    }

    #外部共有がオフであればスキップする
    if($site.SharingCapability -eq "Disable")
    {
        continue
    }

    #指定したSharePointグループにユーザーがいればスキップする
    $groups = Get-SPOSiteGroup -Site $site.Url
    $group  = $groups | where { $_.Title -Like "*閲覧者" -or $_.Title -Like "*Visitors" }    

    if([string]::IsNullOrEmpty($group) -eq $true)
    {
        continue
    }
    if($group.Users.Count -ne 0)
    {
        continue
    }

    #サイトIDを取得
    $siteObject = $tenant.GetSiteByUrl($site.Url)
    $ctx.Load($siteObject)  
    $ctx.ExecuteQuery()  
    $siteID = $siteObject.Id | select -ExpandProperty Guid

    $obj = New-Object PSObject
    $obj | Add-Member -MemberType NoteProperty -Name Title  -Value $site.Title
    $obj | Add-Member -MemberType NoteProperty -Name Url    -Value $site.Url
    $obj | Add-Member -MemberType NoteProperty -Name SiteID -Value $siteID

    $obj | Export-Csv -Path $CSVFilePath -Encoding UTF8 -NoTypeInformation -Append -force
}
```

GitHubにもアップロードしました。

https://github.com/wataruf01/Microsoft365/blob/main/PowerShell/InventorySharePointSitesWhichExternalSharingEnabledAndNoGuest/InventorySharePointSite.ps1

以上です。