Documenting with PowerShell: Increasing the Office365 Secure Score.

So previously we’ve spoken about documenting the Office 365 Secure Score. For a great resource on this I’d suggest you check out Eliot’s blog on documenting the Secure Score here. Its a fantastic resource.

This time I’m not going to focus on documenting the Secure Score directly – But increasing it. we want to make sure that the Secure Score is as high as possible with as little user impact as possible. To do this, I’ve selected some items that increase your secure score but have next to no impact on normal usage. Of course you’ll have to check if this is true for your environment too.

The Script

The script is set up to enable the following features for all tenants in your partner portal.

  • Move mail with a high confidence spam rating to the Junk Folder (Does not increase SecureScore, but was requested to add on Slack. You can remove this item if you only want the Secure Score increase)
  • Mailbox Auditing for all users
  • Mailbox Litigation hold where possible.
  • DelegateSentitemsStyle for mailboxes
  • NDR report for journaling.
  • Set the outbound spam filter reporting e-mail address
  • Set “Do not allow users to grant consent to unmanaged applications”
  • Disable password expire on user accounts
  • Enable the self-service password reset(I’d strongly recommend to first enable multi factor authentication for all your users.

I believe I could’ve added more features but I chose to only enable the ones with no to very little user impact. Using this script you can adapt it to all your wishes. It’s also very easy to disable one of the features – Just remove the the entire block of code that you do not want to enable.

#Set the recipient for outbound spam reports and Journaling NDRs.
$SpamAndEmailRecipient = "Helpdesk@limenetworks.nl"
#######################################################################
###################  CREDENTIALS     ##################################
$ApplicationId         = 'xxxx-xxxx-xxx-xxxx-xxxx'
$ApplicationSecret     = 'TheSecretTheSecrey' | Convertto-SecureString -AsPlainText -Force
$TenantID              = 'YourTenantID'
$RefreshToken          = 'RefreshToken'
$ExchangeRefreshToken  = 'ExchangeRefreshToken'
$upn                   = 'UPN-Used-To-Generate-Tokens' 
###################  END CREDENTIALS ##################################
$credential = New-Object System.Management.Automation.PSCredential($ApplicationId, $ApplicationSecret)

$aadGraphToken = New-PartnerAccessToken -ApplicationId $Applicatio nId -Credential $credential -RefreshToken $refreshToken -Scopes 'https://graph.windows.net/.default' -ServicePrincipal -Tenant $tenantID 
$graphToken = New-PartnerAccessToken -ApplicationId $ApplicationId -Credential $credential -RefreshToken $refreshToken -Scopes 'https://graph.microsoft.com/.default' -ServicePrincipal -Tenant $tenantID 

Connect-MsolService -AdGraphAccessToken $aadGraphToken.AccessToken -MsGraphAccessToken $graphToken.AccessToken
$customers = Get-MsolPartnerContract -All
foreach ($customer in $customers) {
    $token = New-PartnerAccessToken -ApplicationId 'a0c73c16-a7e3-4564-9a95-2bdf47383716'-RefreshToken $ExchangeRefreshToken -Scopes 'https://outlook.office365.com/.default' -Tenant $customer.TenantId
    $tokenValue = ConvertTo-SecureString "Bearer $($token.AccessToken)" -AsPlainText -Force
    $credential = New-Object System.Management.Automation.PSCredential($upn, $tokenValue)
    $customerId = $customer.DefaultDomainName
    $session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri "https://ps.outlook.com/powershell-liveid?DelegatedOrg=$($customerId)&BasicAuthToOAuthConversion=true" -Credential $credential -Authentication Basic -AllowRedirection
    Import-PSSession $session -AllowClobber -DisableNameChecking
    Write-Host "Starting process for client $($customer.name)" -ForegroundColor Green
    #Move mail with a high confidence spam to the Junk folder. 
    try {
        Get-HostedContentFilterPolicy -ErrorAction Stop | Set-HostedContentFilterPolicy -HighConfidenceSpamAction MoveToJmf -ErrorAction Stop 
    }
    catch {
        Write-Output "Failed to change the spam policy. $($_.Exception.Message)"
    }
    #Enable mailbox auditing for each user.
    try {
        Get-Mailbox -ResultSize Unlimited -ErrorAction Stop | Set-Mailbox -ErrorAction Stop -AuditEnabled $true -AuditOwner MailboxLogin, HardDelete, SoftDelete, Update, Move -AuditDelegate SendOnBehalf, MoveToDeletedItems, Move -AuditAdmin Copy, MessageBind 
    }
    catch {
        Write-Output "Failed to enable Mailbox auditing. $($_.Exception.Message)"
    }

    #Enable mailbox litigation hold
    try {
        Get-Mailbox -ResultSize Unlimited -ErrorAction Stop | Set-Mailbox -ErrorAction Stop -LitigationHoldEnabled $true -LitigationHoldDuration 2555 
    }
    catch {
        Write-Output "Failed to enable Mailbox Litigation hold. $($_.Exception.Message)"
    }
    #Enable DelegateSentItems.
    try {
        Get-Mailbox -ResultSize Unlimited -ErrorAction Stop | set-mailbox -ErrorAction Stop -MessageCopyForSentAsEnabled $true -MessageCopyForSendOnBehalfEnabled $true 
    }
    catch {
        Write-Output "Failed to enable DelegateSentItems style. $($_.Exception.Message)"
    }
    #Set Journaling NDR
    try {
        set-transportconfig -JournalingReportNdrTo "$SpamAndEmailRecipient" -ErrorAction Stop 
    }
    catch {
        Write-Output "Failed to set Transport Config Journaling NDR $($_.Exception.Message)"
    }
    #Set outbound spamfilter reporting
    try {
        Set-HostedOutboundSpamFilterPolicy "Default" -NotifyOutboundSpam $true -NotifyOutboundSpamRecipients $SpamAndEmailRecipient -ErrorAction Stop 
    }
    catch {
        Write-Output "Failed to set outbound spam settings $($_.Exception.Message)"
    }
    
    #Set "Do not allow users to grant consent to unmanaged applications"
    try {
        Set-MsolCompanySettings -tenantID $customer.TenantId -UsersPermissionToUserConsentToAppEnabled:$false -ErrorAction Stop 
    }
    catch {
        Write-Output "Failed to set Permissions to allow user to grant consent to unmanaged applications $($_.Exception.Message)"
    }
    #Disable password expire on accounts.
    try {
        Get-MsolUser -TenantId $customer.TenantId -ErrorAction Stop | Set-MsolUser –PasswordNeverExpires $true -ErrorAction Stop 
    }
    catch {
        Write-Output "Disable password expire failed. $($_.Exception.Message)"
    }

    #Enable Self Service Password Reset
    try {
        Set-MsolCompanySettings -TenantId $customer.TenantId -SelfServePasswordResetEnabled:$true -erroraction Stop
    }
    catch {
        Write-Output "Enabling Self Service Password Reset Failed. $($_.Exception.Message)"
    }


    Write-Host "Finished process for client $($customer.name)" -ForegroundColor Green
    Remove-PSSession $session
}

and that’s it! as always, Happy PowerShelling!

Kelvin Tegelaar
Follow me

Leave a Reply

Your email address will not be published. Required fields are marked *

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