<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Media And Microcode : Add-Member</title><link>http://blogs.msdn.com/mediaandmicrocode/archive/tags/Add-Member/default.aspx</link><description>Tags: Add-Member</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Microcode: PowerShell Scripting Tricks: More Joy of Hashtables (with Get-HashtableAsObject)</title><link>http://blogs.msdn.com/mediaandmicrocode/archive/2008/11/30/microcode-powershell-scripting-tricks-more-joy-of-hashtables-with-get-hashtableasobject.aspx</link><pubDate>Sun, 30 Nov 2008 05:10:27 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9156852</guid><dc:creator>JamesBrundage</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/mediaandmicrocode/comments/9156852.aspx</comments><wfw:commentRss>http://blogs.msdn.com/mediaandmicrocode/commentrss.aspx?PostID=9156852</wfw:commentRss><description>&lt;p&gt;I recently did two different &amp;quot;in depth&amp;quot; posts.&amp;#160; One on &lt;a href="http://blogs.msdn.com/mediaandmicrocode/archive/2008/11/27/microcode-powershell-scripting-tricks-the-joy-of-using-hashtables-with-windows-powershell.aspx"&gt;The Joy Of Hashtables&lt;/a&gt; and another on &lt;a href="http://blogs.msdn.com/mediaandmicrocode/archive/2008/11/26/microcode-powershell-scripting-tricks-select-object-note-properties-vs-add-member-script-properties.aspx"&gt;Select-Object versus Add-Member&lt;/a&gt;.&amp;#160; At the end of Select-Object vs Add-Member, I hinted at more convenient ways to write objects that used Script Properties.&amp;#160; Script Properties are particularly useful because, unlike Note Properties, they are evaluated when they are requested.&amp;#160; This means that PowerShell scripts that use script properties will often be faster than those using note properties.&amp;#160; Sadly, they're kind of clunky to add.&amp;#160; A script property will normally look like:&lt;/p&gt; &lt;i&gt;   &lt;blockquote&gt;     &lt;pre&gt;New-Object Object | Add-Member ScriptProperty Foo { Get-Random } -passThru&lt;/pre&gt;
  &lt;/blockquote&gt;
&lt;/i&gt;

&lt;p&gt;This gets pretty ugly, pretty fast.&lt;/p&gt;

&lt;p&gt;Luckily, the post on hashtables gives us a good way out of this problem.&amp;#160; Hashtables look fairly clean in PowerShell scripts, and, with a little bit of work, you can easily turn a hashtable into an object. Here's the Get-HashtableAsObject function.&lt;/p&gt;

&lt;p&gt;In case you're curious, the comments inside of the function aren't just there for fun. They're an example of script-embedded help (which will not be out until CTP3). Once script-embedded Help is there, you can write help content for a function with just what's in the function below, and you'll be able to Get-Help on your function just like any other command.&lt;/p&gt;
&lt;i&gt;
  &lt;blockquote&gt;
    &lt;pre&gt;function Get-HashtableAsObject([Hashtable]$hashtable)
{  
    #.Synopsis
    #    Turns a Hashtable into a PowerShell object
    #.Description
    #    Creates a new object from a hashtable.
    #.Example
    #    # Creates a new object with a property foo and the value bar
    #    Get-HashtableAsObject @{&amp;quot;Foo&amp;quot;=&amp;quot;Bar&amp;quot;}
    #.Example
    #    # Creates a new object with a property Random and a value
    #    # that is generated each time the property is retreived
    #    Get-HashtableAsObject @{&amp;quot;Random&amp;quot; = { Get-Random }}
    #.Example
    #    # Creates a new object from a hashtable with nested hashtables
    #    Get-HashtableAsObject @{&amp;quot;Foo&amp;quot; = @{&amp;quot;Random&amp;quot; = {Get-Random}}} 
    process {       
        $outputObject = New-Object Object
        if ($hashtable -and $hashtable.Count) {
            $hashtable.GetEnumerator() | Foreach-Object {
                if ($_.Value -is [ScriptBlock]) {
                    $outputObject = $outputObject | 
                        Add-Member ScriptProperty $_.Key $_.Value -passThru
                } else {
                    if ($_.Value -is [Hashtable]) {
                        $outputObject = $outputObject | 
                            Add-Member NoteProperty $_.Key (Get-HashtableAsObject $_.Value) -passThru
                    } else {                    
                        $outputObject = $outputObject | 
                            Add-Member NoteProperty $_.Key $_.Value -passThru
                    }
                }                
            }
        }
        $outputObject
    }
}&lt;/pre&gt;
  &lt;/blockquote&gt;
&lt;/i&gt;

&lt;p&gt;Let's check out a few practical examples of Get-HashtableAsObject:&lt;/p&gt;

&lt;p&gt;Check out how we can use Get-HashtableAsObject to create a random card&lt;/p&gt;
&lt;i&gt;
  &lt;blockquote&gt;
    &lt;pre&gt;$card = Get-HashtableAsObject @{
    Card = {2..9 + &amp;quot;Jack&amp;quot;, &amp;quot;Queen&amp;quot;, &amp;quot;King&amp;quot;, &amp;quot;Ace&amp;quot; | Get-Random}
    Suit = {&amp;quot;Clubs&amp;quot;, &amp;quot;Hearts&amp;quot;, &amp;quot;Diamonds&amp;quot;, &amp;quot;Spades&amp;quot; | Get-Random}
}
$card
$card
$card&lt;/pre&gt;
  &lt;/blockquote&gt;
&lt;/i&gt;

&lt;p&gt;Notice that each time I output $card, the Card and Suit change. This is because the script property is being evaluated each time it is read. Essentially, it's shuffling every card. Cool, right?&lt;/p&gt;

&lt;p&gt;The last post introduced you to PowerShell's ability to add hashtables together to merge them.&amp;#160; Check out how we can use this to combine an object that generates user information and an object that generates system information.&lt;/p&gt;
&lt;i&gt;
  &lt;blockquote&gt;
    &lt;pre&gt;$userInfo = @{
    LocalUsers = {Get-WmiObject &amp;quot;Win32_UserAccount WHERE LocalAccount='True'&amp;quot;}
    LoggedOnUsers = {Get-WmiObject &amp;quot;Win32_LoggedOnUser&amp;quot; }    
}

$systemInfo = @{
    Memory = {Get-WmiObject Win32_PhysicalMemory}
    Drives = {Get-WmiObject Win32_LogicalDisk}
}

$liveUserInfo = Get-HashtableAsObject $userInfo
$liveSystemInfo = Get-HashtableAsObject $systemInfo
$allInfo = Get-HashtableAsObject ($userInfo + $systemInfo)

$liveUserInfo.LocalUsers
$allInfo.Drives&lt;/pre&gt;
  &lt;/blockquote&gt;
&lt;/i&gt;

&lt;p&gt;This trick is particularly convenient for quickly joining together chunks of logic from different scripts. For instance, if I wanted to add a property the $userInfo object that kicked off all users who had been logged on for over a period of time, I'd simply add another hashtable to the user info to accomplish this task. For those much more in tune with object-oriented programming, what this essentially gives me is the ability to inherit from an objects defined this way in PowerShell, without the joy of overloading.&amp;#160; Faking overloading is considerably more complicated, so we'll save that one for another day, but I hope that the tricks contained within this post help you write more robust scripts.&lt;/p&gt;

&lt;p&gt;Hope this helps,&lt;/p&gt;

&lt;p&gt;James Brundage [MSFT]&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9156852" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/mediaandmicrocode/archive/tags/PowerShell/default.aspx">PowerShell</category><category domain="http://blogs.msdn.com/mediaandmicrocode/archive/tags/Microcode/default.aspx">Microcode</category><category domain="http://blogs.msdn.com/mediaandmicrocode/archive/tags/Add-Member/default.aspx">Add-Member</category><category domain="http://blogs.msdn.com/mediaandmicrocode/archive/tags/System.Collections.Hashtable/default.aspx">System.Collections.Hashtable</category><category domain="http://blogs.msdn.com/mediaandmicrocode/archive/tags/Get-HashtableAsObject/default.aspx">Get-HashtableAsObject</category></item><item><title>Microcode: PowerShell Scripting Tricks: Select-Object (Note Properties) vs Add-Member (Script Properties)</title><link>http://blogs.msdn.com/mediaandmicrocode/archive/2008/11/26/microcode-powershell-scripting-tricks-select-object-note-properties-vs-add-member-script-properties.aspx</link><pubDate>Wed, 26 Nov 2008 07:30:20 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9143255</guid><dc:creator>JamesBrundage</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/mediaandmicrocode/comments/9143255.aspx</comments><wfw:commentRss>http://blogs.msdn.com/mediaandmicrocode/commentrss.aspx?PostID=9143255</wfw:commentRss><description>&lt;p&gt;As I've said a number of times before, PowerShell's quantum leap forward is something called the Object Pipeline.&amp;#160; It allows you to take the results of one command and easily use them with the next, which means that each command you create becomes a link in a chain rather than an isolated island.&lt;/p&gt;  &lt;p&gt;In several posts, I've talked about how to create objects that are property bags as a means to an end (such as when I was &lt;a href="http://blogs.msdn.com/mediaandmicrocode/archive/2008/07/21/microcode-cleaning-up-get-recordedtv-with-select-object.aspx"&gt;Cleaning Up Get-RecordedTV with Select-Object&lt;/a&gt;), but I haven't really focused on how to make property bags that much on its own.&lt;/p&gt;  &lt;p&gt;There are two basic ways you can create property bags in PowerShell.&amp;#160; The first is by using the Add-Member cmdlet, and the second is by using Select-Object.&amp;#160; As with anything in programming, deciding which way to get a task done involves some trade offs.&amp;#160; Most of the trade off between Select-Object and Add-Member has to do with what type of properties the commands add to objects.&amp;#160; Select-Object will add note properties, which are fine for most purposes and quick to create, but they cannot do anything when the properties are set and cannot create properties that are always up to date.&lt;/p&gt;  &lt;p&gt;The following table shows when I tend to use Select-Object versus Add-Member&lt;/p&gt;  &lt;table cellspacing="0" cellpadding="2" width="400" border="0"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="200"&gt;&lt;strong&gt;When your priority is...&lt;/strong&gt;&lt;/td&gt;        &lt;td valign="top" width="200"&gt;&lt;strong&gt;You should use...&lt;/strong&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="200"&gt;Adding a few quick properties to an existing object &lt;/td&gt;        &lt;td valign="top" width="200"&gt;Select-Object&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="200"&gt;Adding properties that may be take time to evaluate or need to be up-to-date&lt;/td&gt;        &lt;td valign="top" width="200"&gt;Add-Member&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="200"&gt;Creating a property bag to summarize information from cmdlets &lt;/td&gt;        &lt;td valign="top" width="200"&gt;Select-Object&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="200"&gt;Wrapping an existing object with a friendlier surface area &lt;/td&gt;        &lt;td valign="top" width="200"&gt;Add-Member&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="200"&gt;Adding a single property to an object&lt;/td&gt;        &lt;td valign="top" width="200"&gt;Add-Member&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;The bottom line of choosing which way to make your property bag comes down to speed and convenience.&amp;#160; Because you have to call Add-Member once for every property you wish to add to an object, Add-Member is often slower to use for this purpose than Select-Object.&amp;#160; However, to be fair, Select-Object is kind of ugly and a little inconvenient to write. To prove the speed gain and illustrate the strange syntax of Select-Object, here's two equivalent scripts that both create an object with two properties, Foo and Bar:&lt;/p&gt;  &lt;table cellspacing="0" cellpadding="2" width="400" border="0"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="200"&gt;&lt;strong&gt;Select-Object&lt;/strong&gt;&lt;/td&gt;        &lt;td valign="top" width="200"&gt;&lt;strong&gt;Add-Member&lt;/strong&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="200"&gt;         &lt;pre&gt;    1 | Select-Object @{
        Name='Foo'
        Expression={&amp;quot;Bar&amp;quot;}
    }, @{
        Name='Bar'
        Expression={&amp;quot;Baz&amp;quot;}
    }&lt;/pre&gt;
      &lt;/td&gt;

      &lt;td valign="top" width="200"&gt;
        &lt;pre&gt;      New-Object Object |
          Add-Member NoteProperty Foo Bar -passThru | 
          Add-Member NoteProperty Bar Baz -passThru
      &lt;/pre&gt;
      &lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;Obviously, Select-Object is a lot less clean looking than Add-Member.&amp;#160; To determine which is faster, just pack each item into a long loop and run Measure-Command.&lt;/p&gt;

&lt;pre&gt;Measure-Command {
    foreach ($n in (1..1000))  {
        1 | Select-Object @{
            Name='Foo'
            Expression={&amp;quot;Bar&amp;quot;}
        }, @{
            Name='Bar'
            Expression={&amp;quot;Baz&amp;quot;}
        }
    }
}

Measure-Command {
    foreach ($n in (1..1000))  {
        New-Object Object |
            Add-Member NoteProperty Foo Bar -passThru | 
            Add-Member NoteProperty Bar Baz -passThru
    }
}&lt;/pre&gt;

&lt;p&gt;On my computer, Select-Object is much faster. It's actually twice as fast over 1000 objects. The more properties you add with Add-Member, the slower it will be.&amp;#160; This concern should really only come into play when dealing with thousands of objects, so if you were adding properties to the output of Get-Process, the difference should be negligible, but if you're adding properties to every single file underneath Windows\System32, you'll probably want to use Select-Object.&lt;/p&gt;

&lt;p&gt;Add-Member does have one huge advantage over Select-Object, and that's the type of properties that it can tack on.&amp;#160; Select-Object adds Note Properties, which means that it will evaluate each item as you add it to the object (and never again).&amp;#160; For instance, if I wanted to add a property to a file object that would tell me who currently had the file open, then I would need that property to always be up to date.&amp;#160; In this case, if you had a command that would determine if the file was open (let's call it Test-FileOpen) you could add something like Add-Member ScriptProperty IsOpened { Test-FileOpen $this.Fullname }.&lt;/p&gt;

&lt;p&gt;The other thing you can do with a script property that you can't do with a note property is set values.&amp;#160; To do this with a ScriptPropery, you simply give Add-Member two script blocks.&amp;#160; The first is a getter and the second is a setter. In the simple example below, I update the value of Bar through the setter of Foo&lt;/p&gt;

&lt;pre&gt;$i = New-Object Object |
    Add-Member NoteProperty Bar &amp;quot;baz&amp;quot; -passThru |     
    Add-Member ScriptProperty Foo {$this.Bar} { $this.Bar = $args[0]} -passThru 
$i
$i.Foo = &amp;quot;bing&amp;quot;
$i&lt;/pre&gt;

&lt;p&gt;ScriptProperties are especially useful if you would like to take a surface area that's awkward and make it nicer to use in PowerShell.&amp;#160; In this case, you simply create a new object, attach the original object to it as a note property, and then use Script Properties to talk to the original object.&amp;#160; Sadly, in order to demonstrate the usefulness of that particular capability, I have to walk through a long and complicated API.&amp;#160;&amp;#160; Rather than make this post more long and complicated, I'll leave this post as food for thought on where you can use note properties and script properties in your code.&lt;/p&gt;

&lt;p&gt;Have fun experimenting, and remember: Select-Object's Speedy, Add-Member's Adaptable.&lt;/p&gt;

&lt;p&gt;Hope this helps,&lt;/p&gt;

&lt;p&gt;James Brundage [MSFT]&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9143255" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/mediaandmicrocode/archive/tags/Microcode/default.aspx">Microcode</category><category domain="http://blogs.msdn.com/mediaandmicrocode/archive/tags/Select-Object/default.aspx">Select-Object</category><category domain="http://blogs.msdn.com/mediaandmicrocode/archive/tags/Scripting+Tricks/default.aspx">Scripting Tricks</category><category domain="http://blogs.msdn.com/mediaandmicrocode/archive/tags/Measure-Command/default.aspx">Measure-Command</category><category domain="http://blogs.msdn.com/mediaandmicrocode/archive/tags/Add-Member/default.aspx">Add-Member</category></item></channel></rss>