Advertisement
Guest User

Untitled

a guest
Jan 16th, 2019
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. function Get-FolderSize {
  2.     [CmdletBinding()]
  3.     param(
  4.         [Parameter(Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] [string[]] $Path,
  5.         [int] $Precision = 4,
  6.         [switch] $RoboOnly)
  7.     begin {
  8.         $FSO = New-Object -ComObject Scripting.FileSystemObject -ErrorAction Stop
  9.         function Get-RoboFolderSizeInternal {
  10.             [CmdletBinding()]
  11.             param(
  12.                 # Paths to report size, file count, dir count, etc. for.
  13.                 [string[]] $Path,
  14.                 [int] $Precision = 4)
  15.             begin {
  16.                 if (-not (Get-Command -Name robocopy -ErrorAction SilentlyContinue)) {
  17.                     Write-Warning -Message "Fallback to robocopy failed because robocopy.exe could not be found. Path '$p'. $([datetime]::Now)."
  18.                     return
  19.                 }
  20.             }
  21.             process {
  22.                 foreach ($p in $Path) {
  23.                     Write-Verbose -Message "Processing path '$p' with Get-RoboFolderSizeInternal. $([datetime]::Now)."
  24.                     $RoboCopyArgs = @("/L","/S","/NJH","/BYTES","/FP","/NC","/NDL","/TS","/XJ","/R:0","/W:0")
  25.                     [datetime] $StartedTime = [datetime]::Now
  26.                     [string] $Summary = robocopy $p NULL $RoboCopyArgs | Select-Object -Last 8
  27.                     [datetime] $EndedTime = [datetime]::Now
  28.                     [regex] $HeaderRegex = '\s+Total\s*Copied\s+Skipped\s+Mismatch\s+FAILED\s+Extras'
  29.                     [regex] $DirLineRegex = 'Dirs\s*:\s*(?<DirCount>\d+)(?:\s*\d+){3}\s*(?<DirFailed>\d+)\s*\d+'
  30.                     [regex] $FileLineRegex = 'Files\s*:\s*(?<FileCount>\d+)(?:\s*\d+){3}\s*(?<FileFailed>\d+)\s*\d+'
  31.                     [regex] $BytesLineRegex = 'Bytes\s*:\s*(?<ByteCount>\d+)(?:\s*\d+){3}\s*(?<BytesFailed>\d+)\s*\d+'
  32.                     [regex] $TimeLineRegex = 'Times\s*:\s*(?<TimeElapsed>\d+).*'
  33.                     [regex] $EndedLineRegex = 'Ended\s*:\s*(?<EndedTime>.+)'
  34.                     if ($Summary -match "$HeaderRegex\s+$DirLineRegex\s+$FileLineRegex\s+$BytesLineRegex\s+$TimeLineRegex\s+$EndedLineRegex") {
  35.                         $TimeElapsed = [math]::Round([decimal] ($EndedTime - $StartedTime).TotalSeconds, $Precision)
  36.                         New-Object PSObject -Property @{
  37.                             Path = $p
  38.                             TotalBytes = [decimal] $Matches['ByteCount']
  39.                             TotalMBytes = [math]::Round(([decimal] $Matches['ByteCount'] / 1MB), $Precision)
  40.                             TotalGBytes = [math]::Round(([decimal] $Matches['ByteCount'] / 1GB), $Precision)
  41.                             BytesFailed = [decimal] $Matches['BytesFailed']
  42.                             DirCount = [decimal] $Matches['DirCount']
  43.                             FileCount = [decimal] $Matches['FileCount']
  44.                             DirFailed = [decimal] $Matches['DirFailed']
  45.                             FileFailed  = [decimal] $Matches['FileFailed']
  46.                             TimeElapsed = $TimeElapsed
  47.                             StartedTime = $StartedTime
  48.                             EndedTime   = $EndedTime
  49.  
  50.                         } | Select Path, TotalBytes, TotalMBytes, TotalGBytes, DirCount, FileCount, DirFailed, FileFailed, TimeElapsed, StartedTime, EndedTime
  51.                     }
  52.                     else {
  53.                         Write-Warning -Message "Path '$p' output from robocopy was not in an expected format."
  54.                     }
  55.                 }
  56.             }
  57.         }
  58.     }
  59.     process {
  60.         foreach ($p in $Path) {
  61.             Write-Verbose -Message "Processing path '$p'. $([datetime]::Now)."
  62.             if (-not (Test-Path -Path $p -PathType Container)) {
  63.                 Write-Warning -Message "$p does not exist or is a file and not a directory. Skipping."
  64.                 continue
  65.             }
  66.             if ($RoboOnly) {
  67.                 Get-RoboFolderSizeInternal -Path $p -Precision $Precision
  68.                 continue
  69.             }
  70.             $ErrorActionPreference = 'Stop'
  71.             try {
  72.                 $StartFSOTime = [datetime]::Now
  73.                 $TotalBytes = $FSO.GetFolder($p).Size
  74.                 $EndFSOTime = [datetime]::Now
  75.                 if ($TotalBytes -eq $null) {
  76.                     Get-RoboFolderSizeInternal -Path $p -Precision $Precision
  77.                     continue
  78.                 }
  79.             }
  80.             catch {
  81.                 if ($_.Exception.Message -like '*PERMISSION*DENIED*') {
  82.                     Write-Verbose "Caught a permission denied. Trying robocopy."
  83.                     Get-RoboFolderSizeInternal -Path $p -Precision $Precision
  84.                     continue
  85.                 }
  86.                 Write-Warning -Message "Encountered an error while processing path '$p': $_"
  87.                 continue
  88.             }
  89.             $ErrorActionPreference = 'Continue'
  90.             New-Object PSObject -Property @{
  91.                 Path = $p
  92.                 TotalBytes = [decimal] $TotalBytes
  93.                 TotalMBytes = [math]::Round(([decimal] $TotalBytes / 1MB), $Precision)
  94.                 TotalGBytes = [math]::Round(([decimal] $TotalBytes / 1GB), $Precision)
  95.                 BytesFailed = $null
  96.                 DirCount = $null
  97.                 FileCount = $null
  98.                 DirFailed = $null
  99.                 FileFailed  = $null
  100.                 TimeElapsed = [math]::Round(([decimal] ($EndFSOTime - $StartFSOTime).TotalSeconds), $Precision)
  101.                 StartedTime = $StartFSOTime
  102.                 EndedTime = $EndFSOTime
  103.             } | Select Path, TotalBytes, TotalMBytes, TotalGBytes, DirCount, FileCount, DirFailed, FileFailed, TimeElapsed, StartedTime, EndedTime
  104.         }
  105.     }
  106.     end {
  107.         [void][System.Runtime.Interopservices.Marshal]::ReleaseComObject($FSO)
  108.         [gc]::Collect()
  109.     }
  110. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement