#powershell #error-handling #get-childitem
#powershell #обработка ошибок #get-childitem
Вопрос:
Я работаю над небольшим скриптом для захвата хэшей файлов в работающей системе. У меня есть только Powershell.
Это активная часть кода:
get-childitem -path $path -filter $filename -Recurse -Force | Select FullName | foreach-object { get-filehash $_.fullname | select * }
это команда, с помощью которой я тестирую:
./Get-FileHashesRecursive.ps1 -path c: -filename *.txt
При запуске скрипта я получаю ряд ошибок, поскольку некоторые папки недоступны. Я хотел бы записать пути к этим папкам, чтобы у пользователя была запись о завершении того, что не удалось.
ошибка выглядит следующим образом в окне консоли:
get-childitem : Access to the path 'C:$Recycle.BinS-1-5-21-4167544967-4010527683-3770225279-9182' is denied.
At E:gitGet-RemoteFileHashesRecursiveGet-FileHashesRecursive.ps1:14 char:9
get-childitem -path $path -filter $filename -Recurse -Force | ...
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CategoryInfo : PermissionDenied: (C:$Recycle.Bin...3770225279-9182:String) [Get-ChildItem], UnauthorizedAccessException
FullyQualifiedErrorId : DirUnauthorizedAccessError,Microsoft.PowerShell.Commands.GetChildItemCommand
Есть ли способ, которым я могу захватить путь или всю первую строку ошибки, НЕ останавливая выполнение остальной части скрипта?
Комментарии:
1. Почему бы не добавить
-ErrorVariable FailedItems -ErrorAction SilentlyContinue
к вашимGet-ChildItem
параметрам, а затем, как только вы завершите свою команду, добавьте еще один, что-то вроде этого,$FailedItems | Foreach-Object {$_.CategoryInfo.TargetName} | Out-File "C:UserssailingbikerukDesktopnoaccess.log"
. Надеюсь, затем вы должны получить файл со списком всех каталогов, которые выдавали ошибки UnauthorizedAccessException2. Возможно, будет полезно также включить этот
-File
параметр в вашуGet-ChildItem
команду!
Ответ №1:
Как и было запрошено, вот мои предыдущие комментарии в качестве ответа:
Get-ChildItem -Path $Path -Filter $Filename -File -Recurse -Force -ErrorVariable FailedItems -ErrorAction SilentlyContinue | ForEach-Object { Get-FileHash -Path $_.FullName | Select-Object * }
$FailedItems | Foreach-Object {$_.CategoryInfo.TargetName} | Out-File "C:UserssailingbikerukDesktopnoaccess.log"
- Я добавил
-File
параметр вGet-ChildItem
, потому что вы специально имеете дело только с файлами. - Я также добавил параметры
-ErrorVariable
и-ErrorAction
вGet-ChildItem
команду.-ErrorVariable FailedItems
определяет пользовательское имя для переменной, которая хранит ошибки из команды во время обработки.-ErrorAction SilentlyContinue
, сообщает сценарию продолжить, не уведомляя вас об ошибках. - Как только ваша команда завершит обработку, вы можете проанализировать содержимое
$FailedItems
переменной. В приведенном выше примере я вывел файлTargetName
в файл, чтобы вы могли прочитать его на досуге (пожалуйста, не забудьте при необходимости изменить путь к файлу и его имя, если вы также захотите вывести его в файл).
Комментарии:
1.
ErrorRecord
имеет элементTargetObject
, который также хранит путь. Есть ли причина для предпочтенияCategoryInfo.TargetName
?2. Спасибо за это, я протестирую это в выходные и отмечу как ответ после тестирования. Я не знал о параметре -ErrorVariable , который может оказаться очень полезным в будущем.
3. @zett42 Как бы вы получили доступ к targetObject, можете ли вы расширить свой комментарий в качестве ответа?
4. @Compo извиняется за задержку в любом ответе. Я попробовал ваше решение, и оно работает, если ошибка «доступ запрещен», но, похоже, она не создает запись в ErrorVariable, если ошибка есть
The file <filename> cannot be read: The process cannot access the file <filename> because it is being used by another process
. У меня нет уверенности в том, что он сообщает обо всех ошибках доступа.5. Это совершенно другой вопрос, и по прошествии десяти дней, без принятия ответа, который, как вы заявили, работает и который полностью отвечает на заданный вопрос, я не собираюсь публиковать для вас другое решение для этого нового вопроса в рамках этого. Когда я отвечаю на вопрос, я не подписываюсь на то, чтобы быть специалистом службы поддержки forever для ваших дальнейших вопросов. Пожалуйста, создайте новый вопрос, если он у вас есть, и, пожалуйста, если он у вас есть, помните, что мы помогаем вам с исправлением конкретной воспроизводимой проблемы для предоставленного вами кода, мы не пишем для вас код для добавления новых функций, которые вы не включили.