I am trying to get a list of UIDs (NIS attribute). The problem is that UIDs are not in order. I would like to define a range and check if an account exist with that UID and if it does then get me the last UID in range that was used. I have the following code working but it takes a lot of time to loop through the range (for this example, the range is very small). I would like to find out if there is any alternative way to accomplish the same with better performance.

[int32[]] $array= 50000..100000
$initArray = @()
foreach ($arr in $array){
  $acct = (Get-ADUser -Filter (uidnumber -eq $arr) -Properties uidNumber) | select name, uidnumber
  $initArray += $acct.uidnumber      
$initArray | Select -Last 1

This gets me the last used uid but if the range is, let's say, from 300000 to 900000 then the foreach loop is going to take a lot of time in getting the last UID. Any help would be appreciated.

PSVersion: 2.0

  • Personally I think I would just query once to get all uids into an array. Then from there look for the last one in your list.
    – EBGreen
    Jul 10 '18 at 16:00
  • Thanks for replying. I can query this attribute msSFU30MaxUidNumber that will give me the max number but that's a huge number and there are lot of UIDs that are not in use. The other thing to consider is to reserve certain range for internal use. For ex, 40000 to 50000 is reserved only for X purpose and the rest can be used for other purposes.
    – Sid
    Jul 10 '18 at 16:04
  • why don't you count backwards and use a while ($found -eq $nul) and assign a value to $found when you have your first hit?
    – Nixphoe
    Jul 10 '18 at 20:53

Thanks for the information. I have used an approach where I am filtering the UID numbers based on Min and Max defined in my script. So, the code is something like this.

$min = 3000000
$max = 9000000
$res = (Get-ADUser -Filter * -Properties uidnumber | where_object {($_.uidnumber ge $min) -and ($_.uidnumber le $max)}).uidnumber
$uid = ($res |Measure -Maximum).Maximum

if ($uid -eq $null){
   $uid = $min
} else {

Individual gets for that many users is going to be slow. The uidNumber is an indexed attribute, so you can leverage that index with your LDAP query. I would step through it something like this.

for ($x=100000; $x -ge 50000; $x=$x -10000) {
    $q = get-aduser -filter { uidNumber -gt $x } -prop uidNumber,Name
    if ($q) {
        $q | sort-object -prop uidNumber | select-object -last 1
  • Thanks for the information. I understand the logic behind the code but I do have users with UID > 100000. So, the code will return me the highest value but not the highest value within 50000 & 100000
    – Sid
    Jul 16 '18 at 15:13
  • I changed the code to get me {uidNumber -lt $x} and got me the correct results. The execution time for this code is 5 seconds where as, it was 8 seconds earlier, though previous code steps through all the UID numbers in one shot and get's maximum
    – Sid
    Jul 16 '18 at 15:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.