Inform Active Directory Users of Password Expiration

Sometimes your Active Directory users will appreciate receiving notifications of when their passwords are about to expire. Having your CEO call you on your day off to let you know that they can’t login because their password has expired is never fun.

Creative Commons [by-nc-nd]

Here is a simple Powershell script that you can use to easily send out emails to users with impending password expiration.

All you will need to modify is the “-From” address and the “-SmtpServer” address on line 13 to suit your environment, and potentially the “5” on line 28 to adjust the number of days until expiry that will trigger the email to be sent.

Import-Module ActiveDirectory

function Get-PasswordExpirationDays ($User)
{
    (([datetime]::FromFileTime((Get-ADUser –Identity $User -Properties "msDS-UserPasswordExpiryTimeComputed")."msDS-UserPasswordExpiryTimeComputed"))-(Get-Date)).Days
}

function Send-ExpirationEmail ($expDays,$expEmail,$expFirst,$expLast)
{
    if ([int]$expDays -eq 1) { $expNoun = "day" } else { $expNoun = "days" }
    $expSubject = "Your computer password will expire in $expDays $expNoun"
    $expBody = "Our records indicate that your computer password is due to expire in $expDays $expNoun`r`n"
    Send-MailMessage -From [email protected] -To $expEmail -Subject $expSubject -SmtpServer "smtp.example.com" -Body $expBody
}

$Users = Get-AdUser -filter { passwordNeverExpires -eq $false -and enabled -eq $true }

ForEach ($User in $Users)
{

    $CurrentUser = "" + $User.SamAccountName + ""
    $CurrentEmail = "" + $User.UserPrincipalName + ""
    $CurrentFirst = "" + $User.GivenName + ""
    $CurrentLast = "" + $User.Surname + ""
    
    if ($CurrentEmail -ne "") {
        $CurrentExpiration = Get-PasswordExpirationDays $CurrentUser
        if ([int]$CurrentExpiration -ge 0 -and [int]$CurrentExpiration -le 5 -and $CurrentEmail -notlike "*local*") {
            Write-Host "$CurrentExpiration - $CurrentEmail"
            Send-ExpirationEmail $CurrentExpiration $CurrentEmail $CurrentFirst $CurrentLast
        }
    }

}

Run the script via Task Scheduler once a day, and you’re all set.

However, any decision you might make towards implementing such a mechanism needs to be considered as part of your broader security policy. It may not be appropriate for your organisation, and I make no warranties towards your use of the above code.

Nevertheless, this is a quick and easy way to achieve the goal, if it is right for you.

The Little Server That Could

Eight months ago, we had a catastrophic sequence of failures that – (as one of several consequences) – brought down our web infrastructure at the place of employment.

Due to the nature of some of those consequences, we weren’t able to immediately bring that web infrastructure back up on any of our tier 1 equipment.

So I had to compromise.

Running around the office, I scrounged the most powerful PC I could find, and as much memory as possible to run up a temporary hypervisor – (Xen) – then copy the virtual hard disks off our storage array, fire all four virtual machines up on this temporary hardware, and finally get the suite of corporate websites back up and running.

I also didn’t have a switch to connect it all back up to the fibre link serving our websites. You’ll notice in the picture of this Frankenstein below, a Telstra VDSL NBN business modem acting as the switch. It was just laying around!

Yes – one of these!

Given the fibre link is 100Mbps, and the “switch” is a 1000Mbps “switch”, this shouldn’t have been a problem, but I was worried about the switching backplane of this little fellow. Was it going to be able to cope? I had my doubts.

And all of this was supposed to be temporary.

Temporary.

Right.

Got it.

Obviously, it didn’t work out that way, and it was eight months later that I was finally able to shut this “temporary” server down, having finally migrated everything back out onto proper hardware and networking again.

For eight months, this conglomeration hosted 28 corporate websites and served millions and millions and millions of web requests. I can’t tell you how many – if I’d known it was going to hang around for 8 months, I would have made provisions to log and find out exactly how many!

What I’m most proud of when it comes to this beast, is that nobody knew it was like that. The performance of the websites dropped only marginally – (almost negligibly) – and this thing just kept on trucking.

Day after day. Night after night. Week after week.

I lived in constant fear of arriving at the office each day and finding the little Telstra router melted into oblivion, or the PC itself having died.

But it never did, not once.

It was the little server that could, and I’m going to miss it!

The moral of the story is that even in the midst of massive IT disasters, there’s always a way – and that sometimes, the basics can get you by!

And above all, don’t panic!

Sunday Nerding: Columbia and STS-1

Tomorrow – (in Australian time at least) – is the 40th anniversary of the first flight of NASA’s Space Transportation System (STS) – better known to most people as the Space Shuttle.

That first flight was taken by OV-102 – (named “Columbia” at the time of commissioning) – on April 12th 1981, and marked America’s return to space for the first time since the Skylab space station was abandoned in 1974.

So it was a big deal. I clearly remember watching the launch on television at our home in Townsville, and the subsequent regular updates. For someone who was interested in the space program, but not having been alive or old enough to remember Apollo and Skylab, people in space again was amazing to me.

Astronauts John Young – (the ninth man to walk on the moon) – and Robert Crippen took Columbia into orbit that day for what amounted to a test flight – launch it, get it to orbit, and land it a couple of days later.

Columbia was of course lost in 2003 on return from space while completing STS-107, only the second shuttle lost after Challenger just after launch on STS-51L in 1986.

Sunday Nerding: Soyuz Clock

A while back, I published a link to a series of videos about the restoration of an Apollo Guidance Computer (AGC) – the computer that allowed man to travel to and land on the moon in 1969.

Now the same team have been working on a Soviet-era clock from a Soyuz spacecraft.

The clock is in pretty good condition, so won’t take the time and effort it took to restore the AGC, but for the electronic and space geeks, this is pretty cool too.

I will add to this playlist as more installments of their work is added.

Bitly’s V4 API – Sample PHP Code

Recently Bitly have rolled out version 4 of their API, and if you’re using the old API, it is quite a change.

While users were asked to move from older versions to the new version before March 1st 2020, the version 3 API was to hang around until March 31st 2020 to give people a little extra time to move.

Given the current COVID-19 situation, this discontinuation has been put on hold for the time being as per an email sent out to API users.

Nevertheless, it is absolutely time to move to the new version to ensure that you can still automate the shortening of your URLs.

Given my professional working life, I’ve worked with very similar API implementations, so for me it wasn’t a big deal to change over.

Here is the simple function I wrote for PHP, to do a basic URL shorten. Your PHP installation will need to have cURL and JSON libraries installed and enabled.

function shorten_url ($access_token,$group_guid,$shorten_domain,$shorten_url) {

  # setup the JSON payload
  $json_payload = @json_encode(Array(
    "group_guid"=>"".$group_guid."",
    "domain"=>"".$shorten_domain."",
    "long_url"=>"".$shorten_url.""
  ));

  # initialise cURL handle
  $curl_handle = @curl_init();

  # define cURL parameters
  @curl_setopt_array($curl_handle,Array(
    CURLOPT_URL => "https://api-ssl.bitly.com/v4/shorten",
    CURLOPT_RETURNTRANSFER => TRUE,
    CURLOPT_ENCODING => "",
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => TRUE,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "POST",
    CURLOPT_POSTFIELDS => $json_payload,
    CURLOPT_HTTPHEADER => Array (
      "Host: api-ssl.bitly.com",
      "Authorization: Bearer ".$access_token."",
      "Content-Type: application/json",
    ),
  ));

  # execute the cURL request
  $json_output = @curl_exec($curl_handle);

  # decode the output and get the HTTP response code
  $json_decoded = @json_decode($json_output);
  $http_code = ""[email protected]_getinfo($curl_handle,CURLINFO_HTTP_CODE)."";

  # return results for further processing
  return(Array("json"=>$json_decoded,"http"=>$http_code));

}

The inputs are relatively straight forward:

$access_token – this is the same as your existing OAuth application access token – this has not changed, at least in my case.

$group_guid – this is the only new piece of information you might need. While you can query for this value via the API, for most people the simplest way to get it is to open into your Bitly account in a web browser, where you will find the GUID in the URL, as per this image:

$shorten_domain – if you have a custom domain – (for example, I have the domain “mwyr.es” for shortening purposes) – this is the value you need here. If you don’t have a custom domain, just use “bit.ly”.

$shorten_url – this is the URL you wish to shorten – simple!

So now you can call the function, with the required information.

Firstly, the input data required by the API is converted to JSON via the json_encode() function.

Secondly, we set up the cURL handle, and then supply it with the required data. Note the JSON data is passed within the “CURLOPT_POSTFIELDS” variable, and that the access token is passed as the “Authorization: Bearer” header in the “CURLOPT_HTTPHEADER” variable.

Then we execute with curl_exec() – and store and return the results for further processing.

That’s it!

To understand the returned JSON – (including the generated short link) – and the HTTP response codes, refer to the excellent Bitly API v4 documentation.

Sunday Nerding: Machine Learning

In today’s Sunday Nerding, we’re looking at what has become an increasing trend in data and data analysis – machine learning.

In simple terms, as described on Wikipedia, machine learning is:

Machine learning (ML) is the scientific study of algorithms and statistical models that computer systems use to perform a specific task without using explicit instructions, relying on patterns and inference instead.

Watch this video from former NASA engineer Mark Rober on what machine learning is in a practical sense, and how it can be used in a real-world scenario – in this case, sign stealing in baseball.