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\'""
Endoro
  • 37,015
  • 8
  • 50
  • 63
user99999991
  • 1,351
  • 3
  • 19
  • 43
  • 1
    what do you get if you run it directly in powershell ? like `Get-DirSize "c:\Users\username\Saved Games"` – Loïc MICHEL Jul 10 '13 at 14:02
  • Same thing - not recognized as the name of a cmdlet... – user99999991 Jul 10 '13 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!!! – CB. Jul 10 '13 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 – Loïc MICHEL Jul 10 '13 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) – TheTrowser Jul 26 '15 at 20:48
  • @TheTrowser That just solved it for a similar problem I was having. You should list this as an answer instead of a comment! – Ryan Harris Oct 30 '20 at 15:06

4 Answers4

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.

mklement0
  • 382,024
  • 64
  • 607
  • 775
vishva
  • 366
  • 5
  • 17
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
Aaron Jensen
  • 25,861
  • 15
  • 82
  • 91
  • 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. – user99999991 Jul 10 '13 at 15:14
  • Do you get an error when you run `Get-Item` on that directory at a normal PowerShell prompt? – Aaron Jensen Jul 10 '13 at 15:38
  • 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 – mklement0 Feb 03 '21 at 16:00
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.

Ryan Harris
  • 329
  • 2
  • 9
  • 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](https://stackoverflow.com/a/40445998/45375), i.e. it performs _string interpolation_, whereas `'...'` does not. – mklement0 Feb 03 '21 at 16:04
  • 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... – Ryan Harris Feb 14 '21 at 07:15
  • 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;) – mklement0 Feb 14 '21 at 09:33
0

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
Jimi Best
  • 11
  • 3
  • 1
    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](/help/how-to-answer). – Community Apr 12 '22 at 10:03