We used Select-Object -Property to, well, select properties (after all, PowerShell is trying to move away from obscure abbreviations and truncated names.)  How do we know what properties exist?

Get-Member. We covered this in N00bs 2.

Get-Member gets the ... class members of a PowerShell object.  Again, clear names make for clumsy blogs.  To review, class members are methods (functions) and properties (data fields) that the PowerShell object.  It's called a class member, but belongs to an object because an object is an instance of a class. 

Let's see what properties a folder has:

PSH> Get-Item c:\

That's the folder.  Now, let's get the members:

PSH> Get-Member -InputObject (Get-Item c:\)

And let's only look at the properties:

PSH> gm -i (gi \) -m *property

   TypeName: System.IO.DirectoryInfo

Name              MemberType     Definition
----              ----------     ----------
Mode              CodeProperty   System.String Mode{get=Mode;}
PSChildName       NoteProperty   System.String PSChildName=C:\
PSDrive           NoteProperty   System.Management.Automation.PSDriveInfo PS...
PSIsContainer     NoteProperty   System.Boolean PSIsContainer=True
PSParentPath      NoteProperty   System.String PSParentPath=
PSPath            NoteProperty   System.String PSPath=Microsoft.PowerShell.C...
PSProvider        NoteProperty   System.Management.Automation.ProviderInfo P...
Attributes        Property       System.IO.FileAttributes Attributes {get;set;}
CreationTime      Property       System.DateTime CreationTime {get;set;}
CreationTimeUtc   Property       System.DateTime CreationTimeUtc {get;set;}
Exists            Property       System.Boolean Exists {get;}
Extension         Property       System.String Extension {get;}
FullName          Property       System.String FullName {get;}
LastAccessTime    Property       System.DateTime LastAccessTime {get;set;}
LastAccessTimeUtc Property       System.DateTime LastAccessTimeUtc {get;set;}
LastWriteTime     Property       System.DateTime LastWriteTime {get;set;}
LastWriteTimeUtc  Property       System.DateTime LastWriteTimeUtc {get;set;}
Name              Property       System.String Name {get;}
Parent            Property       System.IO.DirectoryInfo Parent {get;}
Root              Property       System.IO.DirectoryInfo Root {get;}
BaseName          ScriptProperty System.Object BaseName {get=$this.Name;}

Now, what is contained in each?  We could expand each, but why?  Let's talk about loops.

Firstly, let's save the 'Get-Item' as a variable so we don't have to keep getting the same data over and over:

PSH> $folder = gi \

Next, let's look the data:

PSH> gm -i $folder -m *property | % { $name= $_.name; @{$name= $_.$name; } } | fl

Okay, lots of shortcuts here.  Here's a glossary:

gm  Get-Member
-i  -InputObject
-m  -MemberType
%   Foreach-Object
$_  Placeholder (see below.)
@{} Output results as name/value pairs (to be elaborated in later post.)
fl  Format-List

Let's take a walkthrough:

We're getting the list of properties, then looping over that list.  For each element of the list (shown in the table above), we are interested only in the 'Name' value.

Let's look at looping a little closer.  $_ is the placeholder.  We're looking at each element of the list in turn, right?  Which element are we looking at right now?  PowerShell takes the current one and makes it available to us as $_.

So, for the first property, the 'mode' property, we take only the name, 'mode.'  $folder.mode is the mode data ("d--hs"), just like $folder.attribute is the attribute data ("Hidden, System, Directory")

Next, we do a bit of syntactical sugar, primarily for formatting.  We could have just output "$name = $($folder.$name)", but that outputs strings, not objects.  This means the data is flattened to strings.  Instead @{} allows us to output name/value pairs.

PSH> gm -i $folder -m *property | % { $name = $_.Name; @{$name = $folder.$name; } }

Name                           Value
----                           -----
Mode                           d--hs
PSChildName                    C:\
PSDrive                        C
PSIsContainer                  True
PSPath                         Microsoft.PowerShell.Core\FileSystem::C:\
PSProvider                     Microsoft.PowerShell.Core\FileSystem
Attributes                     Hidden, System, Directory
CreationTime                   4/21/2009 11:01:15 PM
CreationTimeUtc                4/22/2009 6:01:15 AM
Exists                         True
FullName                       C:\
LastAccessTime                 8/25/2009 3:37:54 PM
LastAccessTimeUtc              8/25/2009 10:37:54 PM
LastWriteTime                  8/25/2009 3:37:54 PM
LastWriteTimeUtc               8/25/2009 10:37:54 PM
Name                           C:\
Root                           C:\
BaseName                       C:\ 

As an example of what we mean:

PSH> gm -i $folder -m *property | % { $name = $_.Name; @{$name = $folder.$name; } } | fl

Name  : Mode
Value : d--hs


Now, this isn't as useful as we'd like because that syntactical sugar.  We're outputting a list of name/value pairs, instead of a single data object.  A future post will expand on this.

To review, we learned a few things:

  • Get-Member allows us to inspect an object's class members.
  • We can specify MemberType to filter Get-Member's output.
  • Foreach-Object loops over each item in a list, such as an object's properties.