Thursday, 31 January 2019

Powershell Script to Create Random Complex Passwords suitable for O365



This script enables you to generate a set of random complex passwords for a list of users which is imported as a CSV file.  The password will contain upper and lowercase letters, symbols, numbers and will always be between 8-16 characters in length (meeting the O365 requirements).  Obviously the functions can be tweaked to make the passords more or less secure and the script could be altered to add more sections to the password.  Remember each time a function is called within the foreach, the variable name will need to be different in order to stop the same part of the password repeating.  That’s why there are multiple random symbol and random numbers.




$JobStart = Get-Date

$userlistpath = "C:\cloudwyse\users_requiring_passwords.csv"

$wordlistpath = "C:\cloudwyse\dictionary.csv"

$DateTime = (Get-Date -Format "ddMMyyyy-HHmmss")

$exportpath = "C:\Cloudwyse\users_with_passwords$DateTime.csv"

Write-Host  -ForegroundColor Magenta "Importing lists from $userlistpath and $wordlistpath..."

$userlist = import-csv $userlistpath

$wordlist = import-csv $wordlistpath

$JobEnd = Get-Date

$JobSecondsTaken = ($JobEnd - $JobStart)

Write-Host -ForegroundColor Yellow "Lists imported taking" $JobSecondsTaken.Minutes "minute(s) and" $JobSecondsTaken.Seconds "second(s)."

$symbollist = @("`^","`!","`%","`&")

function RandomWord {$wordlist[(get-random -maximum 716)] | select-object -ExpandProperty Word}

function RandomNumber {get-random -minimum 10 -maximum 99}

function RandomSymbol {$symbollist[(get-random -maximum 4)]}

$total = $null

$Job2Start = Get-Date

$pwList = @()

foreach ($user in $userlist)     {

       $pwPart1 = RandomSymbol

       $pwPart2a = RandomWord

       $pwPart2 = (Get-Culture).TextInfo.ToTitleCase($pwPart2a.ToLower())

       $pwPart3 = RandomSymbol

       $pwPart4 = RandomNumber

       $pwPart5 = RandomNumber

       $longpass = "$pwPart1$pwPart2$pwPart3$pwPart4"

       if ($longpass.length -lt 8) {   

              do {

             $longpass += $pwPart5


             until ($longpass.length -ge 8)


       $password = $longpass.substring(0, [System.Math]::Min(16, $longpass.Length))

       $username = $user | Select-Object -ExpandProperty User

       $pw = New-Object PSObject

       $pw | Add-Member -type NoteProperty -Name 'User' -Value $username

       $pw | Add-Member -type NoteProperty -Name 'Password' -Value $password

       Write-Host  -ForegroundColor Magenta "Processed password for user" $username

       $pwlist += $pw

       $total = $total +1


$Job2End = Get-Date

$Job2SecondsTaken = ($Job2End - $Job2Start)

Write-Host -ForegroundColor Yellow "Processed $total passwords in" $Job2SecondsTaken.Minutes "minute(s) and" $Job2SecondsTaken.Seconds "second(s)."

Write-Host  -ForegroundColor Magenta "Exporting list..."

$pwList | Export-csv -Path $exportpath

Write-Host -ForegroundColor Yellow "Finished exporting list to $exportpath"



The CSV file I used for the dictionary can be downloaded here.




Monday, 21 January 2019

Powershell Script to export a list of all proxyaddresses for all users in the O365 tenant



This script allows you to export a list of all users in the tenant and all associated proxy addresses.  It’s helpful to be able to get this as a csv filer for future reference so that you can quickly filter on whichever user you like.  It’s also been helpful for me on a recent migration where I was able to make sure that each user’s email addresses were properly migrated.




$LogFilePath = $env:LOCALAPPDATA + "\Cloudwyse\Logs\user_proxy_addresses_" + $(get-date -Format ddMMyy_HHmmss) + ".log"

Start-Transcript -Path $LogFilePath -NoClobber

$365Pass = cat C:\cloudwyse\securestring365.txt | convertto-securestring

$365Cred = new-object -typename System.Management.Automation.PSCredential -argumentlist "",$365Pass

$DateTime = (Get-Date -Format "ddMMyyyy-HHmmss")


$365Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri -Credential $365cred -Authentication Basic -AllowRedirection

Import-PSSession $365Session

Connect-Msolservice -Credential $365Cred



Write-Host  -ForegroundColor Magenta "Pulling mailbox information for all users, please be patient..."

$JobStart = Get-Date

$getmailbox = get-Mailbox

$JobEnd = Get-Date

$JobSecondsTaken =($JobEnd - $JobStart)

Write-Host  -ForegroundColor Yellow "Extract complete.  The Job took" $JobSecondsTaken.Seconds "seconds."

$total = $null

$Job2Start = Get-Date

$userList = @()

foreach ($user in $getmailbox)   {

$lookup = get-msoluser -userprincipalname $user.userprincipalname

       Write-Host  -ForegroundColor Magenta "Current user is" $user.userprincipalname

       $addresses = $lookup.proxyaddresses

       foreach ($address in $addresses) {

       $us = New-Object PSObject

             $us | Add-Member -type NoteProperty -Name 'UPN' -Value $lookup.userprincipalname

             $us | Add-Member -type NoteProperty -Name 'ProxyAddresses' -Value $address

             Write-Host  -ForegroundColor Cyan "Address is" $address

             $userList += $us


       $total = $total +1



$Job2End = Get-Date

$Job2SecondsTaken =($Job2End - $Job2Start)

Write-Host -ForegroundColor Yellow "$total users processed in" $Job2SecondsTaken.Minutes "minute(s) and" $Job2SecondsTaken.Seconds "second(s)."

Remove-PSSession $365Session

$userlist | export-csv C:\Cloudwyse\user_proxy_addresses$datetime.csv

Write-Host -ForegroundColor Yellow "Report exported to C:\Cloudwyse\user_proxy_addresses$datetime.csv"




I’ve shared this before, but if you are unsure how to securely store credentials in a script without using plain text then follow the instructions here to create the securestring.txt.




Friday, 18 January 2019

Finally, a good but concise explanation of DMARC, DKIM and SPF - email security!



I’ve found that the information that’s out there about email authentication is either too detailed or too high level.  So I wanted to produce a quick guide for administrators that’s somewhere in between.

We have three principle technologies at play. These technologies work together to provide an email security foundation.

They are:

1.    Domain-based Message Authentication, Reporting & Conformance (DMARC)

2.    Sender Policy Framework (SPF)

3.    DomainKeys Identified Mail (DKIM)

These technologies protect the recipient of the email more than the sender.  That is the validate the authenticity of the email that you are SENDING.  However large scale adoption means that the online community is able to come together to authenticate each other’s email traffic to help eliminate the effectiveness of phishing and spam emails.


There are two ‘from’ addresses in an email.  The ‘header from’ (AKA friendly from) and the ‘envelope from’ (AKA return path).  An organisation hosts its own SPF record in DNS.  This record can be used by the receiving organisation to confirm that mail received is from a valid source.  That is the receiving organisation will check the DNS records for domain in the ‘envelope from’ field within the email header.  Eg “” to see if there is an SPF record.  If there is, then the server will check to see whether the mail was received from a server matching this record.  An example SPF record would be as follows:

v=spf1 ip4: -all


If you’d like more information please look at this article.


DKIM adds a digital signature the header section of an email.  This uses public key cryptography to ensure that the email was from a genuine source and that the message hasn’t been tampered with or altered en-route.

The sending server creates a signature using it’s private key.  This can be decrypted using the public key, which is stored in a text file within the sender’s DNS.  Due to the high level of security provided by public key cryptography, this method gives those receiving the email peace of mind that the email is genuine.

An example DKIM record would be as follows:

v=DKIM1; p=Es34dfgRGE55ehYRJ54JYRsfMTYesfsdNTNJSRefdgGg54t35tJSR



This relatively recent authentication method was developed in 2007 by PayPal, with collaboration later being offered by Yahoo! and Google.  DMARC is like the ‘digital doorman’ ensuring that every email’s name is on both the SPF and DKIM list. DMARC will match the ‘header from’ domain name with the ‘envelope from’ domain name obtained from the SPF check, and will also match the ‘header from’ domain name with the ‘d= domain name’ in the DKIM signature.  As well as carrying out these tests, DMARC is also used to inform recipient mail servers on what to do with any email that is suspected of not being genuine.

The sender can choose to:

·        Monitor all mail to gain an understanding of misuse of their brand name through spam email and to ensure genuine mail is authenticating properly.

·        Quarantine messages that fail DMARC ie ensure it lands in the recipient's spam folder

·        Reject messages that fail DMARC authentication ie request that the recipient's email server doesn't deliver the message at all.

An example DMARC record would be as follows:

"v=DMARC1; p=reject; pct=100;"


It is a combination of SPF, DKIM and DMARC together that offers confidence and security to businesses, customers and other internet users that an email is genuine and not a phishing attempt or spam.