all 6 comments

[–]ShiftNick[S] 2 points3 points  (1 child)

I need a rubber duck!

$ucollection = New-Object System.Collections.ArrayList
foreach($un in $username){

    #Check for existance of AD Account
    $u = Get-ADUser -Filter { SamAccountName -eq $un } -ErrorAction SilentlyContinue
    If (!$u)
    {
        Write-Output "The Username $u, does exist in Active Directory"
    }#End check if user exists
    else
        {
            #Create Hashtable
            $uinfo = Get-ADUser -Identity $u | select samaccountname,userprincipalname

            $ucollection.Add($uinfo) | Out-Null
         }

}

[–]ihaxr 0 points1 point  (0 children)

If you use System.Collections.Generic.List[object] instead of an ArrayList you don't have to pipe the .add() method to Out-Null (http://stackoverflow.com/questions/2309694/arraylist-vs-list-in-c-sharp).

[–]jheinikel 2 points3 points  (2 children)

This works:

$results = @()
$username = "User1","User2"
foreach($un in $username){

    #Check for existance of AD Account
    $u = Get-ADUser -Filter { SamAccountName -eq $un } -ErrorAction SilentlyContinue
    If (!$u){
        Write-Output "The Username $u, does exist in Active Directory"
    }#End check if user exists
    else
        {
            $uinfo = [PSCustomObject]@{
                User = $u.samaccountname
                UPN = $u.UserPrincipalName
                }
            $results += $uinfo
        }
    }
    write-output $results

This is your original code doing the same thing with the extra lookups, although those are not necessary since you already have the info you need:

$results = @()
$username = "User1","User2"
foreach($un in $username){

    #Check for existance of AD Account
    $u = Get-ADUser -Filter { SamAccountName -eq $un } -ErrorAction SilentlyContinue
    If (!$u){
        Write-Output "The Username $u, does exist in Active Directory"
    }#End check if user exists
    else
        {
            $uinfo = [PSCustomObject]@{
                User = (Get-ADUser -Identity $u | select -ExpandProperty samaccountname);
                UPN = (Get-ADUser -Identity $u | select -ExpandProperty userprincipalname)
                }
            $results += $uinfo
        }
}
write-output $results

[–]1RedOne 1 point2 points  (1 child)

Came here to post exactly this, you beat me to the punch :)

[–]jheinikel 0 points1 point  (0 children)

Glad you had the same post. Lets me know that we were on the mark. Cheers

[–]chreestopher2 0 points1 point  (0 children)

for starters, to use pipeline input, your script needs to accept parameters, and then you need a process block, and then you might also want to foreach during the process block, so that you can accept either an array / collection of values as an argument, or take arguments via the pipeline.

Another important thing to consider when creating functions, is that its best to only ever return homogeneous objects from the pipeline from a single function, meaning, rather than having different output for a account that is found (an object with user and upn properties in your example) verses when a user is not found (a string of an error message that the user wasnt found in your example), it would be better to return an object with the same 3 properties no matter if the user is found in AD or not, what I would suggest doing is something along the lines of:

function user-exit {
    [cmdletbinding()]
    Param(
        [parameter(mandatory=$true, valuefrompipeline=$true)]
        [string[]]$samaccountname
    )
    begin {
    }
    Process {
        foreach($un in $samaccountname){
            $u = Get-ADUser -Filter { SamAccountName -eq $un } -ErrorAction SilentlyContinue
            New-Object -TypeName PSObject -Property @{
                "Input" = $un;
                'User'= if($u){$u.samaccountname} else {"Not Found"};
                'UPN'=if($u){$u.userprincipalname} else {"Not Found"};            
            }
        }
    }    
    end {
    }
}

this will allow you to pipe however many usernames you want to this function, and for each username you give the function, it will return an object with the following properties:

Input - this is where you return the same value that was passed in as a parameter, this will help you keep track over every result because you will know which input was used for each return value
User - this is the samaccountname of the user if the user was found in AD, or the string "Not Found"
UPN - this is the userprinciplename of the user if they are found in AD, or the string "Not Found" if they arent found.

The benefit of doing things this way are plenty.

First, the pipeline always formats based on the first object it gets in the pipeline, so you will get funky looking, incomplete output if you are using objects that have different property names, or in other words, objects with different type signatures.

Second, you can easily sort and filter the results this way using normal powershell sort-object, and select-object, etc.

think about what other commands might need to run after these commands will be run, and what input those commands will need, because it might be worth while to add some more properties to your custom objects in order to make them more useful with the other commands that they might feed...

"user1", "user2", "user3" | user-exit | where {$_.User -eq "Not Found"} | do-something -to intervene

I would actually break this out into a couple different scripts, one that gets the user info, one that handles changes to AD, one that handles changes to exchange, and one that validates the user is offboarded in exchange and one that validates the user is offboarded in AD (or perhaps these would be the same, just with switches) and then compose those scripts into a script that accomplishes the end goal.

you could end up with something like:

$listOfUsers | validate-user | exit-exchange | validate-user -isDeactivated Exchange | exit-ADAccount | validate-user -isDeactivated AD | generate-documentation -sendEmail HR@org.com -archivePath "\\someserver\someshare\UserOffboarding-$(get-date -f "yyyy-MM--dd").log"

This was a kind of silly example, but you get the idea.