############################## # # (C) Ondrej Sevecek, www.sevecek.com - 2014 # # This is a SharePoint 2010 and SharePoint 2013 and newer warm up PowerShell script # which automatically enumerates all web applications, for each in turns, all its site collections # with their web sites and inside that all files in any type of folder or subfolder. # The Get-AllSPFolders function does not use recursion, although it would be a logical step # because the subfolders are recursively stored in their folders and document libraries. # # After enumeration, the script tries to download/touch all files with certain file extensions # such as .ASPX files, HTML files and other infrastructure files. The script does not touch # data files such as .DOCX or .XLSX etc. # # The script also generates some statistics about the numbers of files it found and the times # it took it to enumerate and also download the files # function DBG ([string] $msg) { Write-Host ("{0:s} $msg`r`n" -f (Get-Date)) } function Get-AllSPFolders([object] $folder) { [System.Collections.ArrayList] $outFolders = @($folder) if (($folder -ne $null) -and (($folder -is [Microsoft.SharePoint.SPFolder]) -or ($folder -is [Microsoft.SharePoint.SPWeb]))) { if ($folder -is [Microsoft.SharePoint.SPWeb]) { DBG ('Get subfolders for web site: {0}' -f $folder.Url) $outFolders.AddRange($folder.Folders) } $i = 0; while ($i -lt $outFolders.Count) { DBG ('Get subfolders for folder: {0} | # = {1}' -f $outFolders[$i].Url, $outFolders[$i].SubFolders.Count) if ($outFolders[$i].SubFolders.Count -gt 0) { $outFolders.AddRange($outFolders[$i].SubFolders) } $i ++ } } DBG ('Folders found: {0}' -f $outFolders.Count) return ,$outFolders } function Get-AllSPFiles ( [bool] $includeCA, [string[]] $includedExts = @( '.aspx', '.html', '.htm', '.master', '.preview', '.css', '.bmp', '.jpg', '.jpeg', '.png', '.gif', '.js', '.xml', '.xsl', '.xaml', '.spcolor', '.spfont', '.webpart', '.dwp' '.txt' ) ) { [System.Collections.ArrayList] $urls = @() $results = New-Object PSCustomObject Add-Member -Input $results -MemberType NoteProperty -Name enumStartTime -Value (Get-Date) Add-Member -Input $results -MemberType NoteProperty -Name statsPerSiteCol -Value (New-Object System.Collections.ArrayList) $webApps = Get-SPWebApplication -IncludeCentralAdministration:$includeCA $allFiles = 0 foreach ($oneApp in $webApps) { DBG ('Web application: {0}' -f $oneApp.Url) $sites = Get-SPSite -WebApplication $oneApp foreach ($oneSite in $sites) { DBG ('Site collection: {0}' -f $oneSite.Url) $webs = $oneSite.Allwebs $siteColAllFiles = 0 $siteColOutFiles = 0 foreach ($oneWeb in $webs) { DBG ('Web site: {0}' -f $oneWeb.Url) $folders = Get-AllSPFolders $oneWeb foreach ($oneFolder in $folders) { foreach ($oneFile in $oneFolder.Files) { $allFiles ++ $siteColAllFiles ++ if ([System.IO.Path]::GetExtension($oneFile.Url) -in $includedExts) { if ($oneFile.Url -match '\Ahttp(?:s|)://.+') { $oneFileUrl = $oneFile.Url } else { $oneFileUrl = '{0}/{1}' -f $oneWeb.Url, $oneFile.Url } DBG ('File: {0}' -f $oneFileUrl) [void] $urls.Add($oneFileUrl) $siteColOutFiles ++ } } } } $siteColStat = New-Object PSCustomObject Add-Member -Input $siteColStat -MemberType NoteProperty -Name webApp -Value $oneApp.Url Add-Member -Input $siteColStat -MemberType NoteProperty -Name siteCol -Value $oneSite.Url Add-Member -Input $siteColStat -MemberType NoteProperty -Name allFiles -Value $siteColAllFiles Add-Member -Input $siteColStat -MemberType NoteProperty -Name outFiles -Value $siteColOutFiles [void] $results.statsPerSiteCol.Add($siteColStat) } } Add-Member -Input $results -MemberType NoteProperty -Name enumEndTime -Value (Get-Date) Add-Member -Input $results -MemberType NoteProperty -Name enumMinutes -Value ([Math]::Round(($results.enumEndTime - $results.enumStartTime).TotalMinutes, 1)) Add-Member -Input $results -MemberType NoteProperty -Name allFiles -Value $allFiles Add-Member -Input $results -MemberType NoteProperty -Name outFiles -Value $urls.Count Add-Member -Input $results -MemberType NoteProperty -Name urls -Value $urls return $results } Add-PSSnapin Microsoft.SharePoint.PowerShell $stats = Get-AllSPFiles $true $webClient = New-Object System.Net.WebClient $webClient.Headers.Add('User-Agent', 'Sevecek-SharePoint-Keep-Alive') $webClient.Credentials = [System.Net.CredentialCache]::DefaultCredentials [DateTime] $startTime = Get-Date foreach ($oneUrl in $stats.urls) { [string] $httpOutput = '' $httpOutput = $webClient.DownloadString($oneUrl) if ($httpOutput.Length -lt 1) { DBG ('Empty result: {0}' -f $oneUrl) } } [DateTime] $endTime = Get-Date DBG ('Enum time taken: {0}' -f $stats.enumMinutes) DBG ('Files: all = {0} | touched = {1}' -f $stats.allFiles, $stats.outFiles) DBG ('Download time taken: {0:N1}' -f ($endTime - $startTime).TotalMinutes) DBG ('Site collection stats: {0}' -f ($stats.statsPerSiteCol | ft -Auto | Out-String))