<# .SYNOPSIS SharePoint Production Toolkit - Script 18 - Content Database Inventory Report .DES confirmation prompt..DESCRIPTION #> [CmdletBinding()] param( [Parameter(Mandatory = $true)] [string]$WebAppUrl, [Parameter(Mandatory = $true)] [string]$OutputCsv, [switch]$NoPrompt ) Set-StrictMode -Version Latest $ErrorActionPreference = "Stop" Write-Host "" Write-Host "SCRIPT 18 - CONTENT DATABASE INVENTORY" -ForegroundColor Cyan Write-Host "READ-ONLY. NO CHANGES ARE MADE." -ForegroundColor Green Write-Host "" # ------------------------------------------------------------ # Load SharePoint snap-in # ------------------------------------------------------------ try { if (-not (Get-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue)) { Add-PSSnapin Microsoft.SharePoint.PowerShell } } catch { throw "Run in SharePoint Management Shell. Error: $($_.Exception.Message)" } # ------------------------------------------------------------ # Output setup # ------------------------------------------------------------ $outDir = Split-Path $OutputCsv -Parent if ([string]::IsNullOrWhiteSpace($outDir)) { throw "OutputCsv must be full path (example: C:\Temp\DBInventory.csv)" } if (-not (Test-Path $outDir)) { New-Item -Path $outDir -ItemType Directory -Force | Out-Null } $timestamp = (Get-Date).ToString("yyyyMMdd_HHmmss") $baseName = [System.IO.Path]::GetFileNameWithoutExtension($OutputCsv) $summaryPath = Join-Path $outDir ("{0}_{1}_Summary_ByRisk.csv" -f $baseName, $timestamp) $logPath = Join-Path $outDir ("{0}_{1}_RunLog.txt" -f $baseName, $timestamp) $errorPath = Join-Path $outDir ("{0}_{1}_Errors.csv" -f $baseName, $timestamp) # ------------------------------------------------------------ # Logging + error helpers # ------------------------------------------------------------ $errors = New-Object System.Collections.Generic.List[object] $log = New-Object System.Collections.Generic.List[string] function Log { param($msg) $line = "[{0}] {1}" -f (Get-Date -Format "yyyy-MM-dd HH:mm:ss"), $msg $log.Add($line) | Out-Null Write-Host $line } function Add-Error { param($scope, $msg) $errors.Add([pscustomobject]@{ Timestamp = Get-Date Scope = $scope Message = $msg }) | Out-Null } if (-not $NoPrompt) { Write-Host "This script scans content databases and writes reports only." -ForegroundColor Yellow if ((Read-Host "Type YES to continue") -ne "YES") { return } } # ------------------------------------------------------------ # Risk Classification # ------------------------------------------------------------ function Get-RiskLevel { param($SizeGB, $SiteCount) if ($SizeGB -gt 500 -or $SiteCount -gt 5000) { return "High" } if ($SizeGB -gt 200 -or $SiteCount -gt 2000) { return "Medium" } return "Low" } function Get-Score { param($risk) switch ($risk) { "High" { return 30 } "Medium" { return 60 } "Low" { return 90 } } } function Get-Recommendation { param($risk) switch ($risk) { "High" { return "Split database, reduce size before migration, validate attach strategy." } "Medium" { return "Review sizing and plan migration batches carefully." } "Low" { return "Suitable for standard migration wave." } } } # ------------------------------------------------------------ # Main execution # ------------------------------------------------------------ $results = New-Object System.Collections.Generic.List[object] try { $contentDBs = Get-SPContentDatabase -WebApplication $WebAppUrl Log ("Found {0} content databases." -f $contentDBs.Count) } catch { Add-Error $WebAppUrl $_.Exception.Message throw } foreach ($db in $contentDBs) { try { Log ("Analyzing DB: {0}" -f $db.Name) $sizeGB = 0 try { if ($db.disksizerequired) { $sizeGB = [Math]::Round($db.disksizerequired / 1GB, 2) } } catch {} $siteCount = 0 try { $siteCount = $db.CurrentSiteCount } catch {} $risk = Get-RiskLevel -SizeGB $sizeGB -SiteCount $siteCount $results.Add([pscustomobject]@{ DatabaseName = $db.Name WebApplication = $WebAppUrl DatabaseServer = $db.Server SizeGB = $sizeGB CurrentSiteCount = $siteCount WarningSiteCount = $db.WarningSiteCount MaximumSiteCount = $db.MaximumSiteCount Status = $db.Status RiskLevel = $risk Score = Get-Score $risk Category = "ContentDatabaseInventory" ActionRecommendation= Get-Recommendation $risk }) | Out-Null } catch { Add-Error $db.Name $_.Exception.Message } } # ------------------------------------------------------------ # Export Results # ------------------------------------------------------------ $results | Export-Csv -Path $OutputCsv -NoTypeInformation -Encoding UTF8 $results | Group-Object RiskLevel | ForEach-Object { [pscustomobject]@{ RiskLevel = $_.Name Count = $_.Count } } | Export-Csv -Path $summaryPath -NoTypeInformation -Encoding UTF8 $log | Set-Content $logPath if ($errors.Count -gt 0) { $errors | Export-Csv -Path $errorPath -NoTypeInformation -Encoding UTF8 Write-Host "ERROR REPORT: $errorPath" -ForegroundColor Yellow } Write-Host "" Write-Host "DETAIL REPORT: $OutputCsv" -ForegroundColor Green Write-Host "SUMMARY REPORT: $summaryPath" -ForegroundColor Green Write-Host "RUN LOG: $logPath" -ForegroundColor Green Write-Host "Complete." -ForegroundColor Green READ-ONLY. Enumerates SharePoint content databases and exports an inventory report. Used for: - Migration planning - Capacity planning - Database attach readiness validation .PARAMETER WebAppUrl Target SharePoint Web Application URL. .PARAMETER OutputCsv Full path to output CSV report. .PARAMETER NoPrompt