2010-03-20 6 views
3

Howdy, essaie de copier un fichier du cache IE vers un autre emplacement. Cela fonctionne sur W7, mais pas Vista Ultimate.La copie de PowerShell échoue sans avertissement

En bref:

copie article $ f -Destination "$ targetDir" -force

(j'ai aussi essayé f.fullname $)

Le script complet:

$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 
     } 

Fin de la sagesse. S'il vous plaît aider!

Répondre

3

La raison pour laquelle copy-item ne fonctionne pas est que vous transmettez System.IO.FileInfo comme paramètre -path. Il y a deux possibilités comment le faire correctement:

  1. copy-item -literal $f.Fullname -destination ...
  2. $f | copy-item -destination ...

Notez que j'utilise le paramètre -literalPath car les fichiers dans le dossier temporaire ont généralement [ et ] à l'intérieur du nom qui agit comme caractères génériques.

Si vous vous demandez pourquoi fonctionne le cas n ° 2, jetez un coup d'œil à 'help Copy-Item -Parameter Path`, vous verrez Accepter l'entrée du pipeline? true (ByValue, ByPropertyName). Pour plus d'informations sur ce que cela signifie, regardez le livre électronique de Keith Effective Windows PowerShell.

Pourquoi votre version ne fonctionne pas? Parce paramerer -path (qui est à la position 1) prend une entrée de type [string[]] et non FileInfo. PowerShell a donc essayé de le convertir en [string] (puis en tableau) mais il n'a probablement utilisé que la propriété Name. Vous pouvez l'essayer comme ceci:

[string[]] (gci | select -first 1)

6

Chaque fois que vous rencontrez des problèmes en essayant de comprendre pourquoi un paramètre ne lie pas correctement dans PowerShell, utilisez Trace-commande comme ceci:

Trace-Command -Name ParameterBinding -expr { copy-item $f foo.cat.bak } -PSHost 

Dans ce cas, cela fonctionne pour moi. Peut-être est une « fonction » de PowerShell 2.0, mais vous pouvez le voir tenter de se lier à plusieurs reprises différentes avant qu'elle ne touche le:

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] 

La façon dont cela fonctionne normalement lorsque les objets FileInfo sont passés via le pipeline, ils se lient par "PropertyName" au paramètre LiteralPath. Je sais, vous vous demandez probablement, vous ne pensiez pas que System.IO.FileInfo avait une propriété LiteralPath. Heheh, ce n'est pas le cas. Ces faux PowerShell faufilent un alias PSPath sur le paramètre LiteralPath et PowerShell "adapte" chaque objet FileInfo pour ajouter un certain nombre de propriétés PS *, y compris PSPath. Donc, si vous vouliez « littéralement » correspondre le comportement de pipelining que vous utilisez:

Copy-Item -LiteralPath $f.PSPath $targetDir -force 

Notez que vous n'avez pas à citer targetDir $ dans ce cas (comme argument de paramètre).

Questions connexes