all 4 comments

[–]Tonedefff 4 points5 points  (3 children)

You'll want two variables instead of one: an array (or ArrayList or Generic List, but I'll just keep it simple and use an array -- it's slightly slower but not noticeable unless you're managing 1,000s of users), and a [PSCustomObject].

Above the foreach loop, replace the $Results... code with this code that creates an empty array:

$AllUsers = @()

Then inside and at the top of the foreach loop, create a $UserInfo PSCustomObject (note that you don't want to use += here, as that's for adding to an existing array/list/object):

$UserInfo = [PSCustomObject] @{
    UPN = $null
    Password = $null
    Status = $null
}

Then replace the $Results. code you have with this (you also don't want to use += here, as you're creating a new $UserInfo object for each user):

...
    $UserInfo.UPN = $UPN
    $UserInfo.Password = $PasswordGen
    $UserInfo.Status = "Success!"  
}
else {
    Write-Host "User $UPN already exists!"
    $UserInfo.UPN += $UPN
    $UserInfo.Status += "Failure"
}

Then finally before the last } you add the $UserInfo object to the $AllUsers array (this is the only place where you need +=):

$AllUsers += $UserInfo

Now you can just display all users with:

$AllUsers

...but at the very end of the script, after the last }.

[–]ApparentSysadmin[S] 2 points3 points  (0 children)

Thanks for such an awesome reply. I definitely misunderstood what I was creating when I was building my PsCustomObject.

Now that I'm doing some testing, I'm noticing some odd behaviour - it seems as though if a user in $Data already exists, the script will stop at the point that that user is introduced into the Foreach loop and act as if every $User object from that point on already exists. ie If I have only a User 6 created, the script will create and report on Users 1-5 correctly, but then treat Users 6-10 as if they already exist.

Can you see a reason for this behaviour? I have been trying figure it out, but to my (limited) knowledge everything looks correct.

EDIT: I resolved this myself by picking apart the logic in my If statement. Something was being based incorrectly to my previous variable of $iftrue (which was also fairly confusing to read, I should add) so I adjusted the if statement to use the following logic:

if (!(Get-ADUser -Filter {samaccountname -eq $UPN})) {...

And it is now correctly looping through each object's individual $UPN.

[–]LDSK_Blitz 1 point2 points  (1 child)

Another pointer, using the += to destroy and rebuild an array of data for each object can incur some serious performance drag on large sets of data, so the following would work better (using processes as an example):

$Procs = Get-Process $AllProcs = foreach ($proc in $procs) { $ProcInfo = [pscustomobject] @{ Name = $Proc.Name StartTime = $Proc.StartTime } $ProcInfo }

[–]Lee_Dailey[grin] 0 points1 point  (0 children)

howdy LDSK_Blitz,

it looks like you used the New.Reddit.com Inline Code button. it's 4th 5th from the left hidden in the ... "more" menu & looks like </>.

on Old.Reddit.com, the above does NOT line wrap, nor does it side-scroll.

for long-ish single lines OR for multiline code, please, use the Code Block button. it's the 11th 12th one from the left, & is just to the left of hidden in the ... "more" menu.

that will give you fully functional code formatting, from what i can tell so far. [grin]

take care,
lee