Think Objectively

A challenge many new comers to PowerShell face, especially those arriving with a VBScript background, and one that I often talk about, is shifting gears from working with text to working with objects. Here’s a good example.

The Win32_OperatingSystem class returns a value for TotalVisibleMemorySize, which should be the amount of physical memory installed in a computer. Let’s say as a beginner PowerShell user you want to use this number. You know enough PowerShell to know you can use Select-Object to retrieve just that value:

PS C:\> gwmi win32_operatingsystem | select totalvisiblememorysize

totalvisiblememorysize
————————

1572144

In the VBScript world, or even other text based shells, you might be tempted to figuring out how to parse that output. Instead,a the PowerShell way is it recognize that the Get-WMIObject cmdlet wrote an object to the pipeline which Select accepted and then wrote another object to the pipeline, albeit one with a single property. You can verify this by piping the expression to Get-Member.

PS C:\> gwmi win32_operatingsystem | select totalvisiblememorysize | gm

   TypeName: Selected.System.Management.ManagementObject

Name                   MemberType   Definition
—-                   ———-   ———-
Equals                 Method       bool Equals(System.Object obj)
GetHashCode            Method       int GetHashCode()
GetType                Method       type GetType()
ToString               Method       string ToString()
totalvisiblememorysize NoteProperty System.UInt64 totalvisiblememorysize=1572144

Here’s the part that may not be so obvious. PowerShell let’s us treat the entire expression as an object and as such let’s us grab just the property using the object.property format.

PS C:\> (gwmi win32_operatingsystem).TotalVisibleMemorySize
1572144

We wrap the expression in parentheses which instructs PowerShell to evaluate this first, which returns the WMI object. We don’t even need to use Select-Object because we can access the property directly. This is easier to read, but this is still an object.

PS C:\> (gwmi win32_operatingsystem).TotalVisibleMemorySize | gm

   TypeName: System.UInt64

Name        MemberType Definition
—-        ———- ———-
CompareTo   Method     int CompareTo(System.Object value), int CompareTo(Syste…
Equals      Method     bool Equals(System.Object obj), bool Equals(System.UIn…
GetHashCode Method     int GetHashCode()
GetType     Method     type GetType()
GetTypeCode Method     System.TypeCode GetTypeCode()
ToString    Method     string ToString(), string ToString(System.IFormatProvid…

If you encounter other challenges as you move to PowerShell, please feel free to use the forums at ScriptingAnswers.com.

Post to Twitter Post to Plurk Post to Yahoo Buzz Post to Delicious Post to Digg Post to Facebook Post to FriendFeed Post to Google Buzz Post to Ping.fm Post to Reddit Post to Slashdot Post to StumbleUpon Post to Technorati

This entry was posted in PowerShell, Training, WMI and tagged , , . Bookmark the permalink.

3 Responses to Think Objectively

  1. MikeShepard says:

    I sometimes use the (….).Property syntax, but lately, I’ve been doing a lot more of this (using the script you provided):

    gwmi win32_operatingsystem | select -expand TotalvisibleMemorySize

    It’s a bit more typing, but it seems a bit more idiomatic in powershell. Now, if I had stored the result of the gwmi in a variable, I would definitely use the dot to get to the properties, but I’m trying to avoid “wide ranging parentheses”.

    Just a style choice, but I thought I’d mention it.

    • Jeffery Hicks says:

      There’s nothing wrong with that approach, other than some extra typing. But at least it is clear. Plus you are clearly thinking about objects and not trying to parse output. The final approach anyone might take will likely depend on what they are trying to do with the value. In addition to my examples in the blog entry and your suggestion, this would also work:

      PS C:\> $os=gwmi win32_operatingsystem
      PS C:\> $os.TotalVisibleMemorySize

      This approach has the added benefit of tab completion for the property name.

  2. Panic says:

    Excellent post! Coming from perl/php I have had soo much trouble getting my head about this approach to scripting. Actually came across this post because of a problem at work and this solved it in under ten minutes :D

    Thanks alot and keep ‘em coming!

    /Powershell newbie