Tuesday, 3 February 2015

Using Powershell with Active Directory [3]

So continuing on my Powershell with AD series, here is my student account script newly written in Powershell which is calling Get-ADUser to look up accounts in Active Directory.

function AddStudent($StudentData)
{
    write-host "Add " + $StudentData.LName + " " + $StudentData.FName
}

function UpdateStudent($StudentData)
{
    write-host "Update " + $StudentData.LName + " " + $StudentData.FName
}

function RemoveStudent($StudentData)
{
    write-host "Remove " + $StudentData.samAccountName
}

function CreateSubjects($StudentData)
{
}
For now, my function calls are just stubs that tell me they were called and what function they perform. The code for the dirty work still has to be written.

#First check CSV input against AD
#EnrolNum,Lname,Fname,Class,Pwd,StudentID,Logon
$Students = Import-CSV -Path "C:\Users\Patrick\NewStudents.txt"
foreach ($Student in $Students)
{
    # Look up the student in Active Directory to see if they are a current member
        $StudentID = $Student.StudentID
        $CurrentStudent = Get-ADUser -Filter 'EmployeeID -eq $StudentID'
        if ($CurrentStudent -ne $null)
        {
            UpdateStudent($Student)   
        }
        else
        {
            AddStudent($Student)
        }
}

This part of the script is getting the student accounts in from a CSV file. The column names are in the first line of the file and have to be exactly as shown. Then when I reference a row, I can use the same column name that was specified in the CSV file. We used the EmployeeID field in Active Directory to store the StudentID which in this case is the primary key from the database of the Student Management System. Even if the student's name changes, this number never changes. We assume there is only one result from the search, as there should be, and if the result is null (nothing found) we call our AddStudent function to add the account; otherwise we call UpdateStudent to update any changes to the student's data, such as their username.

#Next check AD against CSV
$ADStudents = Get-ADUser -Filter * -SearchBase "ou=HCS-Students,dc=hcs,dc=local" -SearchScope Subtree -Properties employeeID
foreach ($ADStudent in $ADStudents)
{
    $found = $false
    foreach ($Student in $Students)
    {
        if ($Student.StudentID -eq $ADStudent.EmployeeID)
        {
            $found = $true
            break
        }
    }
    if ($found -eq $false)
    {
        RemoveStudent($ADStudent)
    }
}


The main function of this block of code is to do a reverse lookup from the existing accounts in Active Directory to see if these accounts are found in the CSV file. If not, then RemoveStudent is called to disable their account and archive their home drive. Note that in this case we have set the filter to * (all accounts) and instead have used SearchBase and SearchScope to specify where to find the accounts in AD. We also have to use the Properties parameter to get EmployeeID back from AD because it isn't in the set of default properties returned.


In theory Where-Object should make it possible to do the reverse lookup but I wasn't able to make this work so I have the double Foreach loops with the breakout capability in the inner loop. It's still fast enough.

#Now create the subject links for the students
$AllStudents = Get-ADUser -Filter 'enabled -eq $true' -SearchBase "ou=HCS-Students,dc=hcs,dc=local" -SearchScope Subtree
foreach ($Student in $AllStudents)
{
    CreateSubjects($Student)
}
The last piece of code is to do with setting up subject folders in the student's home drive and then creating junctions to them for the teacher to find those folders when they are marking work. This time in addition to SearchBase and SearchScope we have used a filter to find accounts that are enabled. The code needs to be improved so that it also updates subjects such as when a new subject is added. Command line parameters are also needed to allow it to handle only a partial input file such as would be received to add only one or two accounts at a time, instead of the full start of year file.

Well that is enough for now and next time I will post the extra code for the full working version of the script.