Thursday, 11 June 2015

Creating object tables with Powershell

One of the useful things you get with Powershell is lots of functions that create data tables in memory that you can cycle through using Foreach to get an instance (equivalent to a record or row in a regular database) and then interrogate its properties (equivalent to columns). The Foreach loop automatically steps through all the object instances in the table.

Having done a number of function calls (for example Import-CSV to get a list of users from a CSV file, or Get-ADUser with a search spec to retrieve a bunch of user accounts) I thought it was about time I worked out how to create an object table myself, so that I could populate it with some user account data and then write it all out to a CSV file, using Export-CSV in this case. 

Well it turned out to be exceptionally simple to do this. Basically, object tables are just arrays of objects. Here is some code to illustrate this.

$UserList = @()
foreach ($Class in $Classes)
{   
$ADStudents = Get-ADUser -Filter  {Division -eq $Class} -SearchBase  "ou=Students,ou=School,dc=our,dc=school" -SearchScope Subtree -Properties ipPhone   
if ($ADStudents -ne $null)   
         foreach ($S in $ADStudents)
        {           
$username = $S.samAccountName           
$pwd = $S.ipPhone           
if ($pwd -eq $null)           
{               
    $pwd = ""           
}           
$UserList += New-Object psobject -Property @{Class = $($Class);Username=$($Username);Password=$($pwd)
}        
}   
}
}
So in this script, which loops through a set of classes ($Classes is an array of names of classes) the first line is to create the table itself, with no rows and no columns just yet. This is the simple $UserList = @() call which is actually creating an array.

Then the first Foreach loop is to go through a predefined array of class names for the school, and it gets the name of the current class into $Class. Then it gets all of the student accounts which have that class specified in their Division property. Note that it also retrieves the IpPhone property, which is used to store the passwords that we want to have a list of.

So the next step is to find out if we retrieved any results, and if so, another foreach loop has the task of getting each instance in turn (because the results of the Active Directory call are returned in an object table themselves) and then we add a row or record to $UserList. Firstly we create an object instance in which to store the data, and then we specify that the properties of that instance are Class, Username and Password, and the values they contain. 

It's useful to note here there is no fixed structure for each row, because each row only needs to be an object, and each row could easily refer to a different object structure, with different property names. This is a key difference from a regular database which predefines column names and types so they are consistent throughout the dataset. Obviously I am keeping things simple here and making every object instance identical.

So that is how we create our table, and the final line of the script (not shown) is a simple call to Export-CSV to write out the table to disk.