PS - Disable OWA for O365 users via Scheduled Task


I had a situation where I needed to disable OWA access for a client for all mailboxes. As this is a per mailbox setting I need to a script to process all of the users on a scheduled basis for a couple of reasons:
  • To ensure when new users were created they had OWA disabled.
  • To re-disabled them if someone had manually enabled OWA on an account.


Of course this is a not a secure solution as any admin can simply re-enable OWA for the mailbox, but it will do the job if just a soft-disable is required.

First create a script directory on your management server in this example we'll use D:\Scripts\DisableOWA and also a Logs directory D:\Scripts\DisableOWA\Logs


Visit  - https://blogs.technet.microsoft.com/exoshellwizard/2016/05/12/scheduling-a-task-against-exchange-online/ and save the New-StoredCredential.ps1 and Start-AutomatedScript.ps1

Visit https://gallery.technet.microsoft.com/office/Start-RobustCloudCommand-69fb349e  and save the Start-RobustCloudCommand.ps1 to the same directory.

Now to save your password as a secure string, by executing D:\Scripts\DisableOWA\New-StoredCredential.ps1 -Path D:\Scripts\DisableOWA\O365Account.txt -Password "yourpasswordhere"

Now you need to amend the constraints (and optionally the command if you wish it to do something else) within the Start-AutomatedScript.ps1 file. I've highlighted areas in red of the script that will need changing.

# Constants
[string]$FileAppend = (Get-Date -Format mmddyyyy_) + (Get-Random -Maximum 9999)
$OutputFile = "D:\Scripts\DisableOWA\Logs\output" + $FileAppend + ".csv"
$Username = "YouOffice365AdminAccount@company.onmicrosoft.com"
$LogFile = "D:\Scripts\DisableOWA\Logs\DisableOWA.log"
$ExportRecipients = "D:\Scripts\DisableOWA\Logs\recipients.csv"
$PasswordPath = "D:\Scripts\DisableOWA\O365Account.txt"


# Writes output to a log file with a time date stamp
Function Write-Log {
    Param ([string]$string)
    
    # Get the current date
    [string]$date = Get-Date -Format G
        
    # Write everything to our log file
    ( "[" + $date + "] - " + $string) | Out-File -FilePath $LogFile -Append
    
    # If NonInteractive true then supress host output
    if (!($NonInteractive)){
        ( "[" + $date + "] - " + $string) | Write-Host
    }
}

# Setup a new O365 Powershell Session
Function New-CleanO365Session {
    
    # If we don't have a credential then prompt for it
    $i = 0
    while (($Credential -eq $Null) -and ($i -lt 5)){
        $script:Credential = Get-Credential -Message "Please provide your Exchange Online Credentials"
        $i++
    }
    
    # If we still don't have a credentail object then abort
    if ($Credential -eq $null){
        Write-log "[Error] - Failed to get credentials"
        Write-Error -Message "Failed to get credentials" -ErrorAction Stop
    }

    Write-Log "Removing all PS Sessions"

    # Destroy any outstanding PS Session
    Get-PSSession | Remove-PSSession -Confirm:$false
    
    # Force Garbage collection just to try and keep things more agressively cleaned up due to some issue with large memory footprints
    [System.GC]::Collect()
    
    # Sleep 15s to allow the sessions to tear down fully
    Write-Log ("Sleeping 15 seconds for Session Tear Down")
    Start-sleep -seconds 15

    # Clear out all errors
    $Error.Clear()
    
    # Create the session
    Write-Log "Creating new PS Session"
    
    $session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri "https://outlook.office365.com/powershell-liveid/" -Credential $Credential -Authentication Basic -AllowRedirection
        
    # Check for an error while creating the session
    if ($Error.Count -gt 0){
    
        Write-Log "[ERROR] - Error while setting up session"
        Write-log $Error
        
        # Increment our error count so we abort after so many attempts to set up the session
        $ErrorCount++
        
        # if we have failed to setup the session > 3 times then we need to abort because we are in a failure state
        if ($ErrorCount -gt 3){
        
            Write-log "[ERROR] - Failed to setup session after multiple tries"
            Write-log "[ERROR] - Aborting Script"
            exit
        
        }
        
        # If we are not aborting then sleep 60s in the hope that the issue is transient
        Write-Log "Sleeping 60s so that issue can potentially be resolved"
        Start-sleep -seconds 60
        
        # Attempt to set up the sesion again
        New-CleanO365Session
    }
    
    # If the session setup worked then we need to set $errorcount to 0
    else {
        $ErrorCount = 0
    }
    
    # Import the PS session
    $null = Import-PSSession $session -AllowClobber
    
    # Set the Start time for the current session
    Set-Variable -Scope script -Name SessionStartTime -Value (Get-Date)
}

##### Main #####

# Read the password from the file and convert to SecureString
Write-log "Getting password from $passwordpath"
$SecurePassword = Get-Content $PasswordPath | ConvertTo-SecureString

# Build a Credential Object from the password file and the $username constant
$Credential = New-Object System.Management.Automation.PSCredential -ArgumentList $Username, $SecurePassword

# Connect to O365
New-CleanO365Session

# Get the Recipients to work with
Write-Log "Getting Recipients"
$Recipients = invoke-command -session (get-pssession) -scriptblock {get-mailbox -resultsize unlimited | select-object -property DisplayName,Identity,PrimarySMTPAddress}

# Export them to CSV for documentation
Write-Log "Exporting " + $Recipients.count + " to csv " + $ExportRecipients
$Recipients | Export-Csv $ExportRecipients

# Call Start-RobustCloudCommand to gather the data
# https://blogs.technet.microsoft.com/exchange/2015/11/02/running-powershell-cmdlets-for-large-numbers-of-users-in-office-365/

#######updated to accomodate multiple users with the same identity###############
# Unblock-File -Path D:\Scripts\DisableOWA\Start-RobustCloudCommand.ps1
# D:\Scripts\DisableOWA\Start-RobustCloudCommand.ps1 -Agree -LogFile $LogFile -Recipients  #$Recipients -ScriptBlock { Get-CASMailbox -ResultSize Unlimited | Where {$_.OWAEnabled -eq $True} | Set-CASMailbox -OWAEnabled $False } -Credential $Credential
############################################################

$users=Get-CASMailbox -ResultSize Unlimited |  Where {$_.OWAEnabled -eq $True}
Unblock-File -Path D:\Scripts\DisableOWA\Start-RobustCloudCommand.ps1
D:\Scripts\DisableOWA\Start-RobustCloudCommand.ps1 -Agree -LogFile $LogFile -Recipients $Recipients -ScriptBlock { Foreach($user in $users) {Set-CASMailbox $user.distinguishedname -OWAEnabled $False}} -Credential $Credential


Now you have your script, you can create a Basic Task via Task Scheduler to run it. The user account used should have the right level of permissions to run the process in the unrestricted execution policy.

Program = C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe 
Arguments = -ExecutionPolicy unrestricted -noprofile -file D:\Scripts\DisableOWA\DisableOWA.ps1




Comments