Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   Обработка путей превышающих 260 символов (http://forum.oszone.net/showthread.php?t=308952)

pogo 08-12-2015 21:27 2582840

Обработка путей превышающих 260 символов
 
Доброго времени суток.
Помогите пожалуйста допилить скрипт, для обработки путей больше 260 символов.

Код:

$path = "c:\f1"
$logfile = "C:\f1\log.txt"
if (!(Test-Path $path)) {
  Write-Host "Folder not found" -ForegroundColor Red
  break
}
$folder_list = Get-ChildItem -Path $path -Recurse -Directory
foreach ($folder in $folder_list) {
  #$ACL = Get-Acl $folder.PSPath
  $ACL = Get-Acl $folder.FullName
  if ($ACL.AreAccessRulesProtected -ne $false) {
    $str = $folder.fullname
    Add-Content -Value $str -Path $logfile
  }
}

Вычитал что вроде как это решается монтированием. Попробовал на тестовом скрипте, но что-то он отказывается работать.

Код:

Remove-PSDrive -Name X
$rootpath = "C:\test"
$logfile = "c:\test\log.txt"
try {
  $folder_list = Get-ChildItem $rootpath -Recurse -Directory -ErrorAction Stop
  foreach ($folder in $folder_list) {
    $folder.Name
    Write-Host "+++++++"
    $folder.FullName
    Write-Host "-------"
    $folder.PSPath
    Write-Host "========================="
    ($folder.PSPath).Length
    Write-Host "\\\\\\\\\\\"
  }
}
catch {
  Write-Host "ERROR"
  $folder.FullName
  ($folder.FullName).Length
  $newrootfolder = New-PSDrive -Name X -PSProvider FileSystem -Root $folder.FullName
  Get-ChildItem $newrootfolder
}

И в последней строке Get-ChildItem $newrootfolder скрипт вываливается в ошибку длинного пути.
Подскажите пожалуйста, в чём может быть проблема?

Kazun 09-12-2015 00:10 2582895

Утилита SetAcl не имеет таких ограничений:

Код:

$folders = SetACL.exe -on "C:\f1" -ot file -actn list -rec cont | Where {$_ -match "(:\\|DACL\()"}

$log = for($i =0 ; $i -le $folders.count;$i+=2) {
        $status = $folders[($i+1)] -notmatch "not_protected"
        if($status)
        {
                $folders[$i]
        }
}
$log | Out-File $logfile


greg zakharov 09-12-2015 13:23 2583036

Kazun, вроде бы тот же robocopy умеет работать с путями в более 260 символов, да и трюк с dir тоже прокатывает, например:
Код:

PS E:\sandbox> cmd /c dir \\e:\test /s /b | findstr ...
Что-то в этом роде. Но, если не хочется использовать консоль в хосте, можно попытать счастья со сторонними библиотеками, вроде AlphaFS и QuickIO, - обе с открытым исходным кодом. Ну и наконец можно поробовать использовать методы GetFiles() и GetDirectories из типа System.IO.Directory.

pogo 09-12-2015 13:40 2583039

Спасибо за ответы.

Kazun,
Приведённый Вами скрипт не работает
второй строгой добавил
Код:

write-host folders: $folders
что бы посмотреть что утилита получает, и после вывода ошибка.

Цитата:

folders:
Cannot index into a null array.
At line:6 char:2
+ $status = $folders[($i+1)] -notmatch "not_protected"
....
greg zakharov,
robocopy может и умеет, но она ничего не знает о правах и их наследованиях.
Как показано в первом посте, я попробовал обрезать пути, методом монтирования диска, как пишут в google, но у меня это не работает..

Kazun 09-12-2015 14:03 2583044

Какой результат вывода?
Код:

SetACL.exe -on "C:\f1" -ot file -actn list -rec cont

pogo 09-12-2015 14:37 2583060

C:\test> .\SetACL.exe -on "C:\test" -ot file -actn list -rec cont
Цитата:

C:\test\very_bif_test_folder_001\very_bif_test_folder_002\very_bif_test_folder_003\very_bif_test_fol der_004

DACL(protected+auto_inherited):
SYSTEM full allow container_inherit+object_inherit
Administrators full allow container_inherit+object_inherit
Users read_execute allow container_inherit+object_inherit
Users FILE_ADD_FILE+FILE_ADD_SUBDIRECTORY allow container_inherit
CREATOR OWNER full allow container_inherit+object_inherit+inherit_only


SetACL finished successfully.

pogo 09-12-2015 14:57 2583065

Kazun,

Прошу прощения.
По ходе дела я где-то в путях накосячил, из-за этого не работало.
Вот рабочий вариант

Код:

$logfile = "C:\test\log.txt"
$folders = C:\test\SetACL.exe -on "C:\test" -ot file -actn list -rec cont | Where {$_ -match "(:\\|DACL\()"}

#write-host folders: $folders

$log = for($i=0 ; $i -le $folders.count; $i+=2) {
        $status = $folders[($i+1)] -notmatch "not_protected"
        if($status)
        {
                $folders[$i]
        }
}

$log | Out-File $logfile

Большое спасибо!!

pogo 10-12-2015 09:10 2583307

Подскажите, а можно сделать тоже самое, но средствами утилиты от MS - SubInACL?

Kazun 10-12-2015 09:44 2583314

Код:

$subinacl = "C:\Program Files (x86)\Windows Resource Kits\Tools\subinacl.exe"
$logname = "C:\log.txt"
$folder = "C:\f1"

& $subinacl /outputlog=$logname /subdirectories=directories $folder
$folders = (Get-Content $logname) -match "(\+File|/control)"

$log = for($i=0 ; $i -le $folders.count; $i+=2) {
        $status = $folders[($i+1)] -match "SE_DACL_PROTECTED"
        if($status)
        {
                $folders[$i].TrimStart("+File ")
        }
}
$log | Out-File $logfile


pogo 10-12-2015 10:01 2583318

Kazun, спасибо за оперативный ответ!
Скрипт отрабатывает без ошибок, но лог файл пустой.

P.S. Вроде как проблему решил, указав такой путь
Код:

$folder = "C:\f1\*"

pogo 29-12-2015 16:12 2589554

На удивление, ни один из вариантов, как оказалось, не заработал с UNC и DFS путями ((
Как сказал всем известный поисковик, subinacl вообще не понимает dfs.
SetACL понимает и UNC и DFS, но вывод получается примерно такой:
Цитата:

folders[0]: DACL(protected):
folders[6]: DACL(not_protected):
Подскажите, как подправить скрипты, пожалуйста, пока сам в ключах утилиты не разобрался..

Kazun 30-12-2015 13:33 2589813

Качаем модуль - https://gallery.technet.microsoft.co...f-90dbb2b84e85

Код:

Get-ChildItem2 -Path $folder  -Recurse -Directory | Where {!(Get-NTFSInheritance $_).AccessInheritanceEnabled} | Select -ExpandProperty FullName

pogo 30-12-2015 14:31 2589827

Kazun,
Большое спасибо за все ответы в теме! :)
Интересный модуль, изучим-с) Странно, что во время поиска не наткнулся на него.
В попытках завести один из предложенных Вами вариантов выше, заработал тот, что использует subinacl, ниже рабочий вариант с unc.

Код:

cls
$subinacl = "C:\temp\subinacl.exe" #путь до улититы subinacl.exe
$log = "c:\temp\log.txt" #путь до лог файла
$log_subinacl = "c:\temp\log_subinacl.txt" #путь до внутреннего лог файла subinacl
$path = "\\uncpath...\*" #корневая папка для поиска

& $subinacl /outputlog=$log_subinacl /subdirectories=directories $path #запуск subinacl в фоне, с записью инфы в лог
$content = (Get-Content $log_subinacl) -match "(\+File|\/control)" #выбираем из файла строки по условию

$result = for($i=0; $i -le $content.Count; $i+=2) {
    $status = $content[$i+1] -match "SE_DACL_PROTECTED" #если в строке, есть подстрока, записываем в переменную
    if($status) {
        $content[$i].TrimStart("+File ") #удаляем указанную подстроку из строки
    }
}

Remove-Item $log_subinacl #удаляем лог subinacl
$result | Out-File $log #записываем результат в переменную

На win10 работал подобный вариант написанный Вами ранее, но на win serv 2012r2 регулярное выражение должно выглядеть так - (\+File|\/control).
P.S. Но приведённый Вами модуль, мне нравится большей, этих костыльных решений )


Время: 13:15.

Время: 13:15.
© OSzone.net 2001-