Reputation: 109
Need a little help to tweak this script that copies the latest file to another folder:
$FilePath = "C:\Downloads\Sales 202112*.xlsx"
$DestinationPath = "C:\myFiles\"
gci -Path $FilePath -File |
Sort-Object -Property LastWriteTime -Descending |
Select FullName -First 1 |
Copy-Item $_ -Destination $DestinationPath
Not sure how to reference pipeline input for the Copy-Item command.
Thanks.
Upvotes: 1
Views: 403
Reputation: 437080
tl;dr
Get-ChildItem -Path $FilePath -File |
Sort-Object -Property LastWriteTime -Descending |
Select-Object -First 1 | # Note: No 'FullName'
Copy-Item -Destination $DestinationPath # Note: No '$_'
The simplest and most robust approach is to pipe Get-ChildItem
/ Get-Item
output as-is to other file-processing cmdlets, which binds to the latter's -LiteralPath
parameter, i.e the input file path.
As for what you tried:
The automatic $_
variable, which explicitly refers to the pipeline input object at hand, is only needed (and supported) inside script blocks ({ ... }
) passed to cmdlets.
With suitable pipeline input, PowerShell implicitly binds it to a pipeline-binding parameter of the target cmdlet, which in case of the Copy-Item
call above is -LiteralPath
. In other words: specifying a value for the target parameter as an argument isn't necessary.
This answer explains the mechanism that binds the System.IO.FileInfo
and System.IO.DirectoryInfo
instances that Get-ChildItem
outputs to the -LiteralPath
parameter of file-processing cmdlets such as Copy-Item
.
Note that, with FullName
out of the picture (see below), it is indeed a System.IO.FileInfo
instance that Copy-Item
receives as pipeline input, because the Sort-Object ...
and Select-Object -First 1
calls above pass them through without changing their type.
Selecting the FullName
property in an attempt to pass only the file's full path (as a string) via the pipeline is unnecessary, and, more importantly:
-ExpandProperty FullName
to ensure that only the property value is output; without it, you get an object that has a .FullName
property - see this answer for more information.System.IO.FileInfo
instances as a whole: mere string input binds to the -Path
rather than the -LiteralPath
parameter, which means that what is by definition a literal path is interpreted as a wildcard expression, which notably causes mishandling of literal paths that contain [
characters (e.g. c:\foo\file[1].txt
).Upvotes: 1