使用 PowerShell 解析报表中的站点 URL

本文介绍如何使用 PowerShell 在报表中显示网站 URL。

运作方式

图形 API提供了一个 API,可用于列出组织内的所有站点。 若要使用此 API,需要具有具有 Sites.Read.All 权限的应用程序。

该脚本调用此 API 终结点以获取站点 ID 和站点 URL 之间的映射,然后将站点 URL 添加到导出的 CSV 报表中。

为什么不使用委托的权限?

  • /sites/getAllSites API 仅接受应用程序权限。

  • /sites?search=* API 接受委托的权限,但它不会返回所有网站,即使使用管理员帐户也是如此。

步骤

若要使用 PowerShell 显示网站 URL,请执行以下步骤。

创建 Entra ID 应用程序

  1. 转到 Microsoft Entra 管理中心>Applications>应用注册

  2. 在“应用注册”页上,选择“新建注册”。

  3. 选择此应用程序的名称,并使用默认配置注册应用。

请记住, 客户端 ID租户 ID 显示在应用的 “概要 ”部分中。

显示客户端字段和字段 ID 突出显示的屏幕截图。

向应用添加图形 API权限

在新应用程序的 “请求 API 权限 ”页中,添加 Sites.Read.All 权限。

显示已选择“Sites.Read.All”权限的屏幕截图。

然后,授予管理员同意。

显示已选择“授予管理员同意”设置的屏幕截图。

创建客户端密码

在新应用程序的 “证书 & 机密 ”部分中,创建新的客户端密码。 然后,将 机密的值 存储在安全可靠的位置。

显示创建新客户端密码的步骤的屏幕截图。

下载 Microsoft 365 管理中心 中的报表

在两个报表页上下载站点详细信息报表,并将 CSV 报表文件放在本地文件夹下。

在下载报表之前,请确保关闭用户详细信息的隐私设置。 有关详细信息,请参阅Microsoft 365 管理中心活动报告

对于 SharePoint 网站使用情况,请转到Microsoft 365 管理中心中的 SharePoint 网站使用情况页。

对于 OneDrive 网站使用情况,请转到Microsoft 365 管理中心中的 OneDrive 网站使用情况页。

使用站点 URL 更新报表

若要使用站点 URL 更新报表,请执行 PowerShell 脚本。

.\Update-Report.ps1 -**tenantId** {tenant id above} -**clientId** {client id above} -**reportPaths** @("file path for report \#1", "file path for report \#2")

若要查看 PowerShell 脚本的完整 Update-Report,请参阅 Update-Report PowerShell

该脚本将要求你输入上面创建的 机密值

显示客户端密码的 PowerShell 命令的屏幕截图。

执行脚本后,将创建新版本的报表,并添加站点 URL。

显示使用情况报表中包含的网站 URL 列表的屏幕截图。

清理环境

若要清理环境,请返回到应用程序的 “证书 & 机密 ”页,并删除之前创建的机密。

提示

使用 SSD (固态硬盘) 来提高 IO 性能。 在具有足够可用/未使用内存的计算机上执行脚本。 对于 1500 万个站点,缓存大约需要 2GB。

Update-Report PowerShell 脚本

下面是 Update-Report 的 PowerShell 脚本。

 param(
 [Parameter(Mandatory=$true)]
 [string]$tenantId,
 [Parameter(Mandatory=$true)]
 [string]$clientId,
 [Parameter(Mandatory=$false)]
 [string[]]$reportPaths
)

function Get-AccessToken {
 param(
     [Parameter(Mandatory=$true)]
     [string]$tenantId,
     [Parameter(Mandatory=$true)]
     [string]$clientId,
     [Parameter(Mandatory=$true)]
     [System.Security.SecureString]$clientSecret,
     [Parameter(Mandatory=$false)]
     [string]$scope = "https://graph.microsoft.com/.default"
 )

 $tokenEndpoint = "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token"
 $tokenRequest = @{
     client_id     = $clientId
     scope         = $scope
     client_secret = ConvertFrom-SecureString $clientSecret -AsPlainText
     grant_type    = "client_credentials"
 }

 $tokenResponse = Invoke-RestMethod -Uri $tokenEndpoint -Method Post -Body $tokenRequest
 return $tokenResponse.access_token
}

准备缓存和客户端密码

if ($reportPaths.Count -eq 0) {
  Write-Host "Please provide at least one report path" -ForegroundColor Red
  exit
}
$cache = New-Object 'System.Collections.Generic.Dictionary[[String],[String]]'
$clientSecret = Read-Host "Please enter client secret" -AsSecureString

从图形 API提取网站信息

Write-Host
Write-Host "Getting information for all the sites..." -ForegroundColor Cyan

$uri = "https://graph.microsoft.com/v1.0/sites/getAllSites?`$select=sharepointIds&`$top=10000"
while ($uri -ne $null) {

  Write-Host $uri

  $isSuccess = $false
  while (-not $isSuccess) {
      try {
          $accessToken = Get-AccessToken -tenantId $tenantId -clientId $clientId -clientSecret $clientSecret
          $restParams = @{Headers=@{Authorization="Bearer $accessToken"}}
      }
      catch {
          Write-Host "Retrying...  $($_.Exception.Message)" -ForegroundColor Yellow
          continue
      }
      try {
          $sites = Invoke-RestMethod $uri @restParams
          $isSuccess = $true
      }
      catch {
          if ($_.Exception.Response -and $_.Exception.Response.Headers['Retry-After']) {
              $retryAfter = [int]$_.Exception.Response.Headers['Retry-After']
              Write-Output "Waiting for $retryAfter seconds before retrying..." -ForegroundColor Yellow
              Start-Sleep -Seconds $retryAfter
          }
          Write-Host "Retrying...  $($_.Exception.Message)" -ForegroundColor Yellow
          continue
      }
  }

  $sites.value | ForEach-Object {
      $cache[$_.sharepointIds.siteId] = $_.sharepointIds.siteUrl
  }

  $uri = $sites."@odata.nextLink"

  Write-Host "Total sites received: $($cache.Count)"
}

使用缓存的站点信息更新报表

foreach ($reportPath in $reportPaths) {
  Write-Host
  Write-Host "Updating report $($reportPath) ..." -ForegroundColor Cyan

  $outputPath = "$($reportPath)_$([Math]::Floor((Get-Date -UFormat %s))).csv"
  $writer = [System.IO.StreamWriter]::new($outputPath)
  $reader = [System.IO.StreamReader]::new($reportPath)
  $rowCount = 0

  while ($null -ne ($line = $reader.ReadLine())) {
      $rowCount++

      $columns = $line.Split(",")
      $siteId = $columns[1]

      $_guid = New-Object System.Guid
      if ([System.Guid]::TryParse($siteId, [ref]$_guid)) {
          $siteUrl = $cache[$siteId]
          $columns[2] = $siteUrl
          $line = $columns -join ","
      }
      
      $writer.WriteLine($line)

      if ($rowCount%1000 -eq 0) {
          Write-Host "Processed $($rowCount) rows"
      }
  }
  $writer.Close()
  $reader.Close()

  Write-Host "Processed $($rowCount) rows"
  Write-Host "Report updated: $($outputPath)" -ForegroundColor Cyan
}

完成

Write-Host
Read-Host "Press any key to exit..."

适用于小规模方案的其他选项

对于规模较小的方案,具有适当访问权限的管理员可以使用 SharePoint REST API 或 Microsoft 图形 API检索有关受影响报表中引用的网站 ID 的信息。 SharePoint REST API 可用于检索有关特定网站 ID 的信息。

例如,以下 SharePoint REST API 请求检索站点 ID 为 15d43f38-ce4e-4f6b-bac6-766ece1fbcb4 的 Contoso 网站的信息:

https://contoso.sharepoint.com/_api/v2.1/sites/contoso.sharepoint.com,15d43f38-ce4e-4f6b-bac6-766ece1fbcb4

Microsoft 图形 API可用于列出 SharePoint 网站或检索有关特定网站 ID 的信息。 有关详细信息,请参阅 站点资源类型

例如:

  • https://graph.microsoft.com/v1.0/sites?search=*&$select=sharepointIds
  • https://graph.microsoft.com/v1.0/sites/{siteId}

Microsoft 图形 API还可用于检索有关给定用户的OneDrive for Business站点的信息。 有关详细信息,请参阅 驱动器资源类型

例如:

  • https://graph.microsoft.com/v1.0/users/{userId}/drives?$select=sharepointIds