Лучший отвечающий
Создание групп и вложенности

Вопрос
-
Добрый день
Есть папка, в которой 1 000 папок и у в них куча подпапок
нужно создать права доступа на каждую из 1 000 папок
1. Чем я занялся, тем что требуется ограничить уровень глубины рекурсии, так как раздавать на каждую папку не требуется
function Get-ChildItemToDepth { param( [String]$Path = $PWD, [String]$Filter = "*", [Byte]$ToDepth = 255, [Byte]$CurrentDepth = 0, [Switch]$DebugMode ) $CurrentDepth++ if ($DebugMode) { $DebugPreference = "Continue" } Get-ChildItem $Path | ForEach-Object { $_ | Where-Object { $_.Name -like $Filter } if ($_.PsIsContainer) { if ($CurrentDepth -le $ToDepth) { # Callback to this function Get-ChildItemToDepth -Path $_.FullName -Filter $Filter -ToDepth $ToDepth -CurrentDepth $CurrentDepth } else { Write-Debug $("Skipping GCI for Folder: $($_.FullName) " + "(Why: Current depth $CurrentDepth vs limit depth $ToDepth)") } } }
2. Применил на требуемую папку
Get-ChildItemToDepth -Path \\server\share$\Папка -ToDepth 1 | where {$_.Attributes -eq 'Directory'} | Select-Object FullName
3. Получил
\\server\share$\Папка\ПапкаX1\ПапкаX2
\\server\share$\Папка\ПапкаX1\ПапкаX2.1
\\server\share$\Папка\ПапкаY1\ПапкаY2
\\server\share$\Папка\ПапкаY1\ПапкаY2.1
4. Задача создание группы в Active Directory основываясь на данном выводе
\\server\share$\Папка - всегда одинаковые и можно опустить
Далее идет уровень 1 и 2 \ПапкаX1\ПапкаX2 ( нужно как то динамически это вычислять для переменных )
$var1 = как указать что это ПапкаX1,ПапкаY1 и все 1000 папок на 1 уровне
$var2 = как указать что это ПапкаX2,ПапкаX2.1,ПапкаY2,ПапкаY2.1 и все остальные папки на 2 уровне
То есть в идеале, я хочу получить два массива
Где $var1 = ПапкаX1,ПапкаX2
Где $var2 = ПапкаX2,ПапкаX2.1
После чего могу приступить к созданию 3 групп Просмотра,Чтения и Записи
foreach ($var in $var1){ New-ADGroup -Name "TEMP_$var_L" -Path "OU=TEMP,DC=contoso,DC=com" -groupScope domainlocal New-ADGroup -Name "TEMP_$var_R" -Path "OU=TEMP,DC=contoso,DC=com" -groupScope domainlocal New-ADGroup -Name "TEMP_$var_RW" -Path "OU=TEMP,DC=contoso,DC=com" -groupScope domainlocal }
Далее делаю для 2 уровня
Вот тут я тоже запоролся...
группы по первому уровню я создал ( пофантазирую )
TEMP_ПапкаX1_L
TEMP_ПапкаX1_R
TEMP_ПапкаX1_RW
Далее мне нужно создать такого вида
TEMP_ПапкаX1_ПапкаX2_L
TEMP_ПапкаX1_ПапкаX2_R
TEMP_ПапкаX1_ПапкаX2_RW
Типо того, но конечно это не правильно
foreach ($var in $var2){ $var1 = как задать что это вышестоящая папка... 1 уровня New-ADGroup -Name "TEMP_$var1_$var_L" -Path "OU=TEMP,DC=contoso,DC=com" -groupScope domainlocal New-ADGroup -Name "TEMP_$var1_$var_R" -Path "OU=TEMP,DC=contoso,DC=com" -groupScope domainlocal New-ADGroup -Name "TEMP_$var1_$var_RW" -Path "OU=TEMP,DC=contoso,DC=com" -groupScope domainlocal }
В какую сторону копать?
- Перемещено osr_MVP, Moderator 16 декабря 2015 г. 12:07
16 декабря 2015 г. 11:55
Ответы
-
$tf = dir \\server\share$\Папка\*\* | Where {$_.PsIsContainer} | Group Parent foreach ($f in $tf) { "TEMP_{0}_L" -f $f.Name "TEMP_{0}_R" -f $f.Name "TEMP_{0}_RW" -f $f.Name $f.Group| Foreach { "TEMP_{0}_{1}_L" -f $f.Name,$_.Name "TEMP_{0}_{1}_R" -f $f.Name,$_.Name "TEMP_{0}_{1}_RW" -f $f.Name,$_.Name } }
- Помечено в качестве ответа SharpQ 16 декабря 2015 г. 12:56
16 декабря 2015 г. 12:32Отвечающий -
$tf = dir \\server\share$\Папка | Where {$_.PsIsContainer} | Select Name,@{n="Folders";e={dir $_.FullName | Where {$_.PsIsContainer}}} foreach ($f in $tf) { "TEMP_{0}_L" -f $f.Name "TEMP_{0}_R" -f $f.Name "TEMP_{0}_RW" -f $f.Name $f.Folders| Foreach { "TEMP_{0}_{1}_L" -f $f.Name,$_.Name "TEMP_{0}_{1}_R" -f $f.Name,$_.Name "TEMP_{0}_{1}_RW" -f $f.Name,$_.Name } }
- Помечено в качестве ответа SharpQ 16 декабря 2015 г. 18:12
16 декабря 2015 г. 16:19Отвечающий -
Может возникнуть ситуация, где короткие имена будут одинаковые. 8 - длина (TEMP__RW - максимальное количество символов в добавлении к имени папки)
$tf = dir \\server\share$ | Where {$_.PsIsContainer} | Select Name,@{n="Folders";e={dir $_.FullName | Where {$_.PsIsContainer}}} $tf2 = foreach ($f in $tf) { $name = $f.Name.Replace(" ","-") if(($f.Name.Length+8) -gt 64) { $name = $name.Substring(0,3) } "TEMP_{0}_L" -f $name "TEMP_{0}_R" -f $name "TEMP_{0}_RW" -f $name $f.Folders| Foreach { $cname = $_.Name.Replace(" ","-") if(($name.Length+8+$cname.Length) -gt 64) { $cname = $cname.Substring(0,3) } "TEMP_{0}_{1}_L" -f $name,$cname "TEMP_{0}_{1}_R" -f $name,$cname "TEMP_{0}_{1}_RW" -f $name,$cname } } $tf2 = $tf2 | Group foreach ($f2 in $tf2) { if($f2.Count -eq 1) { New-ADGroup -Name $f2.Name -Path "OU=TEMP,DC=contoso,DC=com" -groupScope domainlocal } else { Write-Host $f2.Name - дубль -ForeGround Yellow } }
- Помечено в качестве ответа SharpQ 17 декабря 2015 г. 7:41
17 декабря 2015 г. 6:25Отвечающий
Все ответы
-
Пока писал догнал как че делать с 1 уровнем
$Path = \\server\share$\Папка $var1 = Get-ChildItemToDepth -Path $Path -ToDepth 0 | Where-Object {$_.PSIsContainer} | Foreach-Object {$_.Name} foreach ($var in $var1){ New-ADGroup -Name "$("TEMP_" + $var + "_L")" -Path "OU=TEMP,DC=contoso,DC=com" -groupScope domainlocal New-ADGroup -Name "$("TEMP_" + $var + "_R")" -Path "OU=TEMP,DC=contoso,DC=com" -groupScope domainlocal New-ADGroup -Name "$("TEMP_" + $var + "_RW")" -Path "OU=TEMP,DC=contoso,DC=com" -groupScope domainlocal }
Но со 2 уровнем пока не ясно...
Получу я вот так массив
$var2 = Get-ChildItemToDepth -Path C:\POSH -ToDepth 1 |
Where-Object {$_.PSIsContainer} |
Foreach-Object {$_.Name}И если сделаю как ранее, то получу не то что нужно...
"$("TEMP_" + $var + "_L")"
А мне нужно что бы, это увязывалась с выше стоящей папкой...
TEMP_ПапкаX2_L
TEMP_ПапкаX2.1_L
А нужно TEMP_ПапкаX1_ПапкаX2_L
16 декабря 2015 г. 12:32 -
$tf = dir \\server\share$\Папка\*\* | Where {$_.PsIsContainer} | Group Parent foreach ($f in $tf) { "TEMP_{0}_L" -f $f.Name "TEMP_{0}_R" -f $f.Name "TEMP_{0}_RW" -f $f.Name $f.Group| Foreach { "TEMP_{0}_{1}_L" -f $f.Name,$_.Name "TEMP_{0}_{1}_R" -f $f.Name,$_.Name "TEMP_{0}_{1}_RW" -f $f.Name,$_.Name } }
- Помечено в качестве ответа SharpQ 16 декабря 2015 г. 12:56
16 декабря 2015 г. 12:32Отвечающий -
как всегда спасибо за невероятно точное решение проблемы
Готовый вариант
$tf = dir \\server\share$\*\* | Where {$_.PsIsContainer} | Group Parent foreach ($f in $tf) { "TEMP_{0}_L" -f $f.Name "TEMP_{0}_R" -f $f.Name "TEMP_{0}_RW" -f $f.Name $f.Group| Foreach { $var1 = "TEMP_{0}_{1}_L" -f $f.Name,$_.Name $var2 = "TEMP_{0}_{1}_R" -f $f.Name,$_.Name $var3 = "TEMP_{0}_{1}_RW" -f $f.Name,$_.Name New-ADGroup -Name "$var1" -Path "OU=TEMP,DC=contoso,DC=com" -groupScope domainlocal New-ADGroup -Name "$var2" -Path "OU=TEMP,DC=contoso,DC=com" -groupScope domainlocal New-ADGroup -Name "$var3" -Path "OU=TEMP,DC=contoso,DC=com" -groupScope domainlocal } }
В идеале, еще бы пробел, заменить на -, было бы шикарно..)
В остальном задачу первую для себя решил)
16 декабря 2015 г. 12:56 -
Если в имени папки есть пробел,то:
$_.Name.Replace(" ","-")
$f.Name.Replace(" ","-")
16 декабря 2015 г. 13:05Отвечающий -
Немножко поспешил, если папка пуста, она не попадает под действие
dir \\server\share$\*\* | Where {$_.PsIsContainer} | Group Parent
Получается, что 1 и 2 уровень создается без ошибок, только если реально есть папка на 2 уровне
решил сделать проверку ( каркас для будущего скрипта )
Если есть 2 уровень, то применяется скрипт который Вы дали, если нету, то применяется только 1 часть скрипта...
Но чето я упоролся ( не понимаю, как только я делаю конструкцию с foreach не правильно отдает данные...
Если отдельно, просто путь забивать без foreach все правильно.. показывает, но в конструкции лупа, никак...
Это просто только сам каркас для скрипта, потом сюда хочу интегрировать то что Вы дали... если конечно моя логика верна.
$Pathdirectory = "\\server\share$" $array1 = Get-ChildItem -Path $Pathdirectory | ?{ $_.PSIsContainer } | Select-Object FullName foreach ($array in $array1) { if (Test-Path "$($array + "\*")" -include $_.PSIsContainer) { Write-Host "2 Уровень папок присутствует" -ForegroundColor Cyan } else { Write-Host "2 Уровень папок отсутствует" -ForegroundColor Red } }
А Вот так правильно отдает, для конкретно папки
if (Test-Path "$($array + "\*")" -include $_.PSIsContainer) { Write-Host "2 Уровень папок присутствует" -ForegroundColor Cyan } else { Write-Host "2 Уровень папок отсутствует" -ForegroundColor Red } }
16 декабря 2015 г. 15:22 -
$tf = dir \\server\share$\Папка | Where {$_.PsIsContainer} | Select Name,@{n="Folders";e={dir $_.FullName | Where {$_.PsIsContainer}}} foreach ($f in $tf) { "TEMP_{0}_L" -f $f.Name "TEMP_{0}_R" -f $f.Name "TEMP_{0}_RW" -f $f.Name $f.Folders| Foreach { "TEMP_{0}_{1}_L" -f $f.Name,$_.Name "TEMP_{0}_{1}_R" -f $f.Name,$_.Name "TEMP_{0}_{1}_RW" -f $f.Name,$_.Name } }
- Помечено в качестве ответа SharpQ 16 декабря 2015 г. 18:12
16 декабря 2015 г. 16:19Отвечающий -
Спасибо, то что нужно
Как всегда, я думаю не туда куда нужно....
16 декабря 2015 г. 18:12 -
Не буду создавать тему отдельную
Вывод такого лупа, можно ли добавить в новый array?
что бы напримери вывод команды был не в консоль или csv, а в $array
Что бы я мог его дальше обрабатывать ?
Я могу выгрузить его в csv, а потом загрузить при создание групп, но интересует вопрос, возможно именно вывод лупа в новый массив добавить.
$tf = dir \\server\share$\Папка | Where {$_.PsIsContainer} | Select Name,@{n="Folders";e={dir $_.FullName | Where {$_.PsIsContainer}}} foreach ($f in $tf) { "TEMP_{0}_L" -f $f.Name "TEMP_{0}_R" -f $f.Name "TEMP_{0}_RW" -f $f.Name $f.Folders| Foreach { "TEMP_{0}_{1}_L" -f $f.Name,$_.Name "TEMP_{0}_{1}_R" -f $f.Name,$_.Name "TEMP_{0}_{1}_RW" -f $f.Name,$_.Name } }
16 декабря 2015 г. 19:21 -
Хех) все просто оказалось... спасибо за помощь
Готовый вариант, создания групп напрямую в АД если комуто будет нужно
$tf = dir \\server\share$ | Where {$_.PsIsContainer} | Select Name,@{n="Folders";e={dir $_.FullName | Where {$_.PsIsContainer}}} $tf2 = foreach ($f in $tf) { "TEMP_{0}_L" -f $f.Name "TEMP_{0}_R" -f $f.Name "TEMP_{0}_RW" -f $f.Name $f.Folders| Foreach { "TEMP_{0}_{1}_L" -f $f.Name.Replace(" ","-"),$_.Name.Replace(" ","-") "TEMP_{0}_{1}_R" -f $f.Name.Replace(" ","-"),$_.Name.Replace(" ","-") "TEMP_{0}_{1}_RW" -f $f.Name.Replace(" ","-"),$_.Name.Replace(" ","-") } } foreach ($f2 in $tf2) { New-ADGroup -Name "$f2" -Path "OU=TEMP,DC=contoso,DC=com" -groupScope domainlocal }
- Изменено SharpQ 16 декабря 2015 г. 19:32
16 декабря 2015 г. 19:30 -
Я понимаю, что уже надоел немного..
Но длина группы в АД имеет ограничение.....
Если папка слишком длинная по названию группа не создатся.. в ручную я обычно сокращал конечно
Но как это можно сделать со скриптом? даже ума не приложу... что бы отсчитаывал 3 буквы ? каждого слова? ... не представлял что такой гемор будет...
По факту, скрипт работает ИДЕАЛЬНО, но если длинна папки большая и в группу не влазивает, группа н создаться
МОжно как то придумать сокращение слов?
Типа Count первые 3 буквы....
Если я правильно понял
Алгоритм
Если длина поля больше 64 символов, то от имени папки должно браться ровно 3 Символа
Например
Папка1\Папка2
Идет проверка, если больше то
Папка1\Пап_L
- Изменено SharpQ 17 декабря 2015 г. 6:24
16 декабря 2015 г. 20:00 -
Может возникнуть ситуация, где короткие имена будут одинаковые. 8 - длина (TEMP__RW - максимальное количество символов в добавлении к имени папки)
$tf = dir \\server\share$ | Where {$_.PsIsContainer} | Select Name,@{n="Folders";e={dir $_.FullName | Where {$_.PsIsContainer}}} $tf2 = foreach ($f in $tf) { $name = $f.Name.Replace(" ","-") if(($f.Name.Length+8) -gt 64) { $name = $name.Substring(0,3) } "TEMP_{0}_L" -f $name "TEMP_{0}_R" -f $name "TEMP_{0}_RW" -f $name $f.Folders| Foreach { $cname = $_.Name.Replace(" ","-") if(($name.Length+8+$cname.Length) -gt 64) { $cname = $cname.Substring(0,3) } "TEMP_{0}_{1}_L" -f $name,$cname "TEMP_{0}_{1}_R" -f $name,$cname "TEMP_{0}_{1}_RW" -f $name,$cname } } $tf2 = $tf2 | Group foreach ($f2 in $tf2) { if($f2.Count -eq 1) { New-ADGroup -Name $f2.Name -Path "OU=TEMP,DC=contoso,DC=com" -groupScope domainlocal } else { Write-Host $f2.Name - дубль -ForeGround Yellow } }
- Помечено в качестве ответа SharpQ 17 декабря 2015 г. 7:41
17 декабря 2015 г. 6:25Отвечающий -
Спасибо, работает.
17 декабря 2015 г. 7:43 -
немного топорно допилил ( с ошибками в консоли ), но задачу решает, если все таки короткие имена совпали
прогоняю после else еще раз но с
$name.Substring(0,6) + "-" + $name.substring($name.length - 6, 6)
$cname.Substring(0,6) + "-" + $cname.substring($cname.length - 6, 6)
и 3 наверно мало все таки, поставил по 6
Если вдруг у кого то такая же задача будет :)
$tf = dir \\server\share$ | Where {$_.PsIsContainer} | Select Name,@{n="Folders";e={dir $_.FullName | Where {$_.PsIsContainer}}} $tf2 = foreach ($f in $tf) { $name = $f.Name.Replace(" ","-") if(($f.Name.Length+8) -gt 64 -and $f.Count -lt 1) { $name = $name.Substring(0,6) } "TEMP_{0}_L" -f $name "TEMP_{0}_R" -f $name "TEMP_{0}_RW" -f $name $f.Folders| Foreach { $cname = $_.Name.Replace(" ","-") if(($name.Length+8+$cname.Length) -gt 64 -and $f.Count -lt 1) { $cname = $cname.Substring(0,6) } "TEMP_{0}_{1}_L" -f $name,$cname "TEMP_{0}_{1}_R" -f $name,$cname "TEMP_{0}_{1}_RW" -f $name,$cname } } $tf2 = $tf2 | Group foreach ($f2 in $tf2) { if($f2.Count -eq 1) { New-ADGroup -Name $f2.Name -Path "OU=TEMP,DC=contoso,DC=com" -groupScope domainlocal } else { $tf = dir \\server\share$ | Where {$_.PsIsContainer} | Select Name,@{n="Folders";e={dir $_.FullName | Where {$_.PsIsContainer}}} $tf2 = foreach ($f in $tf) { $name = $f.Name.Replace(" ","-") if(($f.Name.Length+8) -gt 64) { $name = $name.Substring(0,6) + "-" + $name.substring($name.length - 6, 6) } "TEMP_{0}_L" -f $name "TEMP_{0}_R" -f $name "TEMP_{0}_RW" -f $name $f.Folders| Foreach { $cname = $_.Name.Replace(" ","-") if(($name.Length+8+$cname.Length) -gt 64) { $cname = $cname.Substring(0,6) + "-" + $cname.substring($cname.length - 6, 6) } "TEMP_{0}_{1}_L" -f $name,$cname "TEMP_{0}_{1}_R" -f $name,$cname "TEMP_{0}_{1}_RW" -f $name,$cname } } $tf2 = $tf2 | Group foreach ($f2 in $tf2) { if($f2.Count -eq 1) { New-ADGroup -Name $f2.Name -Path "OU=TEMP,DC=contoso,DC=com" -groupScope domainlocal -ErrorAction Ignore } else { Write-Host $f2.Name - дубль -ForeGround Yellow } } } }
- Изменено SharpQ 17 декабря 2015 г. 8:59
17 декабря 2015 г. 8:58