blog.natfan.io

Rants and ravings from a techy brit.
(Now hosted on DigitalOcean!)
Dark Mode?

Proxy Addresses

Posted 5 months ago.

So a few weeks ago at work I wrote a new script. It did a lot of things, but it basically boils down to the following:

  1. Get all the newly created accounts from our UAM team.
  2. Run a process on the local Active Directory and Exchange servers to change their primary SMTP from [email protected] to [email protected], along with adding in [email protected] and [email protected] as a secondary SMTP address.
    • The [email protected] is because of the wierd way our emails are set up. We used to not run Exchange as standard, so you need the @exchange.domain.com subdomain in order to force emails to go to the right place. I know, it's a mess, but we can't easily get rid of our NIS/EXIM architecture without pulling the plug on 5k+ emails for a bit...
  3. Connect to MSOL (ew, I know) and find when the next ADSync will occur. Add 5 minutes to that just to make sure that the sync completes, then wait.
    • We do a delta sync every 30 minutes, it's unlikely that it will take more than 5 minutes to run as we don't do much change in 30 minutes.
  4. Once that sync has done and we've waited another 5 minutes, then create a new migration batch and submit it to Office365 in order for accounts that I just edited to be pushed to our cloud environment.

Not too bad, you'd think. What could go wrong? It's just 130 lines, including "self-documenting code" (it tells you what it's going to do, does it, then tells you what it's done). Well, dear reader, that's where you underestimate my ability to 🦆 things up!

One of the commands I run is as follows:

Set-OPMailbox
  -Identity $Username `
  -EmailAddresses @( `
    "SMTP:$PrimaryEmail", `
    "smtp:[email protected]", `
    "smtp:[email protected]" `
    "smtp:[email protected]" `
  )

Set-OPMailbox is the same as Set-Mailbox, however I add the OP bit to distinguish what's an on-premisis command and what's an Exchange Online command.

That's the final version of the command, which works like a dream. The problem is, one iteration of the command was as follows:

Set-OPMailbox
  -Identity $Username `
  -EmailAddresses @( `
    "SMTP:$PrimaryEmail", `
    "[email protected]", `
    "[email protected]" `
    "[email protected]" `
  )

You would have thought that invalid proxyAddresses just get ignored, right? WRONG. SO WRONG. The following is an extract of an error that a user sent me when they tried to send an email from their personal Gmail address:

[email protected]
The server has tried to deliver this message, without success, and has stopped trying.
Please try sending this message again. If the problem continues, contact your helpdesk.

That's right. If one proxyAddress is wrong, then all emails fail to send to that account. In the words of that one old Granny:

wat

Luckily, I know PowerShell. I wrote this (in my opinion) pretty sick one-liner: (Ignore the spacing, I wrote it in the terminal so it counts as a one-liner, right?)

foreach ($User in $(
      Get-ADUser -Filter {
        whenCreated -ge (Get-Date 2019-11-01T00:00:00)
      }
    ) -Properties proxyAddresses
  ) {
  foreach ($ProxyAddress in $User.proxyAddresses) {
    if (-NOT 
      $ProxyAddress -like "smtp:*" -or
      $ProxyAddress -like "x500:*" -or
      $ProxyAddress -like "x400:*" -or
      $ProxyAddress -like "sip:*")
    ) {
      "$($User.sAMAccountName) : $ProxyAddress"
      Get-ADUser $User | Set-ADUser -Remove @{proxyAddresses=$ProxyAddress}
    }
  }
}

Let's go through that section-by-section, shall we?

foreach ($User in $(
      Get-ADUser -Filter {
        whenCreated -ge (Get-Date 2019-11-01T00:00:00)
      }
    ) -Properties proxyAddresses
  ) {
...

This bit gets all of the users that were created on or after 2019-11-01 at midnight, and also gets all their proxyAddresses. Each user in that list is assigned to the variable $User.

foreach ($ProxyAddress in $User.proxyAddresses) {
...

This bit loops through all of the proxyAddresses for each of the users that we got from the last section, and assigns each of them to the $ProxyAddress variable

if (-NOT 
  $ProxyAddress -like "smtp:*" -or
  $ProxyAddress -like "x500:*" -or
  $ProxyAddress -like "x400:*" -or
  $ProxyAddress -like "sip:*")
) {
...

This bit checks each of the proxyAddresses, and only provides us with the proxyAddresses that do NOT start with smtp:, x400:, x500: or sip:. Basically, all of the prefixes that we use in my environment.

"$($User.sAMAccountName) : $ProxyAddress"
Get-ADUser $User | Set-ADUser -Remove @{proxyAddresses=$ProxyAddress}

This final bit does two things. The first line just lists the user's sAMAccountName and the proxyAddress that is affected by the "lack of prefix" issue. The second line gets the user that we're at in the list, and removes the offending proxyAddress.

Running that command gives me a fair few users that have been affected by my mistake, but rerunning that it without that final line (Get-ADUser | Set-ADUser ...) will return no output. Boom, we fixed it!

Anywho, this turned into a bit of a long post but I hope I helped you learn something! Thanks for reading!

xoxo,

-nat