User report with hyperlinks

I had a request last week to report on potential name clashes when we migrate some users into our active directory.  I wrote a simple script to read in the logon name for ach user to import and check if it already existed in my AD forest.  I then started thinking how I Might present this information and it occurred to me that I could use a HTML report, mainly because when I searched my archive of code I’d previously used I found an example that did exactly this in one line virtually too which was quite cool, although I can’t remember where I got this tip from:

# create some formatting for the HTML file

$a = “<style>”
$a = $a + “BODY{font-family: Verdana, Arial, Helvetica, sans-serif;font-size:10;font-color: #000000}”
$a = $a + “TABLE{border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}”
$a = $a + “TH{border-width: 1px;padding: 0px;border-style: solid;border-color: black;background-color: #E8E8E8}”
$a = $a + “TD{border-width: 1px;padding: 0px;border-style: solid;border-color: black}”
$a = $a + “</style>”

#Body text, pretty much just the report title:

$b = “<H2>All users found where the name includes: $strUserName</H2>”

$arrUsers | select-object EmployeeID,sAMAccountname,Domain,DisplayName,mail,AccountIsDisabled | sort EmployeeID |ConvertTo-HTML -Title “Lookup for $strUserName” -head $a -body $b | Set-Content $HTMLFile

Now you could open the HTML file and it will show you the details in a nice table.

After compiling this report I looked at the report and thought that I could go one better and set a hyperlink to the user object so it would display all of the attributes in the ARS web portal.  This meant I couldn’t use the trick above but it;’s not much more difficult to write your own HTML report from scratch.

the way I do this is usually to use one of the web based HTML editors and create a dummy table with all the date set as place holders, e.g. [USERNAME],[DISPLAYNAME].  then once I have this in note pad I set up a few variables to hold the parts of HTML that I will dynamically put together as my script runs.  I use HERE strings so that I don’t need to double escape any quotes in the HTML string

$HTMLHeader = @”
<!–DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Strict//EN” “”&gt;


All users found where the name is in the input file




Notice in the rowTemplate I have a URL as a hyper link I’ll explain how I get this later.

$rowTemplate =@”
<td><a href=”[URL]”>[userName]</a></td>

$HTMLEnd = “</table></body></html>”

I then create an array of user objects I want in my report


In my table I’m going to include a hyperlink for the username that will link to the user object in the ARS web portal.  How I work this out is I searched the ARS web portal for a known user and grabbed the hyperlink.  then I split this out into it’s component parts in the same way as I did for the HTML table template.

$stubURL =;

then I need to create some variables that will be used to replace the elements of the users DN that I will get from the user object – these are the HTML translations of cn=, ou= and dc=
$cn = ‘CN%3d’
$ou = ‘%2cOU%3d’
$dc = ‘%2cDC%3d’

Now I start building my HTML output

$HTMLOutput = $HTMLHeader

All that remains is to loop for each user object I have and create a new rowTemplate  each user.  For each user I just replace the characters in the DN with the variables I defined above and the place holders in the rowTemplate and then add that line to the HTMLOutput variable.

ForEach ( $user in $users ) {
$ADUser = Get-QADUser -SamAccountName $user.UserName -IncludedProperties employeeID,PrimarySMTPAddress -Connection $ARSconnection

if ( ! $ADUser ) { continue }
$userObj = “” |
select employeeID,sAMAccountname,Domain,DisplayName,mail,AccountIsDisabled,URL
ForEach ( $returendUser in $ADUser ) {
$userObj.EmployeeID = $returendUser.EmployeeID
$userObj.sAMAccountname = $returendUser.sAMAccountname
$userObj.Domain = $returendUser.Domain.Name
$userObj.DisplayName = $returendUser.DisplayName
$userObj.mail = $returendUser.PrimarySMTPAddress
$userObj.AccountIsDisabled = $returendUser.AccountIsDisabled
$userDNConverted = $returendUser.DN.Replace(“CN=”,$cn)
$userDNConverted = $userDNConverted.replace(“,OU=”,$ou)
$userDNConverted = $userDNConverted.replace(“,DC=”,$dc)
$userDNConverted = $userDNConverted.replace(” “,“+”)
$userDNConverted = “$stubURL$userDNConverted”
$userObj.URL = $userDNConverted
$HTMLRow = $rowTemplate.replace(“[userName]”,$returendUser.sAMAccountname)
$HTMLRow = $HTMLRow.replace(“[employeeID]”,$returendUser.employeeID)
$HTMLRow = $HTMLRow.replace(“[URL]”,$userDNConverted)
$HTMLRow = $HTMLRow.replace(“[domain]”,$returendUser.Domain.Name)
$HTMLRow = $HTMLRow.replace(“[displayName]”,$returendUser.DisplayName)
$HTMLRow = $HTMLRow.replace(“[enabled]”,$returendUser.AccountIsDisabled)
$HTMLRow = $HTMLRow.replace(“[mail]”,$returendUser.PrimarySMTPAddress)
$HTMLOutput += $HTMLRow
$ADUsers += $userObj

all that’s left to do now is output the data and if you like open IE and display it

$HTMLOutput += $HTMLEnd

Out-File -FilePath $HTMLFile -InputObject $HTMLOutput

Invoke-Item $HTMLFile

I use this technique when creating emails too.  A formatted HTML email is so much better than a plain text email with no formatting.  With HTML you can control ho wit looks and it will look much more professional and a finished product.  Create a template email with place holders and replace the text with .replace, simples.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.