A nifty PowerShell example

Let us say you have a directory full of files written to it over a period of time, and you need to quickly move all of the files written on a given day (any time during that day) to a different folder. This is something that is difficult to do using just the standard DOS command line -- but it becomes quite easy in PowerShell (aka Monad).

Here's an example file listing. It may look a little strange -- I created it in PowerShell -- but DOS users can quickly figure out what's going on here:

  Mode   LastWriteTime        Length  Name
  ----   -------------        ------  ----
  -a---   6/1/2006   7:08 PM    3365  000eb851-4c72-4a75-a29c-f73a94ebced2.eml
  -a---  5/28/2006   3:44 AM    2251  000ef0e8-c1c2-4f21-9a30-790a3577475f.eml
  -a---  5/23/2006  10:07 PM   12236  000f2034-b207-414c-abc5-dab4f5db9c03.eml
  -a---   6/1/2006   8:02 AM    1945  000f3c7b-1aa7-48cd-929e-23bef6e19219.eml
  -a---  5/30/2006  11:56 PM    3909  000f4276-947e-4f45-8672-1d465ef0e4e1.eml
  -a---   6/1/2006   9:04 AM    1944  000f8674-3ca1-4e53-bca0-f94e82881400.eml
  -a---  5/29/2006   5:24 PM    3986  000f96ed-6785-4fe9-8511-dcb8dfe14936.eml
  -a---   6/9/2006   6:19 AM    1787  000fe9c9-9b62-4e87-80c1-65018faa7c7d.eml
  -a---  5/30/2006   8:20 AM   12254  000fefb6-9974-4e7b-9939-06bc0e26af82.eml

So, how am I to pull out just the files written on June 1st? Let's fire up PowerShell and try the following command (note that it should be entered on a single line; I've line-wrapped it for readability):

dir | where-object { $_.LastWriteTime -like "6/1/2006 *" } |
    move-item -destination c:\DestFolder

Let's take a closer look.

I pipe the output of the dir cmdlet into where-object, which allows me to set up a single condition to compare against all of the objects in the pipeline. Here's the key difference between PowerShell and traditional shell scripting: in PowerShell, the objects passed through the pipeline are real objects, not strings of text. They have various properties -- in this case, we see the properties of Mode, Name, Length, and most importantly for what we want, LastWriteTime.

Note that in my condition, I use the -like comparison so I can specify the date portion of the date/time string, along with a wildcard indicating that any time will match. I could just as easily specify a string of "6/*/2006" for any day in June or "* PM" to show any file written between 12:00PM and 11:59PM regardless of the day.

The move-item cmdlet normally takes a source parameter as well, but since it's getting objects from the pipeline, it automatically knows to use those instead.

Now, getting used to PowerShell takes time, because it's a bit wordier than you're used to (especially if, like me, you're used to UNIX shell programming, which seems to hate vowels). It is absolutely worth the effort, though, because you really can start doing some amazing (and useful) stuff with just a little effort.

Note: dir dir is an alias for the get-childitem cmdlet. PowerShell provides many of these aliases. I used the alias here so that my example is slightly more readable to those of you who haven't seen PowerShell code before, but if you're going to use it I urge you to not rely on the aliases. Use the full commands so that you more fully understand what is going on in your cmdlets.

Print | posted @ Monday, June 12, 2006 4:14 PM

Comments on this entry:

Gravatar # re: A nifty PowerShell example
by Jeffrey Snover at 6/14/2006 5:42 PM

RE: Wordier
This is a good form for scripts that you are going to share with other people because it is easy to read but if you want pithy, you could have done it this way:

dir |?{$_.lastwritetime -like "6/1/2006 *"}|mi t1.txt c:\DestFolder

? is an alias for WHERE
mi is an alias for Move-Item
you could use positional parameters for destination on MI

We tried to design it so that you could go like a rocket for interactive use but also be precise for documentation purposes when sharing scripts. Don Jones of Sapien showed a demo of an alpha version of Primalscript which would take a fast-n-dirty script and autoexpand all the aliases (and convert back again) - it was awesome.

Jeffrey Snover
Windows PowerShell Architect
Gravatar # PowerShell helps provide customizable batch processing
by US ISV Developer Evangelism Team at 2/8/2008 1:39 PM

My ISVs have been talking about how to expose methods in their application to sorta process data similar
Gravatar # PowerShell helps provide customizable batch processing
by Noticias externas at 2/8/2008 2:21 PM

My ISVs have been talking about how to expose methods in their application to sorta process data similar
Comments have been closed on this topic.