<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://powershell.com/cs/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>Dreaming in PowerShell : Select-Object, Add-Props</title><link>http://powershell.com/cs/blogs/tobias/archive/tags/Select-Object/Add-Props/default.aspx</link><description>Tags: Select-Object, Add-Props</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 (Build: 30929.2835)</generator><item><title>Automatically Surfacing Subproperties</title><link>http://powershell.com/cs/blogs/tobias/archive/2011/02/17/automatically-surfacing-subproperties.aspx</link><pubDate>Thu, 17 Feb 2011 00:22:00 GMT</pubDate><guid isPermaLink="false">f421715f-7aba-45f0-8a8d-44de5318a3a7:9384</guid><dc:creator>Tobias</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://powershell.com/cs/blogs/tobias/rsscomments.aspx?PostID=9384</wfw:commentRss><comments>http://powershell.com/cs/blogs/tobias/archive/2011/02/17/automatically-surfacing-subproperties.aspx#comments</comments><description>&lt;p&gt;Sometimes, the &lt;strong&gt;true information you are after is burried deep inside object models&lt;/strong&gt;. For example, when you manage virtual machines with the VMWare cmdlets, &lt;strong&gt;Get-VM&lt;/strong&gt; will get you only very sparse pieces of information. The real goodies are stored inside of subproperties (which was true&amp;nbsp;&lt;a target="_blank" href="http://powershell.com/cs/blogs/tobias/archive/2011/02/07/reading-and-writing-mpeg-tags-and-attributes-part-2.aspx"&gt;for the MPEG3 module I created last week&lt;/a&gt; as well).&amp;nbsp;Time to get a look at what is going on here (and how you can &amp;quot;move&amp;quot; hidden subproperties onto the stage and make them visible).&amp;nbsp; &lt;/p&gt;
&lt;p&gt;&lt;span style="text-decoration:line-through;"&gt;Just so you don&amp;#39;t think today I was discussing a really geeky topic: what you learn today has tremendous real-life-value. For example, you are getting to see two pieces of code that seem to do the exact same thing, yet the one approach (which is used by a lot of folks out there) &lt;strong&gt;takes 40x more time to execute than the other&lt;/strong&gt; (which is not so known).&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;[This kept spinning in my head: how come there can be such a huge performance difference? Turns out it was a caching effect. The true and real world speed benefit is about 2x, not 40x. Sorry if I got you excited &lt;img src="http://powershell.com/cs/emoticons/emotion-8.gif" alt="Indifferent" /&gt;. Fortunately, the performance gain was just an added benefit, the main story is about auto-adding script properties.]&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;To get a feeling for the problem, did you ever try and create a list of system DLLs and their versions? A plain &lt;strong&gt;dir&lt;/strong&gt; won&amp;#39;t get you far:&lt;/p&gt;
&lt;div class="pscode"&gt;PS &amp;gt; dir &lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$env:windir&lt;/span&gt;&lt;/span&gt;\system32\&lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;*&lt;/span&gt;&lt;/span&gt;.&lt;span style="color:#8b4513;"&gt;&lt;span class="method"&gt;dll&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Mode LastWriteTime Length Name&lt;br /&gt;&lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;----&lt;/span&gt;&lt;/span&gt; &lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;-------------&lt;/span&gt;&lt;/span&gt; &lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;------&lt;/span&gt;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;&lt;span class="op"&gt;----&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="modifier"&gt;&lt;span style="color:#5f9ea0;"&gt;-a&lt;/span&gt;&lt;/span&gt;&lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;---&lt;/span&gt;&lt;/span&gt; 14.07.2009 03:39 158208 &lt;span style="color:#8b4513;"&gt;&lt;span class="namespace"&gt;aaclient.dll&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="modifier"&gt;&lt;span style="color:#5f9ea0;"&gt;-a&lt;/span&gt;&lt;/span&gt;&lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;---&lt;/span&gt;&lt;/span&gt; 14.07.2009 03:40 3745792 &lt;span style="color:#8b4513;"&gt;&lt;span class="namespace"&gt;accessibilitycpl.dll&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="modifier"&gt;&lt;span style="color:#5f9ea0;"&gt;-a&lt;/span&gt;&lt;/span&gt;&lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;---&lt;/span&gt;&lt;/span&gt; 14.07.2009 03:24 39424 &lt;span style="color:#8b4513;"&gt;&lt;span class="namespace"&gt;ACCTRES.dll&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;(...)&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;This line does, though:&lt;/p&gt;
&lt;div class="pscode"&gt;PS &amp;gt; dir &lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$env:windir&lt;/span&gt;&lt;/span&gt;\system32\&lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;*&lt;/span&gt;&lt;/span&gt;.&lt;span class="method"&gt;&lt;span style="color:#8b4513;"&gt;dll&lt;/span&gt;&lt;/span&gt; | &lt;span class="verbnoun"&gt;&lt;span style="color:#5f9ea0;"&gt;Select-Object&lt;/span&gt;&lt;/span&gt; &lt;span class="modifier"&gt;&lt;span style="color:#5f9ea0;"&gt;-ExpandProperty&lt;/span&gt;&lt;/span&gt; VersionInfo&lt;br /&gt;&lt;br /&gt;ProductVersion FileVersion FileName&lt;br /&gt;&lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;--------------&lt;/span&gt;&lt;/span&gt; &lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;-----------&lt;/span&gt;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;&lt;span class="op"&gt;--------&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;6.1.7600.16385 6.1.7600.1638... C:\Windows\system32\&lt;span style="color:#8b4513;"&gt;&lt;span class="namespace"&gt;aaclient.dll&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;6.1.7600.16385 6.1.7600.1638... C:\Windows\system32\&lt;span style="color:#8b4513;"&gt;&lt;span class="namespace"&gt;accessibilitycpl.dll&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;6.1.7600.16385 6.1.7600.1638... C:\Windows\system32\&lt;span style="color:#8b4513;"&gt;&lt;span class="namespace"&gt;ACCTRES.dll&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;6.1.7600.16385 6.1.7600.1638... C:\Windows\system32\&lt;span style="color:#8b4513;"&gt;&lt;span class="namespace"&gt;acledit.dll&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;6.1.7600.16385 6.1.7600.1638... C:\Windows\system32\&lt;span style="color:#8b4513;"&gt;&lt;span class="namespace"&gt;aclui.dll&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;6.1.7600.16385 6.1.7600.1638... C:\Windows\system32\&lt;span style="color:#8b4513;"&gt;&lt;span class="namespace"&gt;acppage.dll&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;6.1.7600.16385 6.1.7600.1638... C:\Windows\system32\&lt;span style="color:#8b4513;"&gt;&lt;span class="namespace"&gt;acproxy.dll&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;(...)&lt;/div&gt;
&lt;p&gt;So what&amp;#39;s going on here? &lt;/p&gt;
&lt;h3&gt;Either - Or: Select-Object can not always help&lt;/h3&gt;
&lt;p&gt;It turns out that file objects have a subproperty called &lt;strong&gt;VersionInfo&lt;/strong&gt;. It contains the DLL versions we are after. To display that information, I used &lt;strong&gt;Select-Object&lt;/strong&gt; with its &lt;strong&gt;-expandProperty&lt;/strong&gt; parameter. This parameter tells PowerShell to &lt;strong&gt;replace the current object&lt;/strong&gt; with the content of the property you specify. Thus I &lt;strong&gt;lost my original FileInfo&lt;/strong&gt; object and in return got the VersionInfo object found in the property I specified. &lt;/p&gt;
&lt;p&gt;Sounds confusing? Now, what it means is that &lt;strong&gt;Select-Object&lt;/strong&gt; can only give you the content of &lt;strong&gt;one&lt;/strong&gt; subproperty, and you pay for it by loosing all the properties in your original object. It is a simple trade-off.&lt;/p&gt;
&lt;h3&gt;Getting Dirty: Using Ad-Hoc Script Properties&lt;/h3&gt;
&lt;p&gt;In the previous example, the trade-off was ok. It is not always ok, though. Let&amp;#39;s assume you need a &lt;strong&gt;report that includes filename, version, length and creationtime&lt;/strong&gt;. How can you do that? After all, the &lt;strong&gt;information needed now comes partially&lt;/strong&gt; from the FileInfo object and partially from the VersionInfo object stored inside of it.&lt;/p&gt;
&lt;p&gt;Well, if your hair is on fire and you haven&amp;#39;t got the time for a decent approach, use &lt;strong&gt;quick-and-dirty scripted properties&lt;/strong&gt;. Here is an example:&lt;/p&gt;
&lt;div class="pscode"&gt;PS &amp;gt; dir &lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$env:windir&lt;/span&gt;&lt;/span&gt;\system32\&lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;*&lt;/span&gt;&lt;/span&gt;.&lt;span class="method"&gt;&lt;span style="color:#8b4513;"&gt;dll&lt;/span&gt;&lt;/span&gt; | &lt;br /&gt;&lt;span class="verbnoun"&gt;&lt;span style="color:#5f9ea0;"&gt;Select-Object&lt;/span&gt;&lt;/span&gt; Name, { &lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$_&lt;/span&gt;&lt;/span&gt;.&lt;span class="namespace"&gt;&lt;span style="color:#8b4513;"&gt;VersionInfo.FileVersion&lt;/span&gt;&lt;/span&gt; }, Length, CreationTime&lt;br /&gt;&lt;br /&gt;Name &lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$_&lt;/span&gt;&lt;/span&gt;.&lt;span class="namespace"&gt;&lt;span style="color:#8b4513;"&gt;VersionInfo.Fil&lt;/span&gt;&lt;/span&gt; Length CreationTime&lt;br /&gt;eVersion&lt;br /&gt;&lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;----&lt;/span&gt;&lt;/span&gt; &lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;-------------------&lt;/span&gt;&lt;/span&gt; &lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;------&lt;/span&gt;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;&lt;span class="op"&gt;------------&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="namespace"&gt;&lt;span style="color:#8b4513;"&gt;aaclient.dll&lt;/span&gt;&lt;/span&gt; 6.1.7600.16385 (... 158208 14.07.2009 02:17:30&lt;br /&gt;accessibilitycpl... 6.1.7600.16385 (... 3745792 14.07.2009 02:34:00&lt;br /&gt;&lt;span class="namespace"&gt;&lt;span style="color:#8b4513;"&gt;ACCTRES.dll&lt;/span&gt;&lt;/span&gt; 6.1.7600.16385 (... 39424 14.07.2009 01:57:56&lt;br /&gt;&lt;span class="namespace"&gt;&lt;span style="color:#8b4513;"&gt;acledit.dll&lt;/span&gt;&lt;/span&gt; 6.1.7600.16385 (... 9216 14.07.2009 01:48:08&lt;br /&gt;&lt;span class="namespace"&gt;&lt;span style="color:#8b4513;"&gt;aclui.dll&lt;/span&gt;&lt;/span&gt; 6.1.7600.16385 (... 154112 14.07.2009 01:57:30&lt;/div&gt;
&lt;div class="pscode"&gt;(...)&lt;/div&gt;
&lt;p&gt;As you see, instead of specifying a column name (property name), you can also submit a script block and access the object subproperty you are after. That approach is ok, and you can even use a &lt;strong&gt;hash table&lt;/strong&gt; if you want to get rid of the ugly column header:&lt;/p&gt;
&lt;div class="pscode"&gt;PS &amp;gt; &lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$version&lt;/span&gt;&lt;/span&gt; &lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;=&lt;/span&gt;&lt;/span&gt; @{name &lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;=&lt;/span&gt;&lt;/span&gt; &lt;span class="string"&gt;&lt;span style="color:#800000;"&gt;&amp;#39;Version&amp;#39;&lt;/span&gt;&lt;/span&gt;; expression&lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;=&lt;/span&gt;&lt;/span&gt;{ &lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$_&lt;/span&gt;&lt;/span&gt;.&lt;span class="namespace"&gt;&lt;span style="color:#8b4513;"&gt;VersionInfo.FileVersion&lt;/span&gt;&lt;/span&gt; } }&lt;br /&gt;PS &amp;gt; dir &lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$env:windir&lt;/span&gt;&lt;/span&gt;\system32\&lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;*&lt;/span&gt;&lt;/span&gt;.&lt;span class="method"&gt;&lt;span style="color:#8b4513;"&gt;dll&lt;/span&gt;&lt;/span&gt; | &lt;span class="verbnoun"&gt;&lt;span style="color:#5f9ea0;"&gt;Select-Object&lt;/span&gt;&lt;/span&gt; Name, &lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$version&lt;/span&gt;&lt;/span&gt;, Length, Crea&lt;br /&gt;tionTime&lt;br /&gt;&lt;br /&gt;Name Version Length CreationTime&lt;br /&gt;&lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;----&lt;/span&gt;&lt;/span&gt; &lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;-------&lt;/span&gt;&lt;/span&gt; &lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;------&lt;/span&gt;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;&lt;span class="op"&gt;------------&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="namespace"&gt;&lt;span style="color:#8b4513;"&gt;aaclient.dll&lt;/span&gt;&lt;/span&gt; 6.1.7600.16385 (... 158208 14.07.2009 02:17:30&lt;br /&gt;(...)&lt;/div&gt;
&lt;p&gt;&lt;em&gt;(Note that this only works when you define the hash table in one line. That&amp;#39;s a PowerShell bug)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;However, it&amp;#39;s a lot of writing, especially with the hash tables. Even worse, &lt;strong&gt;Select-Object actually replaces&amp;nbsp;your object&lt;/strong&gt; and is creating &lt;strong&gt;a read-only copy&lt;/strong&gt;. For reports, that is ok. If you want to keep the object methods, though, you may never use &lt;strong&gt;Select-Object&lt;/strong&gt;. And if you want fast scripts, you should avoid &lt;strong&gt;Select-Object&lt;/strong&gt; as well. Let&amp;#39;s check out why and what to do about it next.&lt;/p&gt;
&lt;h3&gt;ScriptProperties&amp;nbsp;to the Rescue&lt;/h3&gt;
&lt;p&gt;Rather than using &lt;strong&gt;Select-Object&lt;/strong&gt; to add properties, you can&amp;nbsp;also add script properties to the original object. In fact, that is something PowerShell uses by default for a lot of objects. Take a look at process objects returned by &lt;strong&gt;Get-Process&lt;/strong&gt;:&lt;/p&gt;
&lt;div class="pscode"&gt;PS &amp;gt; &lt;span class="verbnoun"&gt;&lt;span style="color:#5f9ea0;"&gt;Get-Process&lt;/span&gt;&lt;/span&gt; | &lt;span class="verbnoun"&gt;&lt;span style="color:#5f9ea0;"&gt;Get-Member&lt;/span&gt;&lt;/span&gt; &lt;span class="modifier"&gt;&lt;span style="color:#5f9ea0;"&gt;-MemberType&lt;/span&gt;&lt;/span&gt; ScriptProperty&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;TypeName: &lt;span style="color:#8b4513;"&gt;&lt;span class="namespace"&gt;System.Diagnostics.Process&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;Name MemberType Definition&lt;br /&gt;&lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;----&lt;/span&gt;&lt;/span&gt; &lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;----------&lt;/span&gt;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;&lt;span class="op"&gt;----------&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;Company ScriptProperty &lt;span class="namespace"&gt;&lt;span style="color:#8b4513;"&gt;System.Object&lt;/span&gt;&lt;/span&gt; Company {get&lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;=&lt;/span&gt;&lt;/span&gt;&lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$this&lt;/span&gt;&lt;/span&gt;.&lt;span class="namespace"&gt;&lt;span style="color:#8b4513;"&gt;Mainmodule.Fi&lt;/span&gt;&lt;/span&gt;...&lt;br /&gt;CPU ScriptProperty &lt;span class="namespace"&gt;&lt;span style="color:#8b4513;"&gt;System.Object&lt;/span&gt;&lt;/span&gt; CPU {get&lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;=&lt;/span&gt;&lt;/span&gt;&lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$this&lt;/span&gt;&lt;/span&gt;.&lt;span class="method"&gt;&lt;span style="color:#8b4513;"&gt;TotalProcessorTim&lt;/span&gt;&lt;/span&gt;...&lt;br /&gt;Description ScriptProperty &lt;span class="namespace"&gt;&lt;span style="color:#8b4513;"&gt;System.Object&lt;/span&gt;&lt;/span&gt; Description {get&lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;=&lt;/span&gt;&lt;/span&gt;&lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$this&lt;/span&gt;&lt;/span&gt;.&lt;span class="method"&gt;&lt;span style="color:#8b4513;"&gt;Mainmodul&lt;/span&gt;&lt;/span&gt;...&lt;br /&gt;FileVersion ScriptProperty &lt;span class="namespace"&gt;&lt;span style="color:#8b4513;"&gt;System.Object&lt;/span&gt;&lt;/span&gt; FileVersion {get&lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;=&lt;/span&gt;&lt;/span&gt;&lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$this&lt;/span&gt;&lt;/span&gt;.&lt;span class="method"&gt;&lt;span style="color:#8b4513;"&gt;Mainmodul&lt;/span&gt;&lt;/span&gt;...&lt;br /&gt;Path ScriptProperty &lt;span class="namespace"&gt;&lt;span style="color:#8b4513;"&gt;System.Object&lt;/span&gt;&lt;/span&gt; Path {get&lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;=&lt;/span&gt;&lt;/span&gt;&lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$this&lt;/span&gt;&lt;/span&gt;.&lt;span class="namespace"&gt;&lt;span style="color:#8b4513;"&gt;Mainmodule.FileN&lt;/span&gt;&lt;/span&gt;...&lt;br /&gt;Product ScriptProperty &lt;span class="namespace"&gt;&lt;span style="color:#8b4513;"&gt;System.Object&lt;/span&gt;&lt;/span&gt; Product {get&lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;=&lt;/span&gt;&lt;/span&gt;&lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$this&lt;/span&gt;&lt;/span&gt;.&lt;span class="namespace"&gt;&lt;span style="color:#8b4513;"&gt;Mainmodule.Fi&lt;/span&gt;&lt;/span&gt;...&lt;br /&gt;ProductVersion ScriptProperty &lt;span class="namespace"&gt;&lt;span style="color:#8b4513;"&gt;System.Object&lt;/span&gt;&lt;/span&gt; ProductVersion {get&lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;=&lt;/span&gt;&lt;/span&gt;&lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$this&lt;/span&gt;&lt;/span&gt;.&lt;span class="method"&gt;&lt;span style="color:#8b4513;"&gt;Mainmo&lt;/span&gt;&lt;/span&gt;...&lt;/div&gt;
&lt;p&gt;Here, PowerShell has made internal subproperties surface the top level by adding script properties. To see their actual code, try this:&lt;/p&gt;
&lt;div class="pscode"&gt;PS &amp;gt; &lt;span class="verbnoun"&gt;&lt;span style="color:#5f9ea0;"&gt;Get-Process&lt;/span&gt;&lt;/span&gt; | &lt;span class="verbnoun"&gt;&lt;span style="color:#5f9ea0;"&gt;Get-Member&lt;/span&gt;&lt;/span&gt; &lt;span class="modifier"&gt;&lt;span style="color:#5f9ea0;"&gt;-MemberType&lt;/span&gt;&lt;/span&gt; ScriptProperty | &lt;span class="verbnoun"&gt;&lt;span style="color:#5f9ea0;"&gt;Select-Object&lt;/span&gt;&lt;/span&gt; &lt;span class="modifier"&gt;&lt;span style="color:#5f9ea0;"&gt;-ExpandProperty&lt;/span&gt;&lt;/span&gt; Definition&lt;br /&gt;&lt;span class="namespace"&gt;&lt;span style="color:#8b4513;"&gt;System.Object&lt;/span&gt;&lt;/span&gt; Company {get&lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;=&lt;/span&gt;&lt;/span&gt;&lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$this&lt;/span&gt;&lt;/span&gt;.&lt;span class="namespace"&gt;&lt;span style="color:#8b4513;"&gt;Mainmodule.FileVersionInfo.CompanyName&lt;/span&gt;&lt;/span&gt;;}&lt;br /&gt;&lt;span class="namespace"&gt;&lt;span style="color:#8b4513;"&gt;System.Object&lt;/span&gt;&lt;/span&gt; CPU {get&lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;=&lt;/span&gt;&lt;/span&gt;&lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$this&lt;/span&gt;&lt;/span&gt;.&lt;span class="namespace"&gt;&lt;span style="color:#8b4513;"&gt;TotalProcessorTime.TotalSeconds&lt;/span&gt;&lt;/span&gt;;}&lt;br /&gt;&lt;span class="namespace"&gt;&lt;span style="color:#8b4513;"&gt;System.Object&lt;/span&gt;&lt;/span&gt; Description {get&lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;=&lt;/span&gt;&lt;/span&gt;&lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$this&lt;/span&gt;&lt;/span&gt;.&lt;span class="namespace"&gt;&lt;span style="color:#8b4513;"&gt;Mainmodule.FileVersionInfo.FileDescription&lt;/span&gt;&lt;/span&gt;;}&lt;br /&gt;&lt;span class="namespace"&gt;&lt;span style="color:#8b4513;"&gt;System.Object&lt;/span&gt;&lt;/span&gt; FileVersion {get&lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;=&lt;/span&gt;&lt;/span&gt;&lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$this&lt;/span&gt;&lt;/span&gt;.&lt;span class="namespace"&gt;&lt;span style="color:#8b4513;"&gt;Mainmodule.FileVersionInfo.FileVersion&lt;/span&gt;&lt;/span&gt;;}&lt;br /&gt;&lt;span class="namespace"&gt;&lt;span style="color:#8b4513;"&gt;System.Object&lt;/span&gt;&lt;/span&gt; Path {get&lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;=&lt;/span&gt;&lt;/span&gt;&lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$this&lt;/span&gt;&lt;/span&gt;.&lt;span class="namespace"&gt;&lt;span style="color:#8b4513;"&gt;Mainmodule.FileName&lt;/span&gt;&lt;/span&gt;;}&lt;br /&gt;&lt;span class="namespace"&gt;&lt;span style="color:#8b4513;"&gt;System.Object&lt;/span&gt;&lt;/span&gt; Product {get&lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;=&lt;/span&gt;&lt;/span&gt;&lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$this&lt;/span&gt;&lt;/span&gt;.&lt;span class="namespace"&gt;&lt;span style="color:#8b4513;"&gt;Mainmodule.FileVersionInfo.ProductName&lt;/span&gt;&lt;/span&gt;;}&lt;br /&gt;&lt;span class="namespace"&gt;&lt;span style="color:#8b4513;"&gt;System.Object&lt;/span&gt;&lt;/span&gt; ProductVersion {get&lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;=&lt;/span&gt;&lt;/span&gt;&lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$this&lt;/span&gt;&lt;/span&gt;.&lt;span class="namespace"&gt;&lt;span style="color:#8b4513;"&gt;Mainmodule.FileVersionInfo.ProductVersion&lt;/span&gt;&lt;/span&gt;;}&lt;/div&gt;
&lt;p&gt;Note the use of &lt;strong&gt;-expandProperty&lt;/strong&gt; again? Whenever PowerShell &lt;strong&gt;truncates your output&lt;/strong&gt;, use it to pick the contents of the column you are interested in, and you get that information &lt;strong&gt;without truncation&lt;/strong&gt;. Using &lt;strong&gt;Select-Object&lt;/strong&gt; is not a bad thing, it is very useful in many scenarios. It is just not the best way to add new properties to objects as you&amp;#39;ll see in a sec.&lt;/p&gt;
&lt;h3&gt;Creating New ScriptProperties With Add-Member&lt;/h3&gt;
&lt;p&gt;To add version information to file objects without changing the objects, you can add this&amp;nbsp;property using &lt;strong&gt;Add-Member&lt;/strong&gt;. Try this:&lt;/p&gt;
&lt;div class="pscode"&gt;PS &amp;gt; dir &lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$env:windir&lt;/span&gt;&lt;/span&gt;\system32\&lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;*&lt;/span&gt;&lt;/span&gt;.&lt;span class="method"&gt;&lt;span style="color:#8b4513;"&gt;dll&lt;/span&gt;&lt;/span&gt; | &lt;span class="verbnoun"&gt;&lt;span style="color:#5f9ea0;"&gt;Add-Member&lt;/span&gt;&lt;/span&gt; &lt;span class="modifier"&gt;&lt;span style="color:#5f9ea0;"&gt;-MemberType&lt;/span&gt;&lt;/span&gt; ScriptProperty &lt;span style="color:#5f9ea0;"&gt;&lt;span class="modifier"&gt;-Nam&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;e Version &lt;span class="modifier"&gt;&lt;span style="color:#5f9ea0;"&gt;-Value&lt;/span&gt;&lt;/span&gt; { &lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$this&lt;/span&gt;&lt;/span&gt;.&lt;span class="namespace"&gt;&lt;span style="color:#8b4513;"&gt;VersionInfo.FileVersion&lt;/span&gt;&lt;/span&gt; } &lt;span class="modifier"&gt;&lt;span style="color:#5f9ea0;"&gt;-PassThru&lt;/span&gt;&lt;/span&gt; | &lt;span class="verbnoun"&gt;&lt;span style="color:#5f9ea0;"&gt;Select-Object&lt;/span&gt;&lt;/span&gt; Nam&lt;br /&gt;e, Version, Length, CreationTime&lt;br /&gt;&lt;br /&gt;Name Version Length CreationTime&lt;br /&gt;&lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;----&lt;/span&gt;&lt;/span&gt; &lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;-------&lt;/span&gt;&lt;/span&gt; &lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;------&lt;/span&gt;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;&lt;span class="op"&gt;------------&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="namespace"&gt;&lt;span style="color:#8b4513;"&gt;aaclient.dll&lt;/span&gt;&lt;/span&gt; 6.1.7600.16385 (... 158208 14.07.2009 02:17:30&lt;br /&gt;accessibilitycpl... 6.1.7600.16385 (... 3745792 14.07.2009 02:34:00&lt;br /&gt;&lt;span class="namespace"&gt;&lt;span style="color:#8b4513;"&gt;ACCTRES.dll&lt;/span&gt;&lt;/span&gt; 6.1.7600.16385 (... 39424 14.07.2009 01:57:56&lt;br /&gt;(...)&lt;/div&gt;
&lt;p&gt;Here&amp;nbsp;I used &lt;strong&gt;Add-Member&lt;/strong&gt; inside the pipeline to add the script property to the file objects returned by &lt;strong&gt;dir&lt;/strong&gt;. I used the very same script block that I&amp;nbsp;used with &lt;strong&gt;Select-Object&lt;/strong&gt; except for &lt;strong&gt;one major difference&lt;/strong&gt;: when you&amp;nbsp;work with scriptproperties, replace &lt;strong&gt;$_&lt;/strong&gt; by&lt;strong&gt; $this&lt;/strong&gt;.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The result seems to be just the same, so what is the difference compared to using &lt;strong&gt;Select-Object&lt;/strong&gt; with hashtables and scripted properties? &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;span style="text-decoration:line-through;"&gt;Huge&lt;/span&gt; Performance Benefit:&lt;/strong&gt; It is &lt;span style="text-decoration:line-through;"&gt;much&lt;/span&gt; faster.&amp;nbsp;My approach&amp;nbsp;with Select-Object &lt;strong&gt;ran 41 seconds&lt;/strong&gt;.&lt;em&gt;[and the SECOND time I ran it, it ran 3 seconds, so there is a caching effect here]&lt;/em&gt;.&amp;nbsp;This approach with &lt;strong&gt;Add-Member&lt;/strong&gt; just &lt;strong&gt;takes 1 second&lt;/strong&gt;. Thats because &lt;strong&gt;Select-Object&lt;/strong&gt; always has to copy the entire object which is a &lt;span style="text-decoration:line-through;"&gt;very&lt;/span&gt; expensive and ressource-hungry task. &lt;strong&gt;Add-Member&lt;/strong&gt; just leaves the object as-is, and just attaches the new property to it.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Methods:&lt;/strong&gt; For the same reasons, you keep the original objects and all the methods contained in them. &lt;strong&gt;Select-Object&lt;/strong&gt; removes all methods and disconnects the copied object from the real object as well, so any changes to any properties will not&amp;nbsp;do anything to&amp;nbsp;the&amp;nbsp;underlying object anymore.&lt;br /&gt;&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Add-SubProps - Enjoy and Automate!&lt;/h3&gt;
&lt;p&gt;So you now know there can be tons of useful information in subproperties, and you should use &lt;strong&gt;Add-Member&lt;/strong&gt; to make these properties&amp;nbsp;visible. But... isn&amp;#39;t&amp;nbsp;that a bit too hard? Too much code, too much to remember? Right. That&amp;#39;s why I&amp;nbsp;created a function called &lt;strong&gt;Add-SubProps&lt;/strong&gt;. &lt;/p&gt;
&lt;p&gt;All you do is pipe your objects to it and specify the subproperty you would like to append. You can do that multiple times if you want and add&amp;nbsp;the properties of a number of subobjects.&amp;nbsp;It is all automated for you, and it is fast. It even creates read/write ScriptProperties for properties that are writeable. Here is what you can do&amp;nbsp;with this function:&lt;/p&gt;
&lt;div class="pscode"&gt;PS &amp;gt; dir &lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$env:windir&lt;/span&gt;&lt;/span&gt;\system32\&lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;*&lt;/span&gt;&lt;/span&gt;.&lt;span class="method"&gt;&lt;span style="color:#8b4513;"&gt;dll&lt;/span&gt;&lt;/span&gt; | &lt;span class="verbnoun"&gt;&lt;span style="color:#5f9ea0;"&gt;Add-SubProps&lt;/span&gt;&lt;/span&gt; VersionInfo | &lt;span class="verbnoun"&gt;&lt;span style="color:#5f9ea0;"&gt;Select-Object&lt;/span&gt;&lt;/span&gt; Name, ProductVersion, OriginalFileName, FileDescription&lt;br /&gt;&lt;br /&gt;Name ProductVersion OriginalFilename FileDescription&lt;br /&gt;&lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;----&lt;/span&gt;&lt;/span&gt; &lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;--------------&lt;/span&gt;&lt;/span&gt; &lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;----------------&lt;/span&gt;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;&lt;span class="op"&gt;---------------&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="namespace"&gt;&lt;span style="color:#8b4513;"&gt;aaclient.dll&lt;/span&gt;&lt;/span&gt; 6.1.7600.16385 &lt;span class="namespace"&gt;&lt;span style="color:#8b4513;"&gt;aaclient.dll.mui&lt;/span&gt;&lt;/span&gt; Client f&amp;uuml;r Zugri...&lt;br /&gt;accessibilitycpl... 6.1.7600.16385 AccessibilityCpl... Systemsteuerung ...&lt;br /&gt;&lt;span class="namespace"&gt;&lt;span style="color:#8b4513;"&gt;ACCTRES.dll&lt;/span&gt;&lt;/span&gt; 6.1.7600.16385 &lt;span class="namespace"&gt;&lt;span style="color:#8b4513;"&gt;ACCTRES.DLL.MUI&lt;/span&gt;&lt;/span&gt; Microsoft Intern...&lt;br /&gt;&lt;span class="namespace"&gt;&lt;span style="color:#8b4513;"&gt;acledit.dll&lt;/span&gt;&lt;/span&gt; 6.1.7600.16385 &lt;span class="namespace"&gt;&lt;span style="color:#8b4513;"&gt;acledit.dll.mui&lt;/span&gt;&lt;/span&gt; Zugriffssteuerun...&lt;br /&gt;&lt;span class="namespace"&gt;&lt;span style="color:#8b4513;"&gt;aclui.dll&lt;/span&gt;&lt;/span&gt; 6.1.7600.16385 &lt;span class="namespace"&gt;&lt;span style="color:#8b4513;"&gt;aclui.dll.mui&lt;/span&gt;&lt;/span&gt; Sicherheitsdeskr...&lt;br /&gt;&lt;span class="namespace"&gt;&lt;span style="color:#8b4513;"&gt;acppage.dll&lt;/span&gt;&lt;/span&gt; 6.1.7600.16385 &lt;span class="namespace"&gt;&lt;span style="color:#8b4513;"&gt;acppage.dll.mui&lt;/span&gt;&lt;/span&gt; Shellerweiterung...&lt;br /&gt;(...)&lt;/div&gt;
&lt;p&gt;Now isn&amp;#39;t that cool? Simply by piping file objects to Add-SubProps, I was able to access all the additional properties usually only found in the &lt;strong&gt;VersionInfo&lt;/strong&gt; property.&lt;/p&gt;
&lt;p&gt;Here is the &lt;strong&gt;Add-SubProps&lt;/strong&gt; function (&lt;a target="_blank" href="http://powershell.com/cs/media/p/9383.aspx"&gt;you can download it here&lt;/a&gt;):&lt;/p&gt;
&lt;div class="pscode"&gt;&lt;span class="keyword"&gt;&lt;span style="color:#0000ff;"&gt;function&lt;/span&gt;&lt;/span&gt; &lt;span class="verbnoun"&gt;&lt;span style="color:#5f9ea0;"&gt;Add-SubProps&lt;/span&gt;&lt;/span&gt; {&lt;br /&gt;&lt;span class="keyword"&gt;&lt;span style="color:#0000ff;"&gt;param&lt;/span&gt;&lt;/span&gt;(&lt;br /&gt;&lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$prefix&lt;/span&gt;&lt;/span&gt;,&lt;br /&gt;[Parameter(ValueFromPipeline&lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;=&lt;/span&gt;&lt;/span&gt;&lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$true&lt;/span&gt;&lt;/span&gt;)]&lt;br /&gt;&lt;span style="color:#800080;"&gt;&lt;span class="var"&gt;$object&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;process {&lt;br /&gt;&lt;span style="color:#008000;"&gt;&lt;span class="comment"&gt;# Add tag subobject properties:&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$props&lt;/span&gt;&lt;/span&gt; &lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;=&lt;/span&gt;&lt;/span&gt; &lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$object&lt;/span&gt;&lt;/span&gt;.&lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$prefix&lt;/span&gt;&lt;/span&gt; | &lt;span class="verbnoun"&gt;&lt;span style="color:#5f9ea0;"&gt;Get-Member&lt;/span&gt;&lt;/span&gt; &lt;span class="modifier"&gt;&lt;span style="color:#5f9ea0;"&gt;-MemberType&lt;/span&gt;&lt;/span&gt; Property&lt;br /&gt;&lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$props&lt;/span&gt;&lt;/span&gt; | &lt;span class="verbnoun"&gt;&lt;span style="color:#5f9ea0;"&gt;ForEach-Object&lt;/span&gt;&lt;/span&gt; {&lt;br /&gt;&lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$propname&lt;/span&gt;&lt;/span&gt; &lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;=&lt;/span&gt;&lt;/span&gt; &lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$_&lt;/span&gt;&lt;/span&gt;.&lt;span style="color:#8b4513;"&gt;&lt;span class="method"&gt;name&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$writeable&lt;/span&gt;&lt;/span&gt; &lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;=&lt;/span&gt;&lt;/span&gt; &lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$_&lt;/span&gt;&lt;/span&gt;.&lt;span class="method"&gt;&lt;span style="color:#8b4513;"&gt;Definition&lt;/span&gt;&lt;/span&gt; &lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;-like&lt;/span&gt;&lt;/span&gt; &lt;span style="color:#800000;"&gt;&lt;span class="string"&gt;&amp;#39;*{get;set;}*&amp;#39;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$getter&lt;/span&gt;&lt;/span&gt; &lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;=&lt;/span&gt;&lt;/span&gt; [&lt;span class="optional"&gt;&lt;span style="color:#0000ff;"&gt;ScriptBlock&lt;/span&gt;&lt;/span&gt;]::&lt;span class="method"&gt;&lt;span style="color:#8b4513;"&gt;Create&lt;/span&gt;&lt;/span&gt;((&lt;span class="string"&gt;&lt;span style="color:#800000;"&gt;&amp;#39;$this.{0}.{1}&amp;#39;&lt;/span&gt;&lt;/span&gt; &lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;-f&lt;/span&gt;&lt;/span&gt; &lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$prefix&lt;/span&gt;&lt;/span&gt;,&lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$propname&lt;/span&gt;&lt;/span&gt;))&lt;br /&gt;&lt;span class="keyword"&gt;&lt;span style="color:#0000ff;"&gt;if&lt;/span&gt;&lt;/span&gt; (&lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$writeable&lt;/span&gt;&lt;/span&gt;) {&lt;br /&gt;&lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$setter&lt;/span&gt;&lt;/span&gt; &lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;=&lt;/span&gt;&lt;/span&gt; [&lt;span class="optional"&gt;&lt;span style="color:#0000ff;"&gt;ScriptBlock&lt;/span&gt;&lt;/span&gt;]::&lt;span class="method"&gt;&lt;span style="color:#8b4513;"&gt;Create&lt;/span&gt;&lt;/span&gt;((&lt;span class="string"&gt;&lt;span style="color:#800000;"&gt;&amp;#39;param(${1}) $this.{0}.{1} = ${1}&amp;#39;&lt;/span&gt;&lt;/span&gt; &lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;-f&lt;/span&gt;&lt;/span&gt; &lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$prefix&lt;/span&gt;&lt;/span&gt;,&lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$propname&lt;/span&gt;&lt;/span&gt;))&lt;br /&gt;try {&lt;br /&gt;&lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$object&lt;/span&gt;&lt;/span&gt; &lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;=&lt;/span&gt;&lt;/span&gt; &lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$object&lt;/span&gt;&lt;/span&gt; | &lt;span class="verbnoun"&gt;&lt;span style="color:#5f9ea0;"&gt;Add-Member&lt;/span&gt;&lt;/span&gt; &lt;span class="modifier"&gt;&lt;span style="color:#5f9ea0;"&gt;-MemberType&lt;/span&gt;&lt;/span&gt; ScriptProperty &lt;span class="modifier"&gt;&lt;span style="color:#5f9ea0;"&gt;-Name&lt;/span&gt;&lt;/span&gt; &lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$propname&lt;/span&gt;&lt;/span&gt; &lt;span class="modifier"&gt;&lt;span style="color:#5f9ea0;"&gt;-Value&lt;/span&gt;&lt;/span&gt; &lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$getter&lt;/span&gt;&lt;/span&gt; &lt;span class="modifier"&gt;&lt;span style="color:#5f9ea0;"&gt;-SecondValue&lt;/span&gt;&lt;/span&gt; &lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$setter&lt;/span&gt;&lt;/span&gt; &lt;span class="modifier"&gt;&lt;span style="color:#5f9ea0;"&gt;-ea&lt;/span&gt;&lt;/span&gt; Stop &lt;span style="color:#5f9ea0;"&gt;&lt;span class="modifier"&gt;-passthru&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;} catch {}&lt;br /&gt;} &lt;span class="keyword"&gt;&lt;span style="color:#0000ff;"&gt;else&lt;/span&gt;&lt;/span&gt; {&lt;br /&gt;try {&lt;br /&gt;&lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$object&lt;/span&gt;&lt;/span&gt; &lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;=&lt;/span&gt;&lt;/span&gt; &lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$object&lt;/span&gt;&lt;/span&gt; | &lt;span class="verbnoun"&gt;&lt;span style="color:#5f9ea0;"&gt;Add-Member&lt;/span&gt;&lt;/span&gt; &lt;span class="modifier"&gt;&lt;span style="color:#5f9ea0;"&gt;-MemberType&lt;/span&gt;&lt;/span&gt; ScriptProperty &lt;span class="modifier"&gt;&lt;span style="color:#5f9ea0;"&gt;-Name&lt;/span&gt;&lt;/span&gt; &lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$propname&lt;/span&gt;&lt;/span&gt; &lt;span class="modifier"&gt;&lt;span style="color:#5f9ea0;"&gt;-Value&lt;/span&gt;&lt;/span&gt; &lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$getter&lt;/span&gt;&lt;/span&gt; &lt;span class="modifier"&gt;&lt;span style="color:#5f9ea0;"&gt;-ea&lt;/span&gt;&lt;/span&gt; Stop &lt;span style="color:#5f9ea0;"&gt;&lt;span class="modifier"&gt;-passthru&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;} catch {}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;span style="color:#800080;"&gt;&lt;span class="var"&gt;$object&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;}&amp;acute;&lt;br /&gt;}&lt;/div&gt;
&lt;p&gt;If you read my post about &lt;a target="_blank" href="http://powershell.com/cs/blogs/tobias/archive/2011/02/07/reading-and-writing-mpeg-tags-and-attributes-part-2.aspx"&gt;reading and writing MPEG3 tags&lt;/a&gt;, you now know how the module magic was done. The module loaded the DLL that made the functionality available, and then &lt;strong&gt;Add-SubProps&lt;/strong&gt; was used to compose the MPEG3 media objects with all their rich information. Since Add-SubProps leaves the original object untouched and adds read/write script properties, you were able to not just only read audio and video tags, but also change them and save them.&lt;/p&gt;
&lt;p&gt;Add-SubProps is extremely valuable as you will see. For example, when you manage virtual machines with VMWare, Get-VM gets you objects that keep the interesting parts of your virtual machines in objects found in subproperties. You can now easily make them visible. Hope you had fun, see you next week around...&lt;/p&gt;
&lt;p&gt;Tobias&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Microsoft MVP PowerShell Germany&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;P.S.&lt;br /&gt;If you live in Germany or other parts of Europe and your company would like to set up a truly great PowerShell training, just contact me! I regularly train mid- to large-size companies. Trainings are always a blast with tons of real-world-examples and solutions. Here&amp;#39;s how to get in touch with me: &lt;a href="mailto:tobias.weltner@scriptinternals.de"&gt;&lt;span style="color:#3366cc;"&gt;tobias.weltner@scriptinternals.de&lt;/span&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://powershell.com/cs/aggbug.aspx?PostID=9384" width="1" height="1"&gt;</description><category domain="http://powershell.com/cs/blogs/tobias/archive/tags/Select-Object/default.aspx">Select-Object</category><category domain="http://powershell.com/cs/blogs/tobias/archive/tags/performance/default.aspx">performance</category><category domain="http://powershell.com/cs/blogs/tobias/archive/tags/ScriptProperty/default.aspx">ScriptProperty</category><category domain="http://powershell.com/cs/blogs/tobias/archive/tags/Properties/default.aspx">Properties</category><category domain="http://powershell.com/cs/blogs/tobias/archive/tags/Add-Props/default.aspx">Add-Props</category><category domain="http://powershell.com/cs/blogs/tobias/archive/tags/Add-Member/default.aspx">Add-Member</category></item></channel></rss>