简体   繁体   中英

Powershell While Loop not Working as Intended

So here's what I'm attempting to do:

I manually input a name, and then I want to get a list of users who work under the person whose name I input (extensionattribute9 is who the user works under). However, for each person that works under that person, I also want to run the process for them, and see if anyone works under them as well. I want this process to continue until no one works under the current user.

I've managed do to this up to 3 times without a while loop, but as I don't know how deep I would have to go to get everyone, I feel using a while loop would be better overall, especially in terms of code length.

Here is the code I currently have:

$users = Get-ADUser -Filter * -Properties extensionattribute9,Displayname,mail,title

$users | ForEach-Object {
 if ($_.extensionattribute9 -like '*Lynn, *')
 {
      $_ | select Displayname,userprincipalname,title,extensionattribute9
      $name = $_.Displayname

      while ($_.extensionattribute9 -ne $null){ $users | ForEach-Object {
          if ($_.extensionattribute9 -eq $name)
          {
          $_ | select Displayname,userprincipalname,title,extensionattribute9
          $name=$_.Displayname
          }
     }
   }        
 }
}

When I run the code I get a user (User A) under 'Lynn', and then a user under User A. After that, nothing. The program still continues to run, but nothing gets returned. I'm guessing it's stuck in an infinite cycle, but I don't know where better to put the while loop. Help?

I'm not familiar with Powershell, but one possible reason you're having trouble is that $_ is being used to mean two different things, depending on whether you use it inside the while loop or not. Is Powershell really smart enough to know what you mean?

More important: the code

$_ | select Displayname,userprincipalname,title,extensionattribute9
  $name = $_.Displayname

appears in two places close together. This is a definite code smell. It should appear once and only once.

When you're traversing a hierarchy and you don't know how deep it will go, you must use a recursive algorithm (a function that calls itself). Here it is in pseudocode:

function myFunc ($node) {
    //report the name of this node
    echo "node $node found." ;
    // check to see if this node has any child nodes
    array $children = getChildNodes ($node) ;
    if (count($children) == 0) {
        //no child nodes, get out of here
        return ;
    }
    //repeat the process for each child
    foreach($children as $child) {
        myFunc($child) ;
    }
}

It sounds like you are trying to do a recursive search with nested while/for-each loops which can end badly. You can try something like this:

Function Get-Manager {

    param([Object]$User)

    $ManagerName = $User.extensionattribute9

    # Recursion base case
    if ($ManagerName -eq $null){
        return
    }

    # Do what you want with the user here
    $User | select Displayname, userprincipalname, title, extensionattribute9

    # Recursive call to find manager's manager
    $Manager = Get-ADUser -Filter "Name -like $ManagerName"
    Get-Manager $Manager

}

# Loop through all ADusers as you did before
$Users = Get-ADUser -Filter * -Properties extensionattribute9,Displayname,mail,title

Foreach ($User in $Users) {
    Get-Manager $User
}

Please note I don't have experience using Powershell with Active Directory so the syntax may be incorrect, but shouldn't be hard to fix. Hope this helps!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM