(+351) 21 24 10006  ·  info@bconcepts.pt
Carnaxide, Lisbon

How to generate disk usage reports by user in PowerShell

João Barros 26 de October de 2026 4 min read

This tutorial shows how to generate a disk usage report by user in PowerShell, useful for audits, freeing up space, or understanding who consumes the most storage. You will learn how to identify the owner of folders, sum sizes recursively and export a CSV ready for analysis.

Prerequisites

  • Windows with PowerShell 5.1 or PowerShell 7+
  • Read permissions on the folders to analyze
  • Basic knowledge of PowerShell commands and CSV files

Step 1: Understand the logic and prepare the environment

Why: we need to list folders, get the owner and calculate the total size of the files inside each folder. To avoid slow queues, we will limit depth or process only top-level folders. Create a folder where you will save the final CSV.

# Exemplo: definir pasta alvo e ficheiro de saída  $RootPath = 'C:\Compartilhado\Projetos'  $OutputCsv = 'C:\Relatorios\UsoPorUtilizador.csv'    # Criar pasta de output se não existir  $OutDir = Split-Path $OutputCsv  if (-not (Test-Path $OutDir)) { New-Item -Path $OutDir -ItemType Directory | Out-Null }

Step 2: Get the owner of a folder

Explanation: we use Get-Acl to obtain the Owner. The Owner comes in the format DOMAIN\User or MACHINE\User; we will normalize only the username for grouping.

# Função para obter proprietário (owner) simplificado  function Get-FolderOwner {      param([string]$Path)      try {          $acl = Get-Acl -Path $Path -ErrorAction Stop          $owner = $acl.Owner -split '\\' | Select-Object -Last 1          return $owner      } catch {          return 'UNKNOWN'      }  }

Step 3: Calculate the size of a folder recursively

Explanation: for each folder we will sum the Length of files recursively. For performance, avoid too many I/O operations; use -File and -ErrorAction to skip inaccessible files.

# Função para calcular dimensão (em bytes) de uma pasta  function Get-FolderSize {      param([string]$Path)      try {          $size = Get-ChildItem -Path $Path -Recurse -File -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum          return ([int64]$size.Sum)      } catch {          return 0      }  }

Step 4: Group by owner and generate the report

Explanation: we iterate each subfolder of the RootPath (depth 1 is a common choice), get owner and size, and then group by owner. Finally, we export to CSV with sizes in human format and in bytes.

# Lista de pastas de topo (profundidade 1)  $folders = Get-ChildItem -Path $RootPath -Directory -ErrorAction Stop    $results = foreach ($f in $folders) {      $path = $f.FullName      $owner = Get-FolderOwner -Path $path      $bytes = Get-FolderSize -Path $path      [PSCustomObject]@{          Owner = $owner          Path = $path          Bytes = $bytes          SizeMB = [math]::Round($bytes / 1MB, 2)      }  }    # Agrupar por Owner e somar Bytes  $grouped = $results | Group-Object -Property Owner | ForEach-Object {      $totalBytes = ($_.Group | Measure-Object -Property Bytes -Sum).Sum      [PSCustomObject]@{          Owner = $_.Name          TotalBytes = [int64]$totalBytes          TotalMB = [math]::Round($totalBytes / 1MB, 2)          Folders = ($_.Group | Select-Object Path,SizeMB)      }  }    # Exportar resumo para CSV (sem a lista de pastas detalhada)  $grouped | Select-Object Owner,TotalBytes,TotalMB | Export-Csv -Path $OutputCsv -NoTypeInformation -Encoding UTF8    # Mostrar no ecrã um exemplo resumido  $grouped | Sort-Object -Property TotalBytes -Descending | Format-Table -Property Owner,TotalMB -AutoSize

Step 5: Handle deep or large folders (advanced options)

Explanation: if you have many subfolders or files, you can parallelize or process in batches. In PowerShell 7+ use ForEach-Object -Parallel; in other versions use jobs. You can also skip folders with certain patterns to speed up.

# Exemplo simples com -Filter para ignorar pastas temporárias  $folders = Get-ChildItem -Path $RootPath -Directory -ErrorAction Stop | Where-Object { $_.Name -notmatch 'temp|cache|bak' }

Verify the result

Open the CSV file in Excel or with Import-Csv to confirm. On the screen you should see a table of Owners with TotalMB. Verify that totals match with a double-check on known folders using Get-FolderSize for a specific folder.

# Verificar um owner específico no PowerShell  Import-Csv -Path $OutputCsv | Where-Object { $_.Owner -eq 'joao' }    # Verificar dimensão de uma pasta manualmente  Get-FolderSize -Path 'C:\Compartilhado\Projetos\ProjetoX' | %{ $_ } # devolve bytes

Conclusion

You generated a disk usage report by user in PowerShell, with owner per folder, sums in bytes and export to CSV. Next steps: add more columns (dates, file count), integrate with a scheduler for periodic reports or send the CSV by email. Tip: if owners appear as SID or 'UNKNOWN', ensure permissions and test Get-Acl manually.