1

In PowerShell 2, you are not able to index into System.IO.FileInfo objects as you are in PowerShell 5. For example, in PowerShell 5, you can do:

PS C:\test> mkdir test


    Directory: C:\test\test


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----        7/20/2018     18:10                test


PS C:\test> echo "test" > test\test
PS C:\test> $foo = (Get-Item test\*)
PS C:\test> $foo.Count
1
PS C:\test> $foo[0]


    Directory: C:\test\test


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----        7/20/2018     18:10             14 test


PS C:\test> $foo[0].Name
test

However, in PowerShell 2, the same behaves very differently:

PS C:\test> mkdir test


    Directory: C:\test


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
d----         7/20/2018   6:14 PM            test


PS C:\test> echo "test" > test\test
PS C:\test> $foo = (Get-Item test\*)
PS C:\test> $foo.Count
PS C:\test> $foo[0]
Unable to index into an object of type System.IO.FileInfo.
At line:1 char:6
+ $foo[ <<<< 0]
    + CategoryInfo          : InvalidOperation: (0:Int32) [], RuntimeException
    + FullyQualifiedErrorId : CannotIndex

PS C:\test> $foo[0].name
Unable to index into an object of type System.IO.FileInfo.
At line:1 char:6
+ $foo[ <<<< 0].name
    + CategoryInfo          : InvalidOperation: (0:Int32) [], RuntimeException
    + FullyQualifiedErrorId : CannotIndex

This makes writing backwards-compatible scripts difficult. Is there a simple way to add indexability to the System.IO.FileInfo object in PowerShell 2 as it exists in PowerShell 5? Or at the very least, an elegant way to loop through the results of Get-Item when it only returns one item, in PowerShell 2?

jdgregson
  • 1,457
  • 17
  • 39
  • 6
    `(Get-Item test\*)` -> `@(Get-Item test\*)` – user4003407 Jul 21 '18 at 01:38
  • @PetSerAl, Welp, that's pretty straight forward. Thanks! – jdgregson Jul 21 '18 at 01:45
  • 1
    Note that this issue was resolved in PowerShell 3, so 3 and 4 both work like 5. – Bacon Bits Jul 21 '18 at 02:28
  • For the backstory, see this near-duplicate: https://stackoverflow.com/q/44035319/45375 – mklement0 Jul 21 '18 at 02:42
  • 1
    "The use of @(...), the array subexpression operator, ensures that whatever the enclosed command outputs is treated as an array, even if only 1 object is output" -- it's exactly what I needed, and probably will continue to use until Windows 7 goes away. – jdgregson Jul 21 '18 at 02:53
  • You know you can install PowerShell 5.1 on Windows 7, right? You don't get all the new commands, but the updated syntax works great. – Bacon Bits Jul 21 '18 at 04:05
  • Yes, I do know that, and encourage users to do so on all of my repositories. However, if a script _can_ be compatible back to 2.0, I'd prefer to support it. – jdgregson Jul 21 '18 at 05:40
  • In PowerShell 2, you always had to care whether you got a single item back from a cmdlet, or a collection of multiple items. Because that was frustrating, this behaviour you ask about in your question was added to PSv3 to help mitigate it, and now you can call `[0]` on any object, not just `system.io.fileinfo`, and PS will pretend as if you had an array with that one thing in it, and "return the first thing". i.e. do nothing/not throw an error. It's mildly amusing to see you asking in 2018 how you can retro-fit it back into PowerShell 2009. – TessellatingHeckler Jul 22 '18 at 05:55
  • @TessellatingHeckler That's some good information, thanks for the explanation. And yeah, I usually just give up and suggest users upgrade to PowerShell v5 to run my scripts, but the on I'm working on now doesn't explicitly require any v3+ features, so why not throw Windows 7 a bone without the need to install an update? I mean, we still have 1.5 years of extended support for Windows 7, plus the 3-5 years it will take some parts of the world to move on. – jdgregson Jul 22 '18 at 16:18

0 Answers0