Я ищу способ рекурсивно просмотреть весь мой файловый ресурс (довольно большие 3 ТБ файлов) и перечислить все файлы / папки, к которым у меня нет доступа. Из-за миграции и некоторых ошибок на больших путях (более 255 символов) мы обнаружили, что некоторые папки / файлы потеряли все разрешения, и нам нужен способ найти их все. В настоящее время как администратор домена я не могу указать разрешения или владельца. Я могу взять его под свой контроль и сбросить разрешения, но у меня так много файлов / папок, что я хотел бы вывести это в файлы CSV или что-то в этом роде.
Я пробовал следующее:
get-childitem "\,\fileshare\f$\folder\etc" -recurse | get-acl
Кажется, это работает отлично, это дает мне списки ACL для всех файлов / папок, которые существуют и имеют соответствующие разрешения на них. Но как только он попадает в папку, к которой у меня нет доступа, я получаю следующую ошибку:
Get-Acl : Attempted to perform an unauthorized operation.
At line:1 char:133
+ get-childitem "\,\fileshare\f$\folder\etc" -re
curse | get-acl <<<<
+ CategoryInfo : NotSpecified: (:) [Get-Acl], UnauthorizedAccessException
+ FullyQualifiedErrorId : System.UnauthorizedAccessException,Microsoft.PowerShell.Commands.GetAclCommand
Это ошибки, которые я хотел бы записать в файл CSV / TXT и проигнорировать все остальные разрешения. Было бы идеально, если бы это можно было выводить в более одной строке для каждой ошибки.
Просто интересно, есть ли у кого-нибудь идея или намек, как мне действовать?
(Обратите внимание, что в приведенных выше путях есть запятые, чтобы они не преобразовывались в реальный путь
\,\fileshare\f$\folder\etc)
Спасибо!
Более простой и менее запутанный способ перехвата ошибок командлета в файл - использование параметра -Errorvariable. Он встроен в большинство командлетов. Ненадежно смотреть на переменную $ Error, поскольку это глобальная переменная, и у нее высока вероятность появления других явных ошибок в процессе PowerShell.
Приведенный ниже код регистрирует ошибки в 2 файлах журнала.
gacl_errors.csv - содержит ошибки при перечислении ACL для определенного файла / папки.
Get-ChildItem C:\Temp -Recurse -ErrorAction SilentlyContinue -ErrorVariable gci_errors | ForEach-Object {
$_ | Get-Acl -ErrorAction SilentlyContinue -ErrorVariable gacl_errors
}
$gci_errors | Select-Object -ExpandProperty CategoryInfo | Export-Csv -NoTypeInformation -Path C:\Temp\gci_errors.csv
$gacl_errors | Select-Object -ExpandProperty CategoryInfo | Export-Csv -NoTypeInformation -Path C:\Temp\gacl_errors.csv
Я изменил вывод на файл CSV в соответствии с вашими требованиями. Это имеет больше смысла, поскольку его легче анализировать и импортировать для выполнения команд с данными. В CSV есть заголовок столбца, который называется Цель который отражает путь к папке, вызывающей проблемы. Вы можете написать командлет, т.е. Fix-DirPerms и трубку к нему. Что-то вроде:
Import-CSV -Path c:\Temp\gci_errors.csv | Fix-DirPerms
Есть много разных способов сделать это. Вот кое-что, что я только что приготовил.
$Error.Clear() # This is a global variable!
$Errors = @()
$Items = Get-ChildItem C:\ -Recurse -ErrorAction SilentlyContinue
ForEach($Err In $Error)
{
$Errors += $Err.Exception
}
ForEach($Item In $Items)
{
Try
{
$Item | Get-ACL -ErrorAction SilentlyContinue | Out-Null
}
Catch
{
$Errors += "$($_.Exception.Message) $($Item.FullName)"
}
}
Write-Host $Errors.Count "errors encountered."
$Errors | Out-File errors.txt
Итак, теперь у вас есть аккуратный список всех ошибок, которые были обнаружены либо в процессе Get-ChildItem, либо в процессе Get-ACL, что важно, поскольку во время каждой операции могут встречаться отдельные ошибки. Вы можете передать переменную $ Errors в CSV или что угодно. Это, вероятно, займет много времени на сетевом ресурсе 3 ТБ. Рассмотрите возможность добавления индикатора прогресса.