0

I am trying to create a script that will check a list of user names and show the user full name and some attribute settings from AD. Basically I have been sent a list of usernames which are just numbers and management want to know the users full name for each username. they also want to know want division they work for.

Below is the script I have created which doesn't work.

$csv = Import-Csv "C:\temp\users.csv"

foreach ($user in $csv) {
    $name = $user.myid
    Get-ADUser -Filter {EmployeeID -eq $name} -Properties * |
        Get-ADUser -Division $user.Programme
} | Export-Csv "C:\Temp\Results.csv"
Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
D. BamBam
  • 5
  • 1
  • 4

3 Answers3

1

So I'm working under the assumption that there is a column named myid in your csv file that contains the id you need to be looking up. Assuming that is the case you'll need to make a few changes here. You'll need to remove the second get-aduser as it is not really doing anything for you, and there is no -division switch available to the get-aduser cmdlet, if you need to restrict your results to just a few settings you can do that using the -properties switch and piping to select as shown below. Keep in mind that none of this will matter if the users do not have the "employeeid" and "division" properties set on their AD accounts, which is fairly rare in my experience but if your company does as a matter of policy when creating accounts should be fine. If you replace the get-aduser line in your script with this it should get the account of any user with an EmployeeID property that matches the one in your spreadsheet and then output that person's full name, division, and employeeid to your CSV file.

Get-ADUser -Filter {EmployeeID -eq $name} -Properties "displayname","division","employeeid" | Select-Object "employeeid","displayname","division"
Will Webb
  • 795
  • 6
  • 20
Mike Garuccio
  • 2,588
  • 1
  • 11
  • 20
  • Thanks you, I didn't realise about the -Properties. I dropped the division as the info is I need is on a extensionAttribute also. I ended up doing based on their SamAccountName as looking the CSV file I was sent from HR the formatting was all over the place and managed to get their displayname and extensionattribute. I just love it when HR role out a new AD integrated system. – D. BamBam Mar 24 '17 at 15:50
0

When in doubt, read the documentation. Get-ADUser doesn't have a parameter -Division. You need to select the properties you want in the output file. Also, foreach loops don't pass output into the pipeline. You need a ForEach-Object loop if you want to pass the output directly into Export-Csv:

Import-Csv 'C:\temp\users.csv' |
    ForEach-Object {
        $name = $_.myid
        Get-ADUser -Filter "EmployeeID -eq $name" -Properties *
    } |
    Select-Object SamAccountName, DisplayName, Division |
    Export-Csv 'C:\Temp\Results.csv' -NoType

Otherwise you need to collect the output in a variable:

$users = foreach ($user in $csv) {
    $name = $user.myid
    Get-ADUser -Filter "EmployeeID -eq $name" -Properties *
}
$users | Export-Csv 'C:\Temp\Results.csv' -NoType

or run the loop in a subexpression:

$(foreach ($user in $csv) {
    $name = $user.myid
    Get-ADUser -Filter "EmployeeID -eq $name" -Properties *
}) | Export-Csv 'C:\Temp\Results.csv' -NoType
Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
0

This is a generic code structure that can be adapted for data collection / enumeration and production of CSV files, tailored to your scenario. We use similar at my workplace. It contains some error handling - the last thing you'd want is inaccurate results in your CSV file.

# Create an array from a data source:
$dataArray = import-csv "C:\temp\users.csv"

# Create an array to store results of foreach loop:
$arrayOfHashtables = @()

# Loop the data array, doing additional work to create our custom data for the CSV file:
foreach($item in $dataArray)
{
    try
    {
        $ADObject = Get-ADUser -Filter { EmployeeID -eq $item.MyID } -Properties DisplayName,Division -ErrorAction Stop
    }
    catch
    {
        Write-Output "$($item.MyID): Error looking up this ID. Error was $($Error[0].Exception.Message)"
    }

    if($ADObject)
    {
        # Create a hashtable to store information about a single item:
        $hashTable = [ordered]@{
            EmployeeID=$item.myID
            DisplayName=$ADObject.DisplayName
        }

        # Add the hashtable into the results array:
        $arrayOfHashtables += (New-Object -TypeName PSObject -Property $hashTable)
    }
    else
    {
        Write-Output "$($item.MyID): No result found for this ID."
    }
}

# If the results array was populated, export it:
if($arrayOfHashtables.Count -gt 0)
{
    $arrayOfHashtables | Export-CSV -Path "C:\Temp\Results.csv" -Confirm:$false -NoTypeInformation
}

As mentioned elsewhere, division isn't a property on an AD object so you might need to lookup this data elsewhere. If you can do that with another line of PowerShell inside your foreach loop, you could add this to your hashtable object like so:

$hashTable = [ordered]@{
    EmployeeID=$item.myID
    DisplayName=$ADObject.DisplayName
    Division=$DivisionFromOtherSource
}
Robin
  • 1,602
  • 3
  • 16
  • 24
  • Appending to an array in a loop is bound to perform poorly, because each append operation re-creates the array (with size increased by one) and copies all existing elements. Using this approach is not recommended and rarely necessary (if ever). – Ansgar Wiechers Mar 13 '17 at 16:33
  • Thank you - that's useful to know. However running multiple instances of this code structure against ~200 Windows servers, 550 VMs, and an AD of 30,000 users gives us no noticeable performance problems on a 4GB, 2vCPU Windows server that's used for collating reporting data (and no reported ones on the downstream servers). The main reason we use this basic structure is because it can be understood by PowerShell beginners and adapted easily. Again, thank you. – Robin Mar 13 '17 at 16:36
  • To give you a rough estimate: execution time of `$a = 1..10000 | %{$_}` vs `$a = @(); 1..10000 | %{$a += $_}` is 0.3 seconds vs 4.1 seconds. – Ansgar Wiechers Mar 13 '17 at 16:50
  • Interesting, but the first example just sends data to the standard output stream. What happens when you want to store that data elsewhere, like in a CSV file? In the second example, $a can be piped to Export-CSV. Would the first result in 10000 "-append"s to a CSV file? – Robin Mar 13 '17 at 17:03
  • Both examples assign a list of 10000 integers to the variable `$a`. The latter appends in a loop, the former assigns the pipeline output. Exporting to a CSV is irrelevant for this appraisal. The example is just to give you a ballpark number for append performance compared to direct assignment performance. The difference might not matter in your scenario, but it's something to keep in mind regardless. – Ansgar Wiechers Mar 13 '17 at 17:35
  • Gotcha. Sorry, I missed the assignment of $a = on the first example. That's really useful, thanks. Will see if this impacts real world performance with some of our monitoring scripts :) – Robin Mar 13 '17 at 17:36