Link to home
Start Free TrialLog in
Avatar of brianm71
brianm71Flag for United States of America

asked on

Determine My Documents folder Size

We are preparing to move My Documents folders from its local location to a network location.  Before we do this I would like to run a powershell script to access all the machines on my network and return the My Documents folder size for each person on the machine.  Would somebody be able to point me in the right direction?
Avatar of Sander Stad
Sander Stad
Flag of Netherlands image

This website can help you with that:

http://myitforum.com/cs2/blogs/yli628/archive/2007/05/14/powershell-script-to-check-folder-size.aspx

You have to have an Excel document with all the workstation in it. This can be ip addresses.

Good luck!
ASKER CERTIFIED SOLUTION
Avatar of Chris Dent
Chris Dent
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
My solution can handle irregular or customized places of the Documents folder and it uses PS 2.0 remoting.
After you define my get-docsize function, it can be called like this:

"computer1", "computer2" | get-docsize | ft docpath, computer, user, size

So it expect computernames as input in the pipeline.
You can get computernames from any source you have: txtfile, get-computer cmdlet from the Active Directory module or Quest's cmdlets.
function get-docsize 
{
begin {
$script = {
dir "hklm:\software\microsoft\windows nt\currentversion\profilelist" | ?{$_.name -match "-(\d+)(\.bak)?$"} | ?{([int] $matches[1]) -ge 1000} |
	%{
		$sid = if($_.name -match "\\(S-1-5-21-[^.]+)(.bak)?$"){$Matches[1]}
		$ntacc = New-Object System.Security.Principal.SecurityIdentifier($sid)
		$acct = $ntacc.translate([System.Security.Principal.NTAccount])
		if(Test-Path "Microsoft.PowerShell.Core\Registry::HKU\$sid"){
			$documents = (Get-ItemProperty -path "Microsoft.PowerShell.Core\Registry::HKU\$sid\software\microsoft\windows\currentversion\explorer\shell folders" -Name personal).personal
		}
		else{
			$profpath = (Get-ItemProperty -Path "Microsoft.PowerShell.Core\Registry::$($_.name)" -Name profileimagepath).profileimagepath
			[void] (invoke-expression "reg load HKU\temp '$profpath\ntuser.dat'")
			$documents = (Get-ItemProperty -path "Microsoft.PowerShell.Core\Registry::HKU\temp\software\microsoft\windows\currentversion\explorer\user shell folders" -Name personal).personal
			$documents = $documents -replace ($env:userprofile -replace "\\","\\"), $profpath
			[void] (invoke-expression 'reg unload HKU\temp')
		}
		$size = 0
		dir $documents -Force -Recurse -ErrorAction SilentlyContinue | %{$size=0} {$size+= $_.length} 
		New-Object -TypeName psobject -Property @{computer = $env:COMPUTERNAME; user = $acct; docpath = $documents; size = $size}
	}
}}
process{
Invoke-Command -ComputerName $_ -ScriptBlock $script
}
}

Open in new window

This is even better, if there is a profile for a deleted user, it gives "unknown" as username.
I also refined some parts of it and some little bugs were removed.
So my solution finds the documents folder not only on c drive, but anywhere else.
This new version can be called like this:
"computer1", "computer2" | get-docsize | ft docpath, user, size, pscomputername

if you need sizes in MBs:
"computer1", "computer2" | get-docsize | ft docpath, user, @{n="size in MBs";e={$_.size/1mb};f="n0"}, pscomputername

Of course you need to run it as admin on all computers.
function get-docsize 
{
begin {
$script = {
dir "hklm:\software\microsoft\windows nt\currentversion\profilelist" | ?{$_.name -match "-(\d+)(\.bak)?$"} | ?{([int] $matches[1]) -ge 1000} |
	%{
		$sid = if($_.name -match "\\(S-1-5-21-[^.]+)(.bak)?$"){$Matches[1]}
		$ntacc = New-Object System.Security.Principal.SecurityIdentifier($sid)
		try {$acct = $ntacc.translate([System.Security.Principal.NTAccount])}
		catch {$acct = "unknown"}
		if(Test-Path "Microsoft.PowerShell.Core\Registry::HKU\$sid"){
			$documents = (Get-ItemProperty -path "Microsoft.PowerShell.Core\Registry::HKU\$sid\software\microsoft\windows\currentversion\explorer\shell folders" -Name personal -ErrorAction silentlycontinue).personal
		}
		else{
			$profpath = (Get-ItemProperty -Path "Microsoft.PowerShell.Core\Registry::$($_.name)" -Name profileimagepath).profileimagepath
			[void] (invoke-expression "reg load HKU\temp '$profpath\ntuser.dat'")
			$documents = (Get-ItemProperty -path "Microsoft.PowerShell.Core\Registry::HKU\temp\software\microsoft\windows\currentversion\explorer\shell folders" -Name personal -ErrorAction silentlycontinue).personal
			[void] (invoke-expression 'reg unload HKU\temp')
		}
		dir $documents -Force -Recurse -ErrorAction SilentlyContinue | %{$size=0} {$size+= $_.length} 
		New-Object -TypeName psobject -Property @{user = $acct; docpath = $documents; size = $size}
	}
}}
process{
Invoke-Command -ComputerName $_ -ScriptBlock $script
}
}

Open in new window