PowerShell自动化eDiscovery导出脚本报错排查请求
eDiscovery搜索导出脚本报错排查与修复
需求说明
通过PowerShell脚本完成以下流程:访问eDiscovery、为指定用户创建搜索任务、等待任务完成、将结果导出至Azure Blob存储,再从Blob下载至本地服务器。
原脚本
# Import required modules Import-Module AzureAD Import-Module Az Import-Module Microsoft.Online.SharePoint.PowerShell Import-Module ExchangeOnlineManagement Import-Module Microsoft.Exchange.Management.ExoPowershellModule # Variables $tenantAdmin = "<tenant admin email>" # Replace with your tenant admin email $tenantAdminPassword = ConvertTo-SecureString "<password>" -AsPlainText -Force # Replace with your tenant admin password $eDiscoveryCaseName = "name of case" # Replace with your eDiscovery case name $blobStorageAccount = "<blob storage account name>" # Replace with your blob storage account name $blobStorageAccessKey = "<blob storage access key>" # Replace with your blob storage access key $blobContainerName = "name of blob container" # Replace with your desired blob container name (without the URL) $localDownloadPath = "name of local server" # Replace with your desired local storage path # Create credentials object $credentials = New-Object System.Management.Automation.PSCredential ($tenantAdmin, $tenantAdminPassword) # Connect to AzureAD Connect-AzureAD -Credential $credentials # Connect to SharePoint Online Connect-SPOService -Url "https://<tenant>-admin.sharepoint.com/" -Credential $credentials # Connect to Exchange Online Connect-ExchangeOnline -Credential $credentials # Connect to Security & Compliance Center PowerShell using Modern Authentication Connect-IPPSSession -Credential $credentials # Create the eDiscovery case if it doesn't exist if (-not (Get-ComplianceCase -Identity $eDiscoveryCaseName -ErrorAction SilentlyContinue)) { New-ComplianceCase -Name $eDiscoveryCaseName -CaseType Core } # Get the eDiscovery case $eDiscoveryCase = Get-ComplianceCase -Identity $eDiscoveryCaseName if ($eDiscoveryCase -eq $null) { Write-Host "eDiscovery case not found" exit } # Start the eDiscovery search $searchName = $eDiscoveryCaseName + "Name of user" New-ComplianceSearch -Name $searchName -ExchangeLocation All -ContentMatchQuery "kind:email OR kind:document" -ComplianceCase $eDiscoveryCase Start-ComplianceSearch -Identity $searchName # Export the eDiscovery search to Azure Blob Storage $exportSettings = @{ ExportId = (New-Guid).Guid StorageAccountName = $blobStorageAccount StorageAccountKey = $blobStorageAccessKey ContainerName = $blobContainerName SearchName = $searchName } New-ComplianceSearchAction -SearchName $searchName -Export -AzureBlobStorageAccountUrl "https://<blob storage account name>.blob.core.windows.net" -AzureBlobStorageAccountKey $blobStorageAccessKey - AzureBlobStorageContainer $blobContainerName # Wait for the export to finish $exportStatus = Get-ComplianceSearchAction -Identity $searchName -ActionType Export while ($exportStatus.Status -eq "InProgress") { Start-Sleep -Seconds 60 $exportStatus = Get-ComplianceSearchAction -Identity $searchName - ActionType Export } # Download exported files from Azure Blob Storage to the specified local storage path if ($exportStatus.Status -eq "Completed") { $blobContext = New-AzureStorageContext -StorageAccountName $blobStorageAccount -StorageAccountKey $blobStorageAccessKey $blobs = Get-AzureStorageBlob -Container $blobContainerName -Context $blobContext foreach ($blob in $blobs) { $localFilePath = Join-Path -Path $localDownloadPath -ChildPath $blob.Name Get-AzureStorageBlobContent -Blob $blob.Name -Container $blobContainerName -Context $blobContext -Destination $localFilePath } else { Write-Host "Export failed" } # Get the compliance case $complianceCase = Get-ComplianceCase -Identity $eDiscoveryCaseName if ($complianceCase -eq $null) { Write-Host "Compliance case not found" exit } # Add the search to the compliance case $complianceCaseSearch = Get-ComplianceCaseSearch -CaseId $complianceCase.Id -SearchName $searchName Add-ComplianceCaseSearch -CaseId $complianceCase.Id -SearchId $complianceCaseSearch.Id
报错信息(翻译后)
- New-ComplianceSearch:找不到匹配的参数名'ComplianceCase'
- Start-ComplianceSearch:找不到已终止账户(隐私保护已移除用户名)
- New-ComplianceSearchAction:找不到匹配的参数名'AzureBlobStorageAccountUrl'
- Get-ComplianceSearchAction:找不到匹配的参数名'ActionType'
- 未识别Get-ComplianceCaseSearch、Add-ComplianceCaseSearch cmdlet
- Remove-PSSession:无法绑定参数'Session',因为该参数为null
问题排查与修复方案
1. New-ComplianceSearch参数错误
原因:New-ComplianceSearch无ComplianceCase参数,关联合规案例需使用CaseId参数,传入案例ID而非对象。
修复:
# 原代码 New-ComplianceSearch -Name $searchName -ExchangeLocation All -ContentMatchQuery "kind:email OR kind:document" -ComplianceCase $eDiscoveryCase # 修改后 New-ComplianceSearch -Name $searchName -ExchangeLocation All -ContentMatchQuery "kind:email OR kind:document" -CaseId $eDiscoveryCase.Id
2. Start-ComplianceSearch找不到已终止账户
原因:-ExchangeLocation All包含已删除/终止账户,导致搜索失败。若为指定用户创建搜索,需替换为目标用户UPN;若要排除终止账户,需筛选活跃用户。
修复:
指定单个用户搜索:
$targetUserUpn = "user@contoso.com" # 替换为目标用户UPN New-ComplianceSearch -Name $searchName -ExchangeLocation $targetUserUpn -ContentMatchQuery "kind:email OR kind:document" -CaseId $eDiscoveryCase.Id
仅搜索活跃用户:
$activeUsers = Get-AzureADUser -Filter "AccountEnabled eq true" | Select-Object -ExpandProperty UserPrincipalName New-ComplianceSearch -Name $searchName -ExchangeLocation $activeUsers -ContentMatchQuery "kind:email OR kind:document" -CaseId $eDiscoveryCase.Id
3. New-ComplianceSearchAction参数错误
原因:导出到Azure Blob的正确参数为-AzureStorageAccountName、-AzureStorageAccountKey、-AzureStorageContainerName,脚本中参数名称错误。
修复:
# 原代码 New-ComplianceSearchAction -SearchName $searchName -Export -AzureBlobStorageAccountUrl "https://<blob storage account name>.blob.core.windows.net" -AzureBlobStorageAccountKey $blobStorageAccessKey -AzureBlobStorageContainer $blobContainerName # 修改后 New-ComplianceSearchAction -SearchName $searchName -Export -AzureStorageAccountName $blobStorageAccount -AzureStorageAccountKey $blobStorageAccessKey -AzureStorageContainerName $blobContainerName
4. Get-ComplianceSearchAction参数错误
原因:Get-ComplianceSearchAction无ActionType参数,需通过Where-Object筛选导出动作。
修复:
# 原代码 $exportStatus = Get-ComplianceSearchAction -Identity $searchName -ActionType Export while ($exportStatus.Status -eq "InProgress") { Start-Sleep -Seconds 60 $exportStatus = Get-ComplianceSearchAction -Identity $searchName -ActionType Export } # 修改后 do { Start-Sleep -Seconds 60 $exportStatus = Get-ComplianceSearchAction -Identity $searchName | Where-Object { $_.Action -eq "Export" } } while ($exportStatus.Status -eq "InProgress")
5. 未识别Get-ComplianceCaseSearch、Add-ComplianceCaseSearch cmdlet
原因:这两个cmdlet已废弃,创建搜索时通过-CaseId参数关联案例即可,无需后续添加操作。
修复:删除脚本中以下冗余代码:
# Get the compliance case $complianceCase = Get-ComplianceCase -Identity $eDiscoveryCaseName if ($complianceCase -eq $null) { Write-Host "Compliance case not found" exit } # Add the search to the compliance case $complianceCaseSearch = Get-ComplianceCaseSearch -CaseId $complianceCase.Id -SearchName $searchName Add-ComplianceCaseSearch -CaseId $complianceCase.Id -SearchId $complianceCaseSearch.Id
6. Remove-PSSession参数为null
原因:未保存会话对象就尝试移除,或会话未成功创建。需在连接时保存会话,最后统一清理。
修复:
连接时保存会话,脚本末尾添加清理代码:
# 连接时保存会话 $ippsSession = Connect-IPPSSession -Credential $credentials $exoSession = Connect-ExchangeOnline -Credential $credentials -ShowBanner:$false # 脚本末尾添加清理 if ($ippsSession) { Remove-PSSession $ippsSession } if ($exoSession) { Remove-PSSession $exoSession }
完整修复后脚本
# Import required modules Import-Module AzureAD Import-Module Az.Storage Import-Module ExchangeOnlineManagement # Variables $tenantAdmin = "<tenant admin email>" $tenantAdminPassword = ConvertTo-SecureString "<password>" -AsPlainText -Force $eDiscoveryCaseName = "name of case" $targetUserUpn = "user@contoso.com" # 指定目标用户UPN $blobStorageAccount = "<blob storage account name>" $blobStorageAccessKey = "<blob storage access key>" $blobContainerName = "name of blob container" $localDownloadPath = "C:\LocalDownloadPath" # 修正为有效本地路径 # Create credentials object $credentials = New-Object System.Management.Automation.PSCredential ($tenantAdmin, $tenantAdminPassword) # Connect services Connect-AzureAD -Credential $credentials $exoSession = Connect-ExchangeOnline -Credential $credentials -ShowBanner:$false $ippsSession = Connect-IPPSSession -Credential $credentials # Create the eDiscovery case if it doesn't exist if (-not (Get-ComplianceCase -Identity $eDiscoveryCaseName -ErrorAction SilentlyContinue)) { New-ComplianceCase -Name $eDiscoveryCaseName -CaseType Core } # Get the eDiscovery case $eDiscoveryCase = Get-ComplianceCase -Identity $eDiscoveryCaseName if (-not $eDiscoveryCase) { Write-Host "eDiscovery case not found" exit } # Create and start eDiscovery search for specified user $searchName = "$eDiscoveryCaseName-$targetUserUpn" New-ComplianceSearch -Name $searchName -ExchangeLocation $targetUserUpn -ContentMatchQuery "kind:email OR kind:document" -CaseId $eDiscoveryCase.Id Start-ComplianceSearch -Identity $searchName # Wait for search to complete do { Start-Sleep -Seconds 60 $searchStatus = Get-ComplianceSearch -Identity $searchName Write-Host "Search status: $($searchStatus.Status)" } while ($searchStatus.Status -eq "InProgress") if ($searchStatus.Status -ne "Completed") { Write-Host "Search failed or was stopped" exit } # Export search results to Azure Blob Storage New-ComplianceSearchAction -SearchName $searchName -Export -AzureStorageAccountName $blobStorageAccount -AzureStorageAccountKey $blobStorageAccessKey -AzureStorageContainerName $blobContainerName # Wait for export to finish do { Start-Sleep -Seconds 60 $exportStatus = Get-ComplianceSearchAction -Identity $searchName | Where-Object { $_.Action -eq "Export" } Write-Host "Export status: $($exportStatus.Status)" } while ($exportStatus.Status -eq "InProgress") # Download exported files from Blob to local if ($exportStatus.Status -eq "Completed") { $blobContext = New-AzStorageContext -StorageAccountName $blobStorageAccount -StorageAccountKey $blobStorageAccessKey $blobs = Get-AzStorageBlob -Container $blobContainerName -Context $blobContext foreach ($blob in $blobs) { $localFilePath = Join-Path -Path $localDownloadPath -ChildPath $blob.Name Get-AzStorageBlobContent -Blob $blob.Name -Container $blobContainerName -Context $blobContext -Destination $localFilePath -Force Write-Host "Downloaded: $localFilePath" } } else { Write-Host "Export failed" } # Clean up sessions if ($ippsSession) { Remove-PSSession $ippsSession } if ($exoSession) { Remove-PSSession $exoSession }
内容的提问来源于stack exchange,提问作者Robert Harley
相关产品推荐
相关产品推荐

