Converting LastLogonTimeStamp from Active Directory to Datetime

I often find myself needing to convert the LastLogonTimeStamp attribute from Active Directory to Datetime with PowerShell. What I have done, is that in my PowerShell profile ($profile) I have added a function ConvertFrom-LastLogonTimeStamp to get the value as a Datetime.

Easier to remember!

function ConvertFrom-LastLogonTimestamp
        # LastLogonTimestamp from AD
        [String] $LastLogonTimestamp

    return [datetime]::FromFileTime($LastLogonTimestamp)

Playing around with the AADSync beta

The beta for the new AADSync tool has been released, and I have been playing around with it a little to discover whats in store and what we might expect from Microsoft Identity Manager (FIM vNext) when that comes out. This is a screenshot heave “try it for the first time and screenshot everything”-article. What I am trying is to see what the new rule editor can manage, and to see whether I can actually manage to provision users in a separate AD forest directly from AADSync.

I made it through the regular installation, which you can see documented somewhat here. This yielded a quite usual DirSync setup, but in miisclient.exe you cannot see attribute flows and filters. This is instead move to the “Synchronization Rules Editor”.

I started of creating a secondary AD management agent. The first ting i notice here is the amount of management agents available by default. This is in strong contrast to DirSync.

Not much to comment on in these screenshots, except for the fact that you cannot configure filters and attribute flow, everything is still FIM. New MA added:

Having a look at the default configure inbound and outbound rules in the new “Synchronization Rules Editor”.

I clicked “Add new rule”, and started on my inbound join rule for my “” AD, which is my second forest. I just want to see if I can provision user account into that forest based on the users in my “” primary forest.

Some new filtering possibilities available, that needed an extension before. However, there is no way of extending it yourself it seems.

Joining pager in AD with sourceAnchor in FIM.

I’ll just skip adding inbound attribute flow for now.

Added successfully.

The default list of outbound sync rules.

Trying to create a outbound provisioning rule to my “” forest.


Same join as the inbound rule.

Let’s just try some transformation and see if it works on first try!

It did.

Doing a full synchronization on the primary AD yields 71 adds to my second AD.

Looking good.

Seems right (wonder if I am missing some very important attribute?)

Exported successfully

Some changes not reimported (userAccountControl was wrong value)

I forgot the sAMAccountName too.

Just as before.

Some still giving error, due to sAMAccountName being more than 20 characters.

Let’s see if “Left” still exists.


One more thing. The new way of triggering “DirSync” is like below. Also notice that it is automatically triggering my custom added MA!

Looks good (except that it did not Delta sync on my custom MA, only import and export).

That’s it. As I said, just some screenshots to see what’s in store. I am starting to look forward to Microsoft Identity Manager / FIM vNext; hopefully this will be a part of it.

PowerShell script to find duplicate proxyaddresses

This script uses the Active Directory PowerShell module to locate duplicate proxyaddresses throughout your forest. The script must be run from a computer that have the AD PowerShell installed, and can reach all PDCEmulators in all domains in your forest.

Import-Module ActiveDirectory

# Create hashmap for proxyaddresses
$proxyaddresses = @{}

# For each domain in the forest
Get-ADForest | Select-Object -ExpandProperty Domains | Get-ADDomain | foreach {
    Write-Output ("Parsing domain {0} by contacting {1}" -f $_.Name, $_.PDCEmulator)
    # Get all AD objects that have proxyaddresses
    Get-ADObject -Filter {proxyaddresses -like "*"} -Properties proxyaddresses -Server $_.PDCEmulator | foreach {
        $_.proxyAddresses | foreach { $proxyaddresses[$_] += 1}

Write-Output "Done, looking for duplicates"
$duplicates = $proxyaddresses.Keys | where{$proxyaddresses[$_] -gt 1}

# Output proxyaddresses that are duplicates
if($duplicates) {
    Write-Output "The following proxyaddresses was found multiple times"
    $duplicates # | Out-Gridview # Remove first hash-sign in order to get an "Excel"-view. Needs PowerShell ISE.
} else {
    Write-Output "No duplicates found"

Virtual hosting with Apache – the good way

There are so many amazingly bad guides to Apache and virtual hosting, so i decided to create a good one. This guide uses Apache2 running om Debian 6. I will not cover installation and stuff. Also, I cut right to the chase.

First, the NameVirtualHost property should just be declared once, and ports.conf is a good place to have it.


NameVirtualHost *:80
Listen 80

Second, do not place all virtual hosts in a single file, that’s not very dynamic. Look at this:

# ls /etc/apache2/sites-*
total 8
dr-xr-x--- 2 root           www-data     3896 Jun 26 15:33 .
dr-x------ 5 www-data        www-data     3896 Jun  8 13:15 ..
-rwxr-x--- 1 root           www-data     569  Apr 11 21:51 default
-rwxr-x--- 1 root           www-data     569  Apr 19 11:40
-rwxr-x--- 1 root           www-data     569  Apr 19 11:41
-rwxr-x--- 1 root           www-data     569  Jun 26 15:25

total 0
dr-xr-x--- 2 www-data  www-data 3896 Jun 26 15:33 .
dr-x------ 5 www-data  www-data 3896 Jun  8 13:15 ..
lrwxrwxrwx 1 root   root  26 Apr 11 21:52 000-default -> ../sites-available/default
lrwxrwxrwx 1 root   root  41 Apr 19 11:49 -> ../sites-available/
lrwxrwxrwx 1 root   root  41 Apr 19 11:50 -> ../sites-available/
lrwxrwxrwx 1 root   root  37 Jun 26 15:29 -> ../sites-available/

So what am I doing that no one else is doing? I am symlinking, and I am splitting each domain or subdomain into separate files. Just use place all the domains in the sites-available folder, and symlink it from sites-enabled. This makes it easy to disable sites temporary, by just removing the symlink and reloading apache. Lets take a look one of those files.


<VirtualHost *:80>
        # ServerAlias

        DocumentRoot /home/mariussm/websites/

        <Directory />
                Options FollowSymLinks
                AllowOverride None

        <Directory /home/mariussm/websites/>
                Options FollowSymLinks MultiViews
                AllowOverride All
                Order allow,deny
                allow from all

        ErrorLog ${APACHE_LOG_DIR}/

        # Possible values include: debug, info, notice, warn, error, crit,
        # alert, emerg.
        LogLevel warn

        CustomLog ${APACHE_LOG_DIR}/ combined


As you can see, it listens on all interfaces (*:80) on port 80, cares only for the hostname and has a root folder. So hey, that’s the easy way.