使用 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 应用程序
转到 Microsoft Entra 管理中心>Applications>应用注册。
在“应用注册”页上,选择“新建注册”。
选择此应用程序的名称,并使用默认配置注册应用。
请记住, 客户端 ID 和 租户 ID 显示在应用的 “概要 ”部分中。
向应用添加图形 API权限
在新应用程序的 “请求 API 权限 ”页中,添加 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。
该脚本将要求你输入上面创建的 机密值 。
执行脚本后,将创建新版本的报表,并添加站点 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