I have this script which parses all shares on a file server to gather information on share size, ACLs, and count of files and folders. The script works great on smaller file servers but on hosts with large shares it consumes all RAM and crashes the host, I can't seem to figure out how to optimize the script during the Get-ChildItem portion to not consume all RAM.
I found a few articles which mentioned to use a foreach loop and pipe out what I need. I am a Powershell beginner, I can't figure out how to get it to work like that. What can I try next?
$ScopeName = Read-Host "Enter scope name to gather data on"
$SavePath = Read-Host "Path to save results and log to"
$SaveCSVPath = "$SavePath\ShareData.csv"
$TranscriptLog = "$SavePath\Transcript.log"
Write-Host
Start-Transcript -Path $TranscriptLog
$StartTime = Get-Date
$Start = $StartTime | Select-Object -ExpandProperty DateTime
$Exclusions = {$_.Description -ne "Remote Admin" -and $_.Description -ne "Default Share" -and $_.Description -ne "Remote IPC" }
$FileShares = Get-SmbShare -ScopeName $ScopeName | Where-Object $Exclusions
$Count = $FileShares.Count
Write-Host
Write-Host "Gathering data for $Count shares" -ForegroundColor Green
Write-Host
Write-Host "Results will be saved to $SaveCSVPath" -ForegroundColor Green
Write-Host
ForEach ($FileShare in $FileShares)
{
$ShareName = $FileShare.Name
$Path = $Fileshare.Path
Write-Host "Working on: $ShareName - $Path" -ForegroundColor Yellow
$GetObjectInfo = Get-Childitem -Path $Path -Recurse -Force -ErrorAction SilentlyContinue
$ObjSize = $GetObjectInfo | Measure-Object -Property Length -Sum -ErrorAction SilentlyContinue
$ObjectSizeMB = "{0:N2}" -f ($ObjSize.Sum / 1MB)
$ObjectSizeGB = "{0:N2}" -f ($ObjSize.Sum / 1GB)
$ObjectSizeTB = "{0:N2}" -f ($ObjSize.Sum / 1TB)
$NumFiles = ($GetObjectInfo | Where-Object {-not $_.PSIsContainer}).Count
$NumFolders = ($GetObjectInfo | Where-Object {$_.PSIsContainer}).Count
$ACL = Get-Acl -Path $Path
$LastAccessTime = Get-ItemProperty $Path | Select-Object -ExpandProperty LastAccessTime
$LastWriteTime = Get-ItemProperty $Path | Select-Object -ExpandProperty LastWriteTime
$Table = [PSCustomObject]@{
'ScopeName' = $FileShare.ScopeName
'Sharename' = $ShareName
'SharePath' = $Path
'Owner' = $ACL.Owner
'Permissions' = $ACL.AccessToString
'LastAccess' = $LastAccessTime
'LastWrite' = $LastWriteTime
'Size (MB)' = $ObjectSizeMB
'Size (GB)' = $ObjectSizeGB
'Size (TB)' = $ObjectSizeTB
'Total File Count' = $NumFiles
'Total Folder Count' = $NumFolders
'Total Item Count' = $GetObjectInfo.Count
}
$Table | Export-CSV -Path $SaveCSVPath -Append -NoTypeInformation
}
$EndTime = Get-Date
$End = $EndTime | Select-Object -ExpandProperty DateTime
Write-Host
Write-Host "Script start time: $Start" -ForegroundColor Green
Write-Host "Script end time: $End" -ForegroundColor Green
Write-Host
$ElapsedTime = $(($EndTime-$StartTime))
Write-Host "Elapsed time: $($ElapsedTime.Days) Days $($ElapsedTime.Hours) Hours $($ElapsedTime.Minutes) Minutes $($ElapsedTime.Seconds) Seconds $($ElapsedTime.MilliSeconds) Milliseconds" -ForegroundColor Cyan
Write-Host
Write-Host "Results saved to $SaveCSVPath" -ForegroundColor Green
Write-Host
Write-Host "Transcript saved to $TranscriptLog" -ForegroundColor Green
Write-Host
Stop-Transcript