Important Notice: On February 29th, this community was put into read-only mode. All existing posts will remain but customers are unable to add new posts or comment on existing. Please feel to join our Community Discord for any questions and discussions.

Local Users Profile Size Report



I know it is stupid to overkill sql with thousands of pointless custom entries as a result of Basic or SQL Report like pic below, but is there some better way to get simple Report about Local Users Profile Sizes?



Date Votes
  • I think I have something I can modify for you. I'll poke at it and let you know.

  • Hmm, this could take a couple of days.

  • I'm having trouble coming up with a clean way to implement what I had in mind. I need to narrow the scope.

    What do you want to do with the data you collect? Are you looking for the largest profile on each computer, or are you looking for every profile larger than a certain size?

  • Hi guys,

    I too would like to know how to do this :)

    Originally I was trying to do a directory listing of the Users folder:

    cd %systemdrive%\users\ | dir

    I then tried to do a report of the Registry Hive for this location as the ProfileImagePath gives me the information I want:

    HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList

    We have staff moving between computers with roaming profiles and the drives are slowly filling up, some with profiles of people who haven't worked for the company for many months or even years.

  • Originally I was going to do this with Custom Variables (blog coming soon), but that would get messy in this use case. My new idea is to use the Files table, but that's going to require some voodoo. Once I finish the Custom Variables blog I'll start working on this.

    Edit: I meant Custom Fields, not Custom Variables.

  • I ended up using PDQ Deploy to run a Powershell script on all the computers to list all the user profiles and sizes. The sizes doesn't quite work at the moment, it gives sizes smaller than reality, possibly due to folder permission issues, a lack of recursion into all the sub-folders, or that the OST files are hidden files.

  • Yeah, this is what I'm going to use to gather the profile size:

    ForEach ( $User_Dir in ( Get-ChildItem "C:\Users" ) ) {

    # Compute the sum of all files in the directory and convert the result into megabytes
    [int32]$Profile_Size = ( Get-ChildItem -Recurse -Force -Path "$($User_Dir.FullName)" | Measure-Object -Property Length -Sum ).Sum / 1MB
    $User_Profile_Array += "$($User_Dir.Name), $Profile_Size"

  • I put the powershell script into a folder called C:\support\ and then used this to call the powershell script:

    cd "c:\Support\"
    Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass -Force
    ./Get-FolderSize.ps1 -path c:\users | Out-File \\PDQSERVERNAME\Get-FolderSize\$env:computername.txt

    The "Get-FolderSize.ps1" is this powershell file. As mentioned above, it doesn't get the size correctly:

    [Parameter(Position=0, ValueFromPipeline=$True, Mandatory=$True)]

    function Get-FolderSize ($_ = (get-item .)) {
    Process {
    $ErrorActionPreference = "SilentlyContinue"
    $length = (Get-ChildItem $_.fullname -recurse | Measure-Object -property length -sum).sum
    $obj = New-Object PSObject
    $obj | Add-Member NoteProperty Folder ($_.FullName)
    $obj | Add-Member NoteProperty Length ($length)
    Write-Output $obj

    Function Class-Size($size)

    IF($size -ge 1GB)
    "{0:n2}" -f ($size / 1GB) + " GigaBytes"
    ELSEIF($size -ge 1MB)
    "{0:n2}" -f ($size / 1MB) + " MegaBytes"
    "{0:n2}" -f ($size / 1KB) + " KiloBytes"

    Get-ChildItem $Path | Get-FolderSize | Sort-Object -Property Length -Descending | Select-Object -Property Folder, Length |
    Format-Table -Property Folder, @{ Label="Size of Folder" ; Expression = {Class-Size($_.Length)} }
  • $User_Profile_Array += "$($User_Dir.Name), $Profile_Size"

    Please don't do that. Use rather a dictionary list or an array list or something with .Add()  and .Remove() methods so you aren't rebuilding the array with every iteration.

    I don't think this is going to be a huge performance hit in this case *however*, example time:

    #empty hash table, keeping this simple

    $User_Profile_Hash = @{}

    #Add Name and Value to hash table


    You could then go ahead later and do cool stuff with the hashtable later:


    $UserProfileObj = New-Object -Type psobject -Property $User_Profile_Hash

    $UserProfileObj | ConvertTo-HTML -Fragment  -OutVariable $table

    Send-MailMessage -smtpserver -Subject "User Profile Sizes" -To you -From script -Body $table -BodyAsHTML


    There, no more soapbox, sorry to hijack :)

  • Stephen, you are correct that I am doing it the slow way. However, that array will almost certainly never be more than a few hundred entries, so I didn't feel like doing it the fancy efficient way :)

  • Don't be lazy ;) Haha. I'm just giving you a hard time, friend!