5
# --------------------------------------------------------- 
# ScriptingGamesBeginnerEvent8_PS1.ps1 
# ed wilson, msft 8/21/2009 
# PS1 version of HSG-08-19-09 http://bit.ly/1d8Rww 
# 
# --------------------------------------------------------- 
Param( 
 [string]$path = 'C:\', 
 [int]$first = 50 
)# end param 
# *** Function Here *** 

function Get-DirSize ($path){ 

  BEGIN {} 

  PROCESS{ 
    $size = 0 
    $folders = @() 

    foreach ($file in (Get-ChildItem $path -Force -ea SilentlyContinue)) { 
      if ($file.PSIsContainer) { 
        $subfolders = @(Get-DirSize $file.FullName) 
        $size += $subfolders[-1].Size 
        $folders += $subfolders 
      } else { 
        $size += $file.Length 
      } 
    } 

    $object = New-Object -TypeName PSObject 
    $object | Add-Member -MemberType NoteProperty -Name Folder -Value (Get-Item $path).fullname
    $object | Add-Member -MemberType NoteProperty -Name Size -Value $size 
    $folders += $object 
    Write-Output $folders 
  } 

  END {} 
} # end function Get-DirSize 

Function Get-FormattedNumber($size) 
{ 
  IF($size -ge 1GB) 
   { 
      "{0:n2}" -f  ($size / 1GB) + " GigaBytes" 
   } 
 ELSEIF($size -ge 1MB) 
    { 
      "{0:n2}" -f  ($size / 1MB) + " MegaBytes" 
    } 
 ELSE 
    { 
      "{0:n2}" -f  ($size / 1KB) + " KiloBytes" 
    } 
} #end function Get-FormattedNumber 

 # *** Entry Point to Script *** 

 if(-not(Test-Path -Path $path))  
   {  
     Write-Host -ForegroundColor red "Unable to locate $path"  
     Help $MyInvocation.InvocationName -full 
     exit  
   } 
 Get-DirSize -path $path |  
 Sort-Object -Property size -Descending |  
 Select-Object -Property folder, size -First $first | 
 Format-Table -Property Folder,  
  @{ Label="Size of Folder" ; Expression = {Get-FormattedNumber($_.size)} } 

So I have this script which I got from http://gallery.technet.microsoft.com/scriptcenter/36bf0988-867f-45be-92c0-f9b24bd766fb#content

I've been playing around with it and created a batch file to help handle the log output of this file and such. However, I'm noticing that paths with spaces in them don't get read. For example ..Documents\My Music

    Get-Item : Could not find item C:\Users\MyUser\Documents\My Music.
    At C:\test.ps1:32 char:80
    +     $object | Add-Member -MemberType NoteProperty -Name Folder -Value (Get-It
    em <<<<  $path).fullname
+ CategoryInfo          : ObjectNotFound: (C:\Users\MyUser\Documents\My
Music:String) [Get-Item], IOException
 + FullyQualifiedErrorId : ItemNotFound,Microsoft.PowerShell.Commands.GetIt
emCommand

On the TechNet page for the code, someone brings the issue up but no solution is given. I'm not sure how to fix it here. I've played with the $path argument, surrounding it in " " or ' ' and such.

Here is part of the batch file to execute it:

  C:\WINDOWS\system32\WindowsPowerShell\v1.0\powershell.exe -noe -command "&       'C:\test.ps1' -path "'C:\Users\MyUser\'""
6
  • 1
    what do you get if you run it directly in powershell ? like Get-DirSize "c:\Users\username\Saved Games" Commented Jul 10, 2013 at 14:02
  • Same thing - not recognized as the name of a cmdlet... Commented Jul 10, 2013 at 14:04
  • 1
    @user2229804 How 'not recognized as the name of a cmdlet' can be the same thing of 'Could not find item C:\Users\MyUser\Documents\My Music.'?? They are two different error. You need to load the function get-dirSize in the console to have it available to call!!! Commented Jul 10, 2013 at 14:25
  • +1 for @C.B comment, or just call c:\test\ScriptingGamesBeginnerEvent8_PS1.ps1 -path "you path with space" from a powershell console Commented Jul 10, 2013 at 14:31
  • 1
    in case of a problem regarding the spaces itself you might try putting single quotes around the path. (added, as this pops up first through google with that problem) Commented Jul 26, 2015 at 20:48

4 Answers 4

9

Might be a bit late for answer here, but, as Aaron mentioned, this is not due to spaces in the path.

If you read the documentation for Get-Item cmdlet, there is a -Force switch, which allows the cmdlet to get items that cannot otherwise be accessed, such as hidden items.

Moreover, it seems from your code that you are not expecting to pass a wildcard pattern to the cmdlet, so instead of (Get-Item $path).FullName you should use

(Get-Item -force -LiteralPath $path).FullName

That should resolve this issue.

Sign up to request clarification or add additional context in comments.

Comments

6

It's not the spaces in the path. If it was, the error would say path C:\Users\MyUser\Documents\My couldn't be found. Get-ChildItem and Get-Item behave... strangely... with certain files/directories, returning errors like you're seeing. That's why Get-ChildItem has an -ErrorAction SilentlyContinue parameter on it. I would add the same to the call to Get-Item, i.e. change

(Get-Item $path).FullName

to

(Get-Item $path -ErrorAction SilentlyContinue | Select-Object -ExpandProperty FullName

or even forgo the call to Get-Item completely:

$path

3 Comments

Is there anyway to fix it though and get it to act accordingly? I replaced it with both ways, but its still skipping the directory for example. Meanwhile I purposely made My Pictures the biggest folder under that user. But otherwise - the script looks much better now and can log much more streamlined, thanks.
Do you get an error when you run Get-Item on that directory at a normal PowerShell prompt?
Good point about the spaces, but there's no mystery about Get-Item / Get-ChildItem's behavior here: because the My Music folder is a hidden one (technically, it is a hidden junction created by the system for backward compatibility), these cmdlets can only retrieve it if -Force is also specified. That said, in the case at hand, because the hidden junction simply points to the (non-hidden) sibling folder Music, ignoring it with -ErrorAction SilentlyContinue / Ignore may be preferable, but in general you would not want to ignore hidden items when calculating a directory's size
1

Using the command below didn't work for me.

get-item 'some path with  two spaces.txt' 

Enclosing the filename in double quotes within the single quotes, forces Powershell to use the filename as written.

get-item '"some path with  two spaces.txt"' 

Note: I'm totally cringing at my origal message (cleaned up a bit above). Below is a better example of what I was seeing.

$exampleA = "c:\temp\weird  path\blah.txt"
$exampleB = "c:\temp\normal path\blah.txt"
 
#  Works
get-item '$exampleA'
get-item $exampleB
 
#  Fails
get-item $exampleA

1 Comment

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
0

As suggested by TheTrowser in a comment above: The problem may be resolved if you replace the double-quotes with single quotes surrounding the file directory with spaces. This is what solved it for me.

3 Comments

With respect to spaces, both "..." (double-quoting) and '...' (single-quoting) work. The only difference between these to quoting styles is that "..." is an expandable string, i.e. it performs string interpolation, whereas '...' does not.
With respect to spaces, using double-quotes caused the path value to be broken down into separate pieces whenever a space is found. Using single-quotes prevented this from happening. I'm not sure if this is what you meant with your comment, but there is certainly an unexpected difference if the user isn't careful. Better to err on the side of caution and always use the single-quotes so the user doesn't have to work that into their troubleshooting steps. Keep it simple...
No, that's not how double-quoting works, and the OP's issue has nothing to do with quoting, despite their thinking it does. (Yes, if you have a verbatim value with spaces, it's good practice to use single quotes, both to signal the intent and to prevent accidental expansion;)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.