Reputation: 8497
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
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:
(Get-Command Get-ChildItem).OutputType
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:
[object[]]
(even though the actual elements have specific types).$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:
[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
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