question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Directly constructed .NET type instances lack properties that ones output by cmdlets have

See original GitHub issue

Update: See also this later proposal to provide the provider properties via class-backed CodeProperty members rather than per-instance NoteProperty members.


From what I can tell, this discrepancy has always existed, so there may be a good reason for it, but it deserves an explanation / documentation.

Specifically, where do the extra properties come from? They appear not to be part of the ETS type data as returned by Get-TypeData System.IO.DirectoryInfo (and there’s also none for the parent type, Get-TypeData System.IO.FileSystemInfo).

The absence of the .PSPath property from the directly constructed [System.IO.DirectoryInfo] and [System.IO.FileInfo] instances is especially problematic, because pipeline-binding to -LiteralPath parameters is based on it.

The types used are just an example; the same discrepancy exists for other types, such as [datetime]::now vs. Get-Date.

Steps to reproduce

# Construct  seemingly identical [System.IO.DirectoryInfo] instances
([System.IO.DirectoryInfo] '/').psextended | Format-List
'---'
(Get-Item '/').psextended | Format-List

Expected behavior

PSPath        : Microsoft.PowerShell.Core\FileSystem::/
PSParentPath  : 
PSChildName   : 
PSDrive       : /
PSProvider    : Microsoft.PowerShell.Core\FileSystem
PSIsContainer : True
Mode          : d-r---
BaseName      : /
Target        : 
LinkType      : 

---

PSPath        : Microsoft.PowerShell.Core\FileSystem::/
PSParentPath  : 
PSChildName   : 
PSDrive       : /
PSProvider    : Microsoft.PowerShell.Core\FileSystem
PSIsContainer : True
Mode          : d-r---
BaseName      : /
Target        : 
LinkType      : 

Actual behavior

Mode     : d-r---
BaseName : /
Target   : 
LinkType : 

---

PSPath        : Microsoft.PowerShell.Core\FileSystem::/
PSParentPath  : 
PSChildName   : 
PSDrive       : /
PSProvider    : Microsoft.PowerShell.Core\FileSystem
PSIsContainer : True
Mode          : d-r---
BaseName      : /
Target        : 
LinkType      : 

As you can see, the PS-prefixed properties only exist on the instance output by Get-Item.

Environment data

PowerShell Core v6.0.0-beta.4 on macOS 10.12.5
PowerShell Core v6.0.0-beta.4 on Ubuntu 16.04.2 LTS
PowerShell Core v6.0.0-beta.4 on Microsoft Windows 10 Pro (64-bit; v10.0.15063)
Windows PowerShell v5.1.15063.413 on Microsoft Windows 10 Pro (64-bit; v10.0.15063)

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:2
  • Comments:24 (14 by maintainers)

github_iconTop GitHub Comments

7reactions
lzybkrcommented, Oct 31, 2018

@SteveL-MSFT describes a current pattern, but it doesn’t make it a good pattern.

To use the Get-Process example, I think Get-Process -IncludeUserName is a bit gross. UserName seems important enough that it should always be available on a Process object, and ETS was designed for just that scenario.

If I want the user name in the output, then I’d rather see Get-Process | Format-Table -View ProcessWithUserName or something like that.

To expand a bit on how we abuse ETS unnecessarily in the name of formatting, I’ll point out an idea first introduced by @KirkMunro in FormatPx.

The basic idea is that formatting directives are attached to an object without relying on the typename. This has the benefit of binding your formats in a script, e.g.:

function Get-Process
{
    # Use a very basic default format
    [System.Diagnostics.Process]::GetProcesses() | Format-Table Id,ProcessName
}

And use the function like this:

PS> $x = Get-Process
PS> $x[0].ProcessName
cmd
PS> $x

Id  ProcessName
==  ===========
11  cmd
22  powershell

PS> $x | Format-Table Id,SI,ProcessName

Id  SI  ProcessName
==  ==  ===========
11   1  cmd
22   2  powershell

So in this example, my function Get-Process fully specifies the default formatting while writing instances of System.Diagnostics.Process that can be used normally and later have a different format applied.

FormatPx works like this using the existing format system, and I’ve implemented this idea in PSMore which is just barely functional as a prototype.

In summary, I’d like to see PowerShell move away from adding members to each instance and use type members as much as possible. I think this would be a win from a performance and usability point of view.

3reactions
vexx32commented, Oct 31, 2018

I would love to see the Format cmdlets work like that – still return usable objects, just with the formatting directives altered – wow!

That would save a significant amount of confusion for newbies, give us a way to simply and easily specify default formats programatically, the whole deal. Love it!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Differences between Windows PowerShell 5.1 and ...
NET Core. This article summarizes the significant differences and breaking changes between Windows PowerShell and the current version of ...
Read more >
Select the values of one property on all objects of an array ...
Accessing a property at the collection level to get its elements' values as an array (if there are 2 or more elements) is...
Read more >
Windows PowerShell Cheat Sheet
All cmdlets return one or more objects into a pipeline (see below). At the end of a pipeline some selected properties of the...
Read more >
What is a Cmdlet and How Does It Work?
Cmdlets are based on .NET classes and rely on the use of .NET objects. Thus, cmdlets can receive objects as input and deliver...
Read more >
PowerShell - Wikipedia
Windows PowerShell can execute four kinds of named commands: cmdlets (.NET Framework programs designed to interact with PowerShell); PowerShell scripts (files ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found