{"id":11021,"date":"2006-04-25T12:17:38","date_gmt":"2006-04-25T12:17:38","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/powershell\/2006\/04\/25\/introduction-to-mshobject\/"},"modified":"2019-02-18T13:25:10","modified_gmt":"2019-02-18T20:25:10","slug":"introduction-to-mshobject","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/powershell\/introduction-to-mshobject\/","title":{"rendered":"Introduction to MshObject"},"content":{"rendered":"<p>If you\u2019ve ever worked with the Monad APIs then you\u2019ve no doubt seen a type called System.Management.Automation.MshObject.&nbsp; I\u2019m not going to go into all the details of what it is because that would take me more time than I have right now and there are people who can explain better than I.&nbsp; Suffice it to say that it\u2019s a wrapper class and that all those objects you are using in MSH are wrapped by an instance of MshObject.&nbsp;&nbsp; And because the objects are wrapped by an MshObject you can add extra information to them.&nbsp; For example, if you look closely you\u2019ll see that the FileInfo objects returned by get-childitem have extra information attached.<\/p>\n<p>&nbsp;<\/p>\n<p>MSH&gt;dir | get-member<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;&nbsp;&nbsp; TypeName: System.IO.FileInfo<\/p>\n<p>&nbsp;<\/p>\n<p>Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MemberType&nbsp;&nbsp;&nbsp;&nbsp; Definition<\/p>\n<p>&#8212;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8212;&#8212;-&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8212;&#8212;-<\/p>\n<p>AppendText&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.IO.StreamWriter AppendText()<\/p>\n<p>.<\/p>\n<p>.<\/p>\n<p>.<\/p>\n<p>ToString&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.String ToString()<\/p>\n<p>MshChildName&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NoteProperty&nbsp;&nbsp; System.String MshChildName=Add-Note.msh<\/p>\n<p>MshDrive&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NoteProperty&nbsp;&nbsp; System.Management.Automation.DriveInfo MshDrive=C<\/p>\n<p>MshIsContainer&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NoteProperty&nbsp;&nbsp; System.Boolean MshIsContainer=False<\/p>\n<p>MshParentPath&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NoteProperty&nbsp;&nbsp; System.String MshParentPath=FileSystem::C:\\monad\\ScriptTools<\/p>\n<p>MshPath&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NoteProperty&nbsp;&nbsp; System.String MshPath=FileSystem::C:\\monad\\ScriptTools\\Add-Note.msh<\/p>\n<p>MshProvider&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NoteProperty&nbsp;&nbsp; System.Management.Automation.ProviderInfo MshProvider=System.Management.Aut&#8230;<\/p>\n<p>Attributes&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Property&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.IO.FileAttributes Attributes {get;set;}<\/p>\n<p>.<\/p>\n<p>.<\/p>\n<p>.<\/p>\n<p>Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Property&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.String Name {get;}<\/p>\n<p>Mode&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ScriptProperty System.Object Mode {get=$catr = &#8220;&#8221;;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>Besides the regular methods and properties on the object you can see there are members called NoteProperty and ScriptProperty.&nbsp; Notes are like fields and properties well\u2026 like properties (they can have both a getter and a setter scriptblocks).&nbsp; Now that you know they are there you can go ahead and use them in your scripts.&nbsp; For example, say you wanted to get all the directories.&nbsp; Well, that note called MshIsContainer sounds like it might help.<\/p>\n<p>&nbsp;<\/p>\n<p>MSH&gt;dir | where { $_.MshIsContainer }<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;&nbsp;&nbsp; Directory: FileSystem::C:\\WINDOWS<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>Mode&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LastWriteTime&nbsp;&nbsp;&nbsp;&nbsp; Length Name<\/p>\n<p>&#8212;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8212;&#8212;&#8212;-&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8212; &#8212;-<\/p>\n<p>d&#8212;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 7\/23\/2004&nbsp;&nbsp; 6:56 AM&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; addins<\/p>\n<p>.<\/p>\n<p>.<\/p>\n<p>.<\/p>\n<p>d-r&#8211;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2\/15\/2005&nbsp;&nbsp; 5:39 PM&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Web<\/p>\n<p>d&#8212;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6\/6\/2005&nbsp;&nbsp; 6:42 PM&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WinSxS<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>Perfect.&nbsp; We got the containers.&nbsp; Go ahead and check out the rest of the notes and properties.&nbsp; BTW, some of these notes are there to help cmdlets play nice with each other so be careful about changing their value.&nbsp; So where did these notes come from?&nbsp; Well, there are various ways that notes can get attached to your object.<\/p>\n<p>Programatically.&nbsp; A cmdlet has access to the MshObject and can add notes to it using the Members property. <br \/>Types.mshxml.&nbsp; Using types.mshxml you can define scriptmethods, scriptproperties and notes for particular types of objects. <br \/>Once you know the secret code, you can add them yourself!!!!&nbsp; Later on I\u2019ll show you some scripts that make use of notes. <br \/>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>We can dive into types.mshxml at some other time (it\u2019s a big topic)&nbsp; but I encourage you to go and take a look at the file.&nbsp; Look for NoteProperty, ScriptProperty, AliasProperty (These are just aliases to another property.&nbsp; Arrays have aliased Count to Length).&nbsp; <\/p>\n<p>&nbsp;<\/p>\n<p>So how would you go about adding notes to your objects?&nbsp; Next time I\u2019ll show you an example of a filter that does it.&nbsp; Before I finish though let me mention three things so you can start playing around with MshObjects.<\/p>\n<p>&nbsp;<\/p>\n<p>MshObject <br \/>MshBase <br \/>MshExtended <br \/>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>Remember those three.&nbsp; Those three properties are on every object you use in Msh.&nbsp; They are usually invisible and won\u2019t show up via get-member but if you know the magic words you can access them.&nbsp; MshObject will give you a reference to the MshObject wrapping that object.&nbsp; MshBase will give you a reference to the object being wrapped without all the notes, scriptproperties, etc.&nbsp; And MshExtended will only return the extensions.&nbsp; To take a look go ahead and do the following:<\/p>\n<p>&nbsp;<\/p>\n<p>MSH&gt;$a = (dir)[0]<\/p>\n<p>MSH&gt;$a.MshObject.Gettype().FullName<\/p>\n<p>System.Management.Automation.MshObject<\/p>\n<p>MSH&gt;$a.MshObject | get-member<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;&nbsp;&nbsp; TypeName: System.Management.Automation.MshMemberSet<\/p>\n<p>&nbsp;<\/p>\n<p>Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MemberType Definition<\/p>\n<p>&#8212;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8212;&#8212;- &#8212;&#8212;&#8212;-<\/p>\n<p>Copy&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp; System.Management.Automation.MshObject Copy()<\/p>\n<p>Equals&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp; System.Boolean Equals(Object obj)<\/p>\n<p>get_BaseObject Method&nbsp;&nbsp;&nbsp;&nbsp; System.Object get_BaseObject()<\/p>\n<p>get_Members&nbsp;&nbsp;&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp; System.Management.Automation.MshMemberInfoCollection get_Members()<\/p>\n<p>get_Methods&nbsp;&nbsp;&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp; System.Management.Automation.MshMemberInfoCollection get_Methods()<\/p>\n<p>get_Properties Method&nbsp;&nbsp;&nbsp;&nbsp; System.Management.Automation.MshMemberInfoCollection get_Properties()<\/p>\n<p>get_TypeNames&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp; System.Collections.ObjectModel.Collection`1[[System.String, mscorlib, Version=2.0.0.0, Cul&#8230;<\/p>\n<p>GetHashCode&nbsp;&nbsp;&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp; System.Int32 GetHashCode()<\/p>\n<p>GetType&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp; System.Type GetType()<\/p>\n<p>ToString&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp; System.String ToString(), System.String ToString(String format, IFormatProvider formatProv&#8230;<\/p>\n<p>BaseObject&nbsp;&nbsp;&nbsp;&nbsp; Property&nbsp;&nbsp; System.Object BaseObject {get;}<\/p>\n<p>Members&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Property&nbsp;&nbsp; System.Management.Automation.MshMemberInfoCollection Members {get;}<\/p>\n<p>Methods&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Property&nbsp;&nbsp; System.Management.Automation.MshMemberInfoCollection Methods {get;}<\/p>\n<p>Properties&nbsp;&nbsp;&nbsp;&nbsp; Property&nbsp;&nbsp; System.Management.Automation.MshMemberInfoCollection Properties {get;}<\/p>\n<p>TypeNames&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Property&nbsp;&nbsp; System.Collections.ObjectModel.Collection`1[[System.String, mscorlib, Version=2.0.0.0, Cul&#8230;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>MSH&gt;$a.MshBase.Gettype().FullName<\/p>\n<p>System.IO.FileInfo<\/p>\n<p>MSH&gt;$a.MshBase | get-member<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;&nbsp;&nbsp; TypeName: System.Management.Automation.MshMemberSet<\/p>\n<p>&nbsp;<\/p>\n<p>Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MemberType Definition<\/p>\n<p>&#8212;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8212;&#8212;- &#8212;&#8212;&#8212;-<\/p>\n<p>AppendText&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp; System.IO.StreamWriter AppendText()<\/p>\n<p>.<\/p>\n<p>.<\/p>\n<p>.<\/p>\n<p>Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Property&nbsp;&nbsp; System.String Name {get;}<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;&nbsp;&nbsp; TypeName: System.Management.Automation.MshMemberSet<\/p>\n<p>&nbsp;<\/p>\n<p>Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MemberType&nbsp;&nbsp;&nbsp;&nbsp; Definition<\/p>\n<p>&#8212;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8212;&#8212;-&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8212;&#8212;-<\/p>\n<p>MshChildName&nbsp;&nbsp; NoteProperty&nbsp;&nbsp; System.String MshChildName=about_Alias.help.txt<\/p>\n<p>.<\/p>\n<p>.<\/p>\n<p>.<\/p>\n<p>Mode&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ScriptProperty System.Object Mode {get=$catr = &#8220;&#8221;;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>MSH&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>&#8211; Marcel<\/p>\n<p>&nbsp;<\/p>\n<p>[<i>Edit: Monad has now been renamed to Windows PowerShell.  This script or discussion may require slight adjustments before it applies directly to newer builds.<\/i>]<\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you\u2019ve ever worked with the Monad APIs then you\u2019ve no doubt seen a type called System.Management.Automation.MshObject.&nbsp; I\u2019m not going to go into all the details of what it is because that would take me more time than I have right now and there are people who can explain better than I.&nbsp; Suffice it to [&hellip;]<\/p>\n","protected":false},"author":600,"featured_media":13641,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-11021","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-powershell"],"acf":[],"blog_post_summary":"<p>If you\u2019ve ever worked with the Monad APIs then you\u2019ve no doubt seen a type called System.Management.Automation.MshObject.&nbsp; I\u2019m not going to go into all the details of what it is because that would take me more time than I have right now and there are people who can explain better than I.&nbsp; Suffice it to [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts\/11021","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/users\/600"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/comments?post=11021"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts\/11021\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/media\/13641"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/media?parent=11021"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/categories?post=11021"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/tags?post=11021"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}