Thufir
Thufir

Reputation: 8497

return array of objects from Get-ChildItem -Path

From powershell, ls -R *.txt will list files recursively by directory, or, even better:

PS> Get-ChildItem -Path C:\Test -Name

logs

anotherfile.txt
Command.txt
CreateTestFile.ps1
ReadOnlyFile.txt

but how do I feed this into an array? I would like an array of the file (?) object itself, looking at:

Get-ChildItem "C:\WINDOWS\System32" *.txt -Recurse | Select-Object FullName

https://stackoverflow.com/a/24468733/262852

I'm looking for an array of "file" objects with powershell from these types of commands.

probably better syntax:

Copy-Item -Filter *.txt -Path c:\data -Recurse -Destination C:\temp\text

but rather than copy the items, I just want an object, or rather, array of objects. Not the path to a file, not the file, but, presumably, a powershell reference or pointer to a file.

(Reading the fine manual now.)

Upvotes: 5

Views: 9180

Answers (2)

mklement0
mklement0

Reputation: 439692

tl;dr

  • When you capture a PowerShell statement's output in a variable (e.g.,
    $output = Get-ChildItem ...), it is automatically collected in an array if there are two or more output objects.

  • To ensure that an array is always used - even with only a single or no output object - use @(...) (e.g.,
    $output = @(Get-ChildItem ...))


  • PowerShell cmdlets, such as Get-ChildItem, can output any number of objects.

    • Get-ChildItem outputs [System.IO.FileInfo] and/or [System.IO.DirectoryInfo] objects, depending on whether information about files and/or directories is being output.

    • To determine a given cmdlet's output-object types:

      • Run, e.g., (Get-Command Get-ChildItem).OutputType
      • If that doesn't work, or to see what types are output for a specific invocation, use
        Get-ChildItem | Get-Member.
      • Get-Help -Full Get-ChildItem should show an OUTPUTS section as well, as does the online help, though not that in the case of Get-ChildItem it is less specific, since Get-ChildItem also works with providers other than the filesystem.
  • When output to the pipeline, each output object is passed individually to the next command in the pipeline for typically immediate processing.

  • When output is captured in a variable ($var = ...), the following logic applies:

    • If two or more objects are output, they are collected in a regular PowerShell array, which is of type [object[]] (even though the actual elements have specific types).
    • If one object is output, it is output as-is; that is, it is not wrapped in an array.
    • If no objects are output, an "array-valued null" is output (sometimes called "AutomationNull" for its type name), which in expression contexts behaves like $null and in enumeration contexts like an empty collection; it results in no visible output - see this answer for details.

Therefore, when captured in a variable, a given command may situationally return:

  • an array of objects
  • a single object
  • "nothing" ([System.Management.Automation.Internal.AutomationNull]::Value)

To ensure that a given command's output is always treated as an array, you have two options:

  • Use @(...), the array subexpression operator; e.g.

    • $fileSystemObjects = @(Get-ChildItem -Recurse -Filter *.txt)
  • Type-constrain the target variable with [array] (which is equivalent to, and easier to type than, [object[]]).

    • [array] $fileSystemObjects = Get-ChildItem -Recurse -Filter *.txt

That said, in PSv3+ you often need not worry about whether a given variable contains a scalar (single value) or an array, because scalars can implicitly be treated like arrays: you can call .Count even on scalars, and use indexing ([0], [-1]) - see this answer for details.

Upvotes: 10

ArcSet
ArcSet

Reputation: 6860

Get-ChildItem "C:\test" -Recurse will return an array of FileInfo and DirectoryInfo objects inside an array

We can see an a example showing that here

Get-ChildItem "C:\test" -Recurse | %{
    $_.gettype()
}

Returns

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     DirectoryInfo                            System.IO.FileSystemInfo
True     True     DirectoryInfo                            System.IO.FileSystemInfo
True     True     FileInfo                                 System.IO.FileSystemInfo
True     True     DirectoryInfo                            System.IO.FileSystemInfo

Upvotes: 3

Related Questions