Get-ChildItem
предназначен для перечисления потомков , поэтому вы даете ему каталог, но кажется, что вы даете ему файл, поэтому, когда он говорит, что не может найти путь, это потому, чтоон не может найти каталог с таким именем.
Вместо этого вы можете использовать Get-Item -LiteralPath
для получения каждого отдельного элемента (это будут те же элементы, которые вы получите, если вывыполнил Get-ChildItem
на своем родителе.
Я думаю, что замена в Get-Item
заставит ваш код работать как есть.
После тестирования, я думаю, что на самом деле выше ложно,извините за это, но я оставлю нижеследующее на случай, если это будет полезно, даже если оно не решит вашу непосредственную проблему.
Но давайте посмотрим, как это можно упростить с помощью конвейера.
Сначала вы начинаете с пустого массива, затем вызываете команду (Get-Content
), которая, вероятно, уже возвращает массив, упаковывает его в массив, затем объединяет его с пустым.
Вы можете просто сделать:
$inFiles = Get-Content -Path "C:\Users\sw_admin\FoundLinks.csv"
Да, тамЕсть вероятность, что $inFiles
будет содержать только один элемент, а не массив вообще.
Но приятно то, что foreach
не будет возражать ни капли!
Выможет сделать что-то вроде этого, и это просто работает:
foreach ($string in "a literal single string") {
Write-Host $string
}
Но Get-Item
(и Get-ChildItem
в этом отношении) принимают входные данные конвейера, поэтому они принимают несколько элементов.
Это означаетВы можете сделать это:
$inFiles = Get-Content -Path "C:\Users\sw_admin\FoundLinks.csv" | Get-Item
foreach ($inFile in $inFiles) {
Write-Host("Processing: " + $inFile)
New-Object PSObject -Prop @{
FullName = $inFile.FullName
ModifyTime = $inFile.LastWriteTime
}
}
Но даже более того, существует командлет с поддержкой конвейера для обработки элементов, называемый ForEach-Object
, которому вы передаете [ScriptBlock]
, в котором $_
представляет текущий элемент, поэтому мы можем сделать это следующим образом:
Get-Content -Path "C:\Users\sw_admin\FoundLinks.csv" |
Get-Item |
ForEach-Object -Process {
Write-Host("Processing: " + $_)
New-Object PSObject -Prop @{
FullName = $_.FullName
ModifyTime = $_.LastWriteTime
}
}
Все в одном конвейере!
Но, кроме того, вы создаете новый объект с двумя желаемыми свойствами.
PowerShell имеет изящный командлет с именем Select-Object
, который принимает входной объект и возвращает новый объект, содержащий только нужные вам свойства;это улучшило бы синтаксис:
Get-Content -Path "C:\Users\sw_admin\FoundLinks.csv" |
Get-Item |
Select-Object -Property FullName,LastWriteTime
Это мощность конвейера, передающего реальные объекты от одной команды к другой.
Я понимаю, что в последнем примере нет записать сообщение об обработке на экран, однако вы можете добавить его, если хотите:
Get-Content -Path "C:\Users\sw_admin\FoundLinks.csv" |
Get-Item |
ForEach-Object -Process {
Write-Host("Processing: " + $_)
$_ | Select-Object -Property FullName,LastWriteTime
}
Но вы также можете учесть, что многие командлеты поддерживают подробный вывод и попробуйте просто добавить -Verbose
к некоторым из ваших существующих командлетов.К сожалению, это не очень поможет в этом случае.
И последнее замечание: когда вы передаете элементы в командлеты файловой системы через конвейер, параметр, к которому они привязываются, на самом деле -LiteralPath
, а не -Path
,так что ваши специальные символы все еще в безопасности.