Home > Software design >  Powershell: Use variable from inner loop as condition of outer loop
Powershell: Use variable from inner loop as condition of outer loop

Time:03-28

we're using a PS-Script for creating new AD-users and configure everything in one go. I'd like to create a unique 6-digit number and check if it's already in use. I thought a do-until-loop will do the trick, but i can't get it to re-run if a match is found.

My code as of now is this:

    $AllUsedPins=(Get-ADUser -Properties ExtensionAttribute3 -Filter {ExtensionAttribute3 -like '*'} | select -ExpandProperty ExtensionAttribute3)
    do{
        $PinIsUnique="True"
        #$TempPin="333860"
        $TempPin=(Get-Random -Minimum 0 -Maximum 999999).ToString('000000')
        foreach ($UsedPin in $AllUsedPins) {
            If ("$TempPin" -eq "$UsedPin" ) {
                $PinIsUnique="False"
                Write-Host '$PinIsUnique(IF): '$PinIsUnique
            }
        }
    Write-Host '$PinIsUnique(inDO): '$PinIsUnique
    }
    until ($PinIsUnique="True")
    Write-Host '$PinIsUnique(outDO): '$PinIsUnique

    #Set-ADUser -Identity $sam -Replace @{extensionAttribute3=$TempPin}

$TempPin="333860" is for testing, as it is one already used. The loop should then run endlessly, but stops after one run nevertheless, so I added some Write-Outputs to narrow it down. They show:

$PinIsUnique(IF):  False
$PinIsUnique(inDO):  False
$PinIsUnique(outDO):  True
$TempPin:  333860

What puzzles me here: $PinIsUnique is only set at the beginning of the do-loop, before that it doesn't even exist. $PinIsUnique is False until end of the do-loop, but True when used for checking the while-condition?

I wasted by far too much time on this already: Reading up on loops in general, nested loops, global variables, return, Write-Host vs Write-Output and other things that sounded as they could help me solve this...

I altered the code for easier testing as nearly half of all options should trigger at least one re-run:

    $AllUsedPins=("01", "02", "03", "04", "05", "11", "12", "13", "14", "15")
    do{
        $PinIsUnique="True"
        $TempPin=(Get-Random -Minimum 0 -Maximum 20).ToString('00')
        foreach ($UsedPin in $AllUsedPins) {
            If ("$TempPin" -eq "$UsedPin" ) {
                $PinIsUnique="False"
            }
        }
    }
    until ($PinIsUnique="True")
    Write-Host '$AllUsedPins: '$AllUsedPins
    Write-Host '$TempPin: '$TempPin

As i realized just now while trying the altered code, $TempPin is useable outside the do-loop just fine... So what am I missing here?

Some litte extra if someone cares: I tried to stop the inner foreach-loop if an existing pin was found, but couldn't get that to work either. Neither break nor a labeled break worked... at least the way i tried.

Also, as i'm no expert in scripting/programming but can usually identify a well-written piece of code: How would you guys have solved this?

Thanks in advance!

CodePudding user response:

Sometimes you just have to talk about a problem to get to the solution... and to be ashamed of yourself...

Just edited until ($PinIsUnique="True") to until ($PinIsUnique -eq "True") and it works just fine...

Other examples of how to solve it are encouraged, while i'm standing in the corner facing the wall...

  • Related