none
Сделать отступ в рекурсии

    Вопрос

  • Коллеги,

    задался вопросом получения наглядного вида вложенных групп AD...

    Есть папка testR0 вида

    testR0
         testL1
              testL2
                   testL3
                        testL4.1
                        testL4.2
                             testL5.1

    Я "написал" функцию с рекурсией, которая смотрит вложенные группы.

    function Get-NestedGroups ($group)
    {
        $groupMembers = Get-ADGroupmember $group | Sort-Object objectClass -descending
        ForEach ($member in $groupMembers) 
        {
            IF ($member.ObjectClass -eq "group")
            {
                write-host $member.name
                Get-NestedGroups $member.name
            } 
        }
    } 
    $rootGroup = "testR0"
    Get-NestedGroups $rootGroup

    Она отрабатывает на ура, показывает все группы, но в виде одного столбца. И совершенно не понятно, какая группа в какую вложена.

    Пытаюсь добавить отступы $indent += "`t" перед циклом - он сдвигает столбец на один отступ, если внутри цикла, то он для каждого цикла сдвигает на один отступ.

    function Get-NestedGroups ($group)
    {
        $groupMembers = Get-ADGroupmember $group | Sort-Object objectClass -descending
        ForEach ($member in $groupMembers) 
        {
            IF ($member.ObjectClass -eq "group")
            {
                write-host $indent $member.name
                $indent +="`t"
                Get-NestedGroups $member.name
             } 
        }
            
    } 
    $rootGroup = "testR0"
    Get-NestedGroups $rootGroup

    testL1
         testL2
         testL3
         testL4.1
         testL4.2
              testL5.1

    А нужно, чтобы для каждой итерации сдвигал на один отступ, а не для каждого цикла.

    13 декабря 2018 г. 7:14

Ответы

  • function Show-GroupTree
    {
        [CmdletBinding()]
        param(
            $GroupName,                    
            $IndentSize = 4
        )
    
        Begin {       
            $lineChars = @{
                EndCap        = '└'
                Junction      = '├'
                HorizontalBar = '─'
                VerticalBar   = '│'
            }
             
            function GetIndentString([bool[]]$IsLast) {
                $str = ''
                for ($i=0; $i -lt $IsLast.Count - 1; $i++)
                {
                    $str += if ($IsLast[$i]) {' '} else {$lineChars.VerticalBar}
                    $str += " " * ($IndentSize - 1)
                }
                $str += if ($IsLast[-1]) {$lineChars.EndCap} else {$lineChars.Junction}
                $str += $lineChars.HorizontalBar * ($IndentSize - 1)
                $str
            }
            
            function ShowItemText([string]$Item, [bool[]]$IsLast) {
    			$String = $Item
                if ($IsLast.Count -ne 0) {
                    $String = "$(GetIndentString $IsLast)$Item "
                }
    			
                $String  
            }
                  
            function ShowItem($Item, [bool[]]$IsLast=@()) {        
                ShowItemText $Item.Name $IsLast
                
                $childItems = @()
                if ($IsLast.Count -lt 255) {
                    $childItems = @(Get-ADGroupMember $Item | Where objectClass -eq group)
                }
    
                $IsLast += @($false)
                            
                for ($i=0; $i -lt $childItems.Count; $i++) {
                    $childItem = $childItems[$i]
                    $IsLast[-1] = ($i -eq $childItems.Count - 1)
                    ShowItem $childItem $IsLast
                }
            }
        }
    
        Process {
    		$GroupName = Get-ADGroup $GroupName 
    		ShowItem $GroupName  
        }        
    }

    Вывод:

    PS > Show-GroupTree GR -IndentSize 10
    GR
    ├─────────D
    │         ├─────────B
    │         │         └─────────A
    │         └─────────C
    │                   └─────────A
    ├─────────C
    │         └─────────A
    ├─────────B
    │         └─────────A
    └─────────GR_FTP

    • Помечено в качестве ответа Kupriyanov 13 декабря 2018 г. 9:33
    13 декабря 2018 г. 8:18
    Отвечающий

Все ответы

  • function Show-GroupTree
    {
        [CmdletBinding()]
        param(
            $GroupName,                    
            $IndentSize = 4
        )
    
        Begin {       
            $lineChars = @{
                EndCap        = '└'
                Junction      = '├'
                HorizontalBar = '─'
                VerticalBar   = '│'
            }
             
            function GetIndentString([bool[]]$IsLast) {
                $str = ''
                for ($i=0; $i -lt $IsLast.Count - 1; $i++)
                {
                    $str += if ($IsLast[$i]) {' '} else {$lineChars.VerticalBar}
                    $str += " " * ($IndentSize - 1)
                }
                $str += if ($IsLast[-1]) {$lineChars.EndCap} else {$lineChars.Junction}
                $str += $lineChars.HorizontalBar * ($IndentSize - 1)
                $str
            }
            
            function ShowItemText([string]$Item, [bool[]]$IsLast) {
    			$String = $Item
                if ($IsLast.Count -ne 0) {
                    $String = "$(GetIndentString $IsLast)$Item "
                }
    			
                $String  
            }
                  
            function ShowItem($Item, [bool[]]$IsLast=@()) {        
                ShowItemText $Item.Name $IsLast
                
                $childItems = @()
                if ($IsLast.Count -lt 255) {
                    $childItems = @(Get-ADGroupMember $Item | Where objectClass -eq group)
                }
    
                $IsLast += @($false)
                            
                for ($i=0; $i -lt $childItems.Count; $i++) {
                    $childItem = $childItems[$i]
                    $IsLast[-1] = ($i -eq $childItems.Count - 1)
                    ShowItem $childItem $IsLast
                }
            }
        }
    
        Process {
    		$GroupName = Get-ADGroup $GroupName 
    		ShowItem $GroupName  
        }        
    }

    Вывод:

    PS > Show-GroupTree GR -IndentSize 10
    GR
    ├─────────D
    │         ├─────────B
    │         │         └─────────A
    │         └─────────C
    │                   └─────────A
    ├─────────C
    │         └─────────A
    ├─────────B
    │         └─────────A
    └─────────GR_FTP

    • Помечено в качестве ответа Kupriyanov 13 декабря 2018 г. 9:33
    13 декабря 2018 г. 8:18
    Отвечающий
  • если я вас правильно понял, вам нужно уровень вложенности передавать в функцию
    13 декабря 2018 г. 8:21
  • Разобрался, в моем примере, вместо $indent+="`t" нужно сделать $indent=$indent+"`t"

    Хотя я думал, что это одно и тоже.

    function Get-NestedGroups ($group)
    {
        $indent = $indent + "`t"
        $groupMembers = Get-ADGroupmember $group | Sort-Object objectClass -descending
        ForEach ($member in $groupMembers) 
        {
            IF ($member.ObjectClass -eq "group")
            {
                write-host $indent $member.name
                Get-NestedGroups $member.name
            } 
        }
    } 
    $rootGroup = "testR0"
    Get-NestedGroups $rootGroup

    Но пример Kazun'a интереснее, псевдографика ещё больше упрощает понимание. 

    Нужно только ещё соединение вниз сделать.
    • Изменено Kupriyanov 13 декабря 2018 г. 8:57
    13 декабря 2018 г. 8:55