Копирование PowerShell происходит без предупреждения - PullRequest
4 голосов
/ 20 марта 2010

Привет, я пытаюсь скопировать файл из кеша IE в другое место.Это работает на w7, но не на Vista Ultimate.

Короче:

copy-item $ f -Предназначение "$ targetDir" -force

(я также пробовал $ f.fullname)

Полный сценарий:

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

Конец мудрости.Пожалуйста, помогите!

Ответы [ 2 ]

6 голосов
/ 21 марта 2010

Каждый раз, когда у вас возникают проблемы с попыткой выяснить, почему параметр не связывается правильно в PowerShell, используйте Trace-Command следующим образом:

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

В этом случае это работает для меня. Возможно, это «особенность» PowerShell 2.0, но вы можете увидеть, как он пытается связать несколько раз, прежде чем он попадет на:

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]

То, как это обычно работает, когда объекты FileInfo передаются через конвейер, они привязываются посредством «PropertyName» к параметру LiteralPath. Я знаю, вы, вероятно, задаетесь вопросом, вы не думали, что System.IO.FileInfo имеет свойство LiteralPath. Хехех, это не так. Эти хитрые люди PowerShell добавили псевдоним PSPath к параметру LiteralPath, и PowerShell «адаптирует» каждый объект FileInfo для добавления ряда свойств PS *, включая PSPath. Поэтому, если вы хотите «буквально» соответствовать конвейерному поведению, вы должны использовать:

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

Обратите внимание, что в этом случае вам не нужно заключать в кавычки $ targetDir (в качестве аргумента параметра).

3 голосов
/ 21 марта 2010

Причина, по которой copy-item не работает, заключается в том, что вы передаете System.IO.FileInfo в качестве параметра -path. Как сделать это правильно, есть две возможности:

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

Обратите внимание, что я использую параметр -literalPath, поскольку файлы во временной папке обычно содержат [ и ] внутри имени, которое действует как символы подстановки.

Если вы удивляетесь, почему дело № 2 работает, посмотрите на 'help Copy-Item -Parameter Path`, вы увидите Принимать входные данные из конвейера? true (ByValue, ByPropertyName) . Подробнее о том, что это значит, читайте в книге Кита Кита Effective Windows PowerShell .

.

Почему ваша версия не работает? Поскольку параметр -path (который находится в позиции 1) принимает ввод типа [string[]], а не FileInfo. Таким образом, PowerShell пытался преобразовать его в [string] (а затем в массив), но, вероятно, использовал только свойство Name. Вы можете попробовать это так:

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

...