none
Создание групп и вложенности RRS feed

  • Вопрос

  • Добрый день

    Есть папка, в которой 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
    
    }
    

    В какую сторону копать?



    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