Lesson Learned Today about PowerShell’s .Net Type System

Today I was asked why this person saw more properties showing with a “format-table”, than with a “format-table *”.  I will admit, I wasn't sure.  I kicked myself later once I got the answer and I realized I should have known this.  There is a PFE colleague of mine that always seems to be AMAZING at answering our questions when we ask them.  He took maybe 30 minutes to school me on this.

Here is an example of what I am talking about:

PS C:\> (resolve-path HKLM:\SOFTWARE\Microsoft).provider | format-list *
ImplementingType : Microsoft.PowerShell.Commands.RegistryProvider
HelpFile         : System.Management.Automation.dll-Help.xml
Name             : Registry
PSSnapIn         : Microsoft.PowerShell.Core
Description      :
Capabilities     : ShouldProcess
Home             :
Drives           : {HKLM, HKCU}

PS C:\> (resolve-path HKLM:\SOFTWARE\Microsoft).provider | format-list
Name             : Registry
Drives           : {HKLM, HKCU}
Path             :
Home             :
Description      :
Capabilities     : ShouldProcess
ImplementingType : Microsoft.PowerShell.Commands.RegistryProvider
AssemblyInfo     :

You’ll notice that in the second try, that there is a property showing that is called “assemblyinfo” that doesn't show in the first.  I always though that a format-list * should show everything.


Here is Rich Doyle’s response to me when I asked this (Rich is a PFE like me):

If you weren't aware, the default formatting for viewing of types are defined in the following files:

PS C:\> get-childitem $pshome\*.ps1xml

    Directory: Microsoft.PowerShell.Core\FileSystem::C:\Windows\System32\WindowsPowerShell\v1.0

Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---        11/21/2006  11:47 AM      22120 Certificate.format.ps1xml
-a---        11/21/2006  11:47 AM      60703 DotNetTypes.format.ps1xml
-a---        11/21/2006  11:47 AM      19730 FileSystem.format.ps1xml
-a---        11/21/2006  11:47 AM     250197 Help.format.ps1xml
-a---        11/21/2006  11:47 AM      65283 PowerShellCore.format.ps1xml
-a---        11/21/2006  11:47 AM      13394 PowerShellTrace.format.ps1xml
-a---        11/21/2006  11:47 AM      13540 Registry.format.ps1xml
-a---        11/21/2006  11:47 AM     129836 types.ps1xml

If you look inside of PowerShellCore.format.ps1xml you will find the following view definition for System.Management.Automation.ProviderInfo:


Now, looking at an object of type System.Management.Automation.ProviderInfo using Get-Member we can see all of the Properties that are available on the object:

PS C:\>  (resolve-path HKLM:\SOFTWARE\Microsoft).provider | get-member

   TypeName: System.Management.Automation.ProviderInfo

Name                 MemberType Definition
----                 ---------- ----------
Equals               Method     System.Boolean Equals(Object obj)
GetHashCode          Method     System.Int32 GetHashCode()
GetType              Method     System.Type GetType()
get_Capabilities     Method     System.Management.Automation.Provider.ProviderCapabilities get_Capabilities()
get_Description      Method     System.String get_Description()
get_Drives           Method     System.Collections.ObjectModel.Collection`1[[System.Management.Automation.PSDriveInf...
get_HelpFile         Method     System.String get_HelpFile()
get_Home             Method     System.String get_Home()
get_ImplementingType Method     System.Type get_ImplementingType()
get_Name             Method     System.String get_Name()
get_PSSnapIn         Method     System.Management.Automation.PSSnapInInfo get_PSSnapIn()
set_Description      Method     System.Void set_Description(String value)
set_Home             Method     System.Void set_Home(String value)
ToString             Method     System.String ToString()
Capabilities         Property   System.Management.Automation.Provider.ProviderCapabilities Capabilities {get;}
Description          Property   System.String Description {get;set;}
Drives               Property   System.Collections.ObjectModel.Collection`1[[System.Management.Automation.PSDriveInf...
HelpFile             Property   System.String HelpFile {get;}
Home                 Property   System.String Home {get;set;}
ImplementingType     Property   System.Type ImplementingType {get;}
Name                 Property   System.String Name {get;}
PSSnapIn             Property   System.Management.Automation.PSSnapInInfo PSSnapIn {get;}

As we can see, AssemblyInfo is actually not a property of the object.

So, what is happening here is:

(resolve-path HKLM:\SOFTWARE\Microsoft).provider | format-list *

Piping the output to format-list * assumes inherent usage of the properties switch, and, just as with Get-Member enumerating properties, format-list is reading all of the properties from the object returning a nice list of their names and values - correct behavior.

(resolve-path HKLM:\SOFTWARE\Microsoft).provider | format-list

Piping the output to format-list (no properties or properties wildcard) invokes the default View definition in PowerShellCore.format.ps1xml, which enumerates what is defined and the values of those Properties, formatting them in a list.

This, again, is the correct behavior, it's just that the default View contains the property AssemblyInfo that is not present on this instance of this System.Management.Automation.ProviderInfo object.  Therefore, we see the property showing in the result, of course with no value as the property is not really there.  This is exactly how the .Net Type system is supposed to work, just the same as if you typed “format-list name,assemblyinfo”, which would show the empty looking property.

Thanks Rich for your response!


This posting is provided "AS IS" with no warranties, and confers no rights. Use of included script samples are subject to the terms specified at http://www.microsoft.com/info/cpyright.htm.

Comments (0)

Skip to main content