Prof. Powershell

To DIR, with Love; Or, How PowerShell 3 Will Improve Get-ChildItem

PowerShell 3 will make some much-needed improvements to the Get-ChildItem cmdlet.

If you are like me and have a lot of experience with shells, you probably were a little frustrated with Windows PowerShell. For example, in the CMD shell it was very easy to run a command and return only folders:

C:\>dir test /ad
  Volume in drive C has no label.
  Volume Serial Number is A4BA-3EFF

  Directory of C:\test

12/12/2011 02:22 PM   <DIR>   .
12/12/2011 02:22 PM   <DIR>   ..
12/12/2011 02:21 PM   <DIR>   Folder$
12/12/2011 02:21 PM   <DIR>   Folder1
12/12/2011 02:21 PM   <DIR>   Folder2
12/12/2011 02:21 PM   <DIR>   Folder3
12/12/2011 02:21 PM   <DIR>   Folder4
12/12/2011 02:21 PM   <DIR>   Folder5
       0 File(s)            0 bytes
       8 Dir(s) 5,071,941,632 bytes free


But in PowerShell 2.0, we needed to resort to additional filtering using Where-Object:

PS C:\> dir test | where {$_.psiscontainer}

  Directory: C:\test

Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 12/12/2011 2:21 PM Folder1
d---- 12/12/2011 2:21 PM Folder2
d---- 12/12/2011 2:21 PM Folder3
d---- 12/12/2011 2:21 PM Folder4
d---- 12/12/2011 2:21 PM Folder5

Hardly efficient. Fortunately, PowerShell 3.0 has made dramatic improvements to Get-ChildItem, which is what the dir alias is pointing to.

Now if we only want directories we can use the –Directory parameter:

PS C:\test> dir -directory

Directory: C:\test

Mode         LastWriteTime  Length  Name
----         -------------  ------  ----
d----   12/12/2011 2:21 PM          Folder1
d----   12/12/2011 2:21 PM          Folder2
d----   12/12/2011 2:21 PM          Folder3
d----   12/12/2011 2:21 PM          Folder4
d----   12/12/2011 2:21 PM          Folder5

Or perhaps all we want are files:

PS C:\test> dir $env:temp -file | measure length -sum

Count    : 8
Average  :
Sum      : 478225
Maximum  :
Minimum  :
Property : Length

Get-Childitem also makes it easier to filter on attributes. For example, in the CMD shell we could do this:

C:\>dir /ah
  Volume in drive C has no label.
  Volume Serial Number is A4BA-3EFF

  Directory of C:\

02/16/2011  03:54 PM  <DIR>        $Recycle.Bin
07/14/2009  12:08 AM  <JUNCTION>   Documents and Settings [C:\Users]
12/02/2011  03:07 PM  <DIR>        ProgramData
08/21/2009  12:08 PM  <DIR>        Recovery
12/01/2011  08:31 PM  <DIR>        System Volume Information
            0 File(s)            0 bytes
            5 Dir(s) 5,071,945,728 bytes free

In PowerShell 3.0 we have parameters for Hidden, ReadOnly and System:

PS C:\test> dir c:\ -hidden

  Directory: C:\

Mode        LastWriteTime   Length  Name
----        -------------   ------  ----
d--hs   2/16/2011 3:54 PM           $Recycle.Bin
d--hs   7/14/2009 1:08 AM           Documents and Settings
d--h-   12/2/2011 3:07 PM           ProgramData
d--hs   8/21/2009 1:08 PM           Recovery
d--hs   12/1/2011 8:31 PM           System Volume Information

They can even be combined:

PS C:\test> dir c:\ -hidden -system

  Directory: C:\

Mode       LastWriteTime  Length  Name
----       -------------  ------  ----
d--hs  2/16/2011 3:54 PM          $Recycle.Bin
d--hs  7/14/2009 1:08 AM          Documents and Settings
d--hs  8/21/2009 1:08 PM          Recovery
d--hs  12/1/2011 8:31 PM          System Volume Information

Get-ChildItem also has a new parameter called –Attributes that gets very granular. Suppose I want to list just the compressed files in my Scripts folder:

PS C:\> dir c:\scripts -Attributes Compressed

  Directory: C:\scripts

Mode         LastWriteTime  Length  Name
----         -------------  ------  ----
-a---   12/2/2011 12:28 PM    1345  get-computers2.ps1
-a---   12/2/2011 12:42 PM    1666  get-computers3.ps1

PowerShell 3.0 has given us a much needed update to Get-ChildItem. All your version 2 scripts should continue to work, but I expect you’ll find these new features will make new scripting projects even easier. Be sure to look at full cmdlet help for Get-ChildItem.

Note: This information is based on PowerShell 3.0 CTP 2 and is subject to change -- and most likely will -- prior to release.


Reader Comments:

Sun, Mar 4, 2012 Marcus UK

Have they included a -depth parameter or better yet -mindepth & -maxdepth to limit recursive searches to a subdirectory depth?

Wed, Jan 18, 2012 Lee Holmes

A few other cool features: - dir -directory (and friends) have parameter aliases for those that had the cmd.exe syntax burned into their synapses: "dir -ad", "dir -ah", etc. - The attributes parameter supports a mini filtering syntax: "dir -Attribute Directory+Hidden" (directory AND hidden), "dir -Attribute !Directory,!ReadOnly" (File, or not readonly". You can simplify the constants down just like you can with parameters, so these work too: dir -a d+h, dir -a "!d,!r" - dir *.ps1 -rec just works now :) No need for dir . -filter *.ps1 -rec :)

Wed, Jan 18, 2012 EVVJSK

Glad to see articles on PowerShell scripting here (not only when a new release is due). Handy to see ways to improve upon CMD methods of doing tasks (because after all the best way to learn something is to use it frequently). Hopefully we will continue to see what Powershell can do to improve upon basic CMD tasks.Thanks !

Add Your Comment Now:

Your Name:(optional)
Your Email:(optional)
Your Location:(optional)
Comment:
Please type the letters/numbers you see above