Howdy, am trying to copy a file from IE cache to somewhere else. This works on w7, but not Vista Ultimate.
In short:
copy-item $f -Destination "$targetDir" -force
(I also tried $f.fullname)
The full script:
$targetDir = "C:\temp"
$ieCache=(get-itemproperty "hkcu:\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders").cache
$minSize = 5mb
Write-Host "minSize:" $minSize
Add-Content -Encoding Unicode -Path $targetDir"\log.txt" -Value (get-Date)
Set-Location $ieCache
#\Low\Content.IE5 for protected mode
#\content.ie5 for unprotected
$a = Get-Location
foreach ($f in
(get-childitem -Recurse -Force -Exclude *.dat, *.tmp | where {$_.length -gt $minSize})
)
{
Write-Host (get-Date) $f.Name $f.length
Add-Content -Encoding Unicode -Path $targetDir"\log.txt" -Value $f.name, $f.length
copy-item $f -Destination "$targetDir" -force
}
End of wisdom. Please help!
Anytime you're having problems trying to figure out why a parameter doesn't bind correctly in PowerShell, use Trace-Command like so:
Trace-Command -Name ParameterBinding -expr { copy-item $f foo.cat.bak } -PSHost
In this case, it works for me. Perhaps this is a "feature" of PowerShell 2.0 but you can see it attempt to bind several different times before it hits on:
COERCE arg to [System.String]
Trying to convert argument value from System.Management.Automation.PSObject to System.String
CONVERT arg type to param type using LanguagePrimitives.ConvertTo
CONVERT SUCCESSFUL using LanguagePrimitives.ConvertTo: [C:\Users\Keith\foo.cat]
The way this normally works when the FileInfo objects are passed via the pipeline, they bind by "PropertyName" to the LiteralPath parameter. I know, you're probably wondering, uh didn't think System.IO.FileInfo had a LiteralPath property. Heheh, it doesn't. Those tricky PowerShell folks snuck a PSPath alias onto the LiteralPath parameter and PowerShell "adapts" each the FileInfo object to add a number of PS* properties including PSPath. So if you wanted to "literally" match the pipelining behavior you would use:
Copy-Item -LiteralPath $f.PSPath $targetDir -force
Note that you don't have to quote $targetDir in this case (as a parameter argument).
The reason why copy-item
doesn't work is that you pass System.IO.FileInfo
as parameter -path
.
There are two possibilities how to do it correctly:
copy-item -literal $f.Fullname -destination ...
$f | copy-item -destination ...
Note that I use parameter -literalPath
because files in the temp folder have usually [
and ]
inside the name which acts as wildcards characters.
If you wonder why case #2 works, have a look at 'help Copy-Item -Parameter Path`, you will see Accept pipeline input? true (ByValue, ByPropertyName). For more info what it means look at Keith's ebook Effective Windows PowerShell.
Why you version doesn't work? Because paramerer -path
(which is at position 1) takes input of type [string[]]
and not FileInfo
. So PowerShell tried to convert it to [string]
(and then to the array) but it probably used only Name
property. You can try it like this:
[string[]] (gci | select -first 1)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With