Microsoft 365 / Exchange Online Specialist Needed — Fix Email Mirroring to Gmail

Please login or register as jobseeker to apply for this job.

TYPE OF WORK

Part Time

WAGE / SALARY

AI-Suggested Ranges: P253--P635 per hour

HOURS PER WEEK

5

DATE UPDATED

May 19, 2026

JOB OVERVIEW

# JOB OVERVIEW

I need an experienced Microsoft 365 / Exchange Online specialist to fix a mail-flow issue.

My company domain is currently hosted in Microsoft 365 / Exchange Online. Microsoft 365 must remain the authoritative mail system for now. I am not ready to move MX records to Google Workspace yet, although it is planned.

The goal is simple:
- All inbound company email should arrive in Microsoft 365 / Outlook and also be mirrored into a normal Gmail inbox.
- I do not want to buy additional Microsoft 365 licenses, since I am in the process of slowly migrating away from Microsoft.


# CURRENT ENVIRONMENT

- Microsoft 365 / Exchange Online tenant
- One real licensed mailbox/user: ----------
- Other company addresses are aliases on that same mailbox, such as:
-- ----------
-- ----------
-- ----------
- Mail sent to those aliases successfully arrives in the ---------- mailbox.
- Desired result: those same inbound emails should also appear in a Gmail inbox.
- Microsoft 365 must remain authoritative for the domain during this interim period.
- No Google Workspace MX cutover yet.
- No extra M365 licenses.


# CURRENT PROBLEM

I tried multiple approaches, but the Gmail mirror still does not work reliably.
Known facts:
- Direct email to the Gmail inbox works.
- Mail to ---------- arrives in Outlook.
- Mail to aliases like ---------- and ---------- arrives in Outlook.
- Gmail forwarding is disabled.
- Gmail filters/blocked addresses are clean.
- Outlook inbox rules appear clean.
- Exchange connectors appear empty.
- Exchange transport rules appear empty except for a test mirror rule.
- POP pull from Gmail failed and should not be used.
- App passwords are not available in this tenant.

Previous Microsoft 365 mailbox forwarding initially failed with:
- 550 5.7.520 – external forwarding not allowed

An outbound anti-spam policy was then created to allow external forwarding for the mailbox.

After that, forwarding still did not produce the desired result. Some NDRs showed SRS-style forwarding behavior and 550 5.1.1 rejections from Google / ---------- .

I also tested a mail-flow rule to Bcc/copy mail to a Gmail mail contact, but the mirrored copy still did not appear in Gmail.


# REQUIRED OUTCOME

The project is successful when:
- Email sent to ----------
- Email sent to ----------
- Email sent to ----------
- Email sent to ----------

--> Arrives in ---------- 365 mailbox
--> Also appears in the target Gmail inbox
--> No extra Microsoft 365 licenses are required
--> Microsoft 365 remains authoritative
--> No MX change to Google Workspace is required


# SCOPE OF WORK

Please audit and fix the inbound mail mirroring issue.

You should be able to inspect:
- Exchange Online mailbox forwarding properties
- Hidden forwarding settings
- Inbox rules via PowerShell
- Mail-flow rules
- Remote domain settings
- Outbound anti-spam policy
- Accepted domain settings
- Mail contact configuration
- Message trace
- SRS / forwarding-loop behavior
- Alias/proxy address configuration
- Any hidden PowerShell-only routing/forwarding state


# OUT OF SCOPE UNLESS SEPARATELY APPROVED

Do not focus on these unless asked later:
- Full Google Workspace migration
- Moving MX records
- Buying additional Microsoft 365 licenses
- Creating separate paid mailboxes for aliases
- POP/IMAP Gmail pull
- Gmail Send As / SMTP sending setup

There is also a secondary Gmail “Send mail as” issue, but the main priority is inbound mail mirroring only.


# REQUIRED SKILLS

You must have real hands-on experience with:
- Microsoft 365 Admin Center
- Exchange Admin Center
- Exchange Online PowerShell
- Exchange Online message trace
- Microsoft Defender outbound anti-spam policies
- Mailbox forwarding
- Remote domains
- Mail contacts
- Transport/mail-flow rules
- NDR/header analysis
- Gmail delivery behavior


# STRONG PREFERENCE

Please only apply if you are comfortable with PowerShell checks such as:
Get-Mailbox
Get-InboxRule
Get-TransportRule
Get-RemoteDomain
Get-AcceptedDomain
Get-MailContact
Get-MessageTrace
Get-MessageTraceDetail

And mailbox properties such as:
ForwardingAddress
ForwardingSmtpAddress
DeliverToMailboxAndForward

Email
Addresses
RecipientTypeDetails


# ACCESS METHOD

Access method will be agreed before work begins.

Possible options:
- Screen share while I operate
- Temporary delegated access
- Remote session with approval for each admin change

Do not request the Microsoft 365 admin password directly.


# DELIVERABLES

Please provide:
- Root-cause diagnosis
- Exact settings checked
- Exact settings changed
- Screenshots or PowerShell output showing relevant checks
- Message trace evidence
- Before/after test results
- Confirmation that test emails to ---------- ---------- ---------- and ---------- in both Outlook and Gmail
- Short written summary of what was fixed


# Application Instructions

When applying, please answer all questions below.

1. How much hands-on Microsoft 365 / Exchange Online experience do you have?

2. Can you use Exchange Online PowerShell confidently?
Please rate yourself from 1–10 and briefly mention which Exchange Online PowerShell tasks you have personally done.

3. Have you diagnosed Microsoft 365 forwarding, NDR, message trace, or mail-flow issues before?
If yes, briefly describe the type of issue you handled.

4. What exact first 3 checks would you run for this issue? Please be specific.

5. Please include your pricing and availability:
A) Your current, recent, or typical hourly rate for similar Microsoft 365 / Exchange Online troubleshooting work (in PHP);
B) The best hourly rate you are comfortable offering for this specific narrow troubleshooting engagement (in PHP);
C) Your earliest availability;
D) How many billable hours you expect the first diagnosis to take.

Hourly is preferred. If you want to include a fixed-price diagnosis option as an alternative, you may do so, but please also include the hourly rate and estimated hours behind that fixed price.

I am mainly comparing applicants based on relevant Exchange Online experience, hourly rate, expected total diagnosis cost, availability, and quality+specificity of the first 3 checks proposed.


Thanks.


(Generic applications or applicants who skip the instructions will not be considered.)

VIEW OTHER JOB POSTS FROM:
SHARE THIS POST
facebook linkedin
  BENCHMARKS  
Loading Time: Base Classes  0.0008
Controller Execution Time ( Jobseekers / Job )  0.0318
Total Execution Time  0.0331
  GET DATA  
No GET data exists
  MEMORY USAGE  
1,543,792 bytes
  POST DATA  
No POST data exists
  URI STRING  
jobseekers/job/Microsoft-365-Exchange-Online-Specialist-Needed-Fix-Email-Mirroring-to-Gmail-1643623
  CLASS/METHOD  
jobseekers/job
  DATABASE:  onlinejobs (Jobseekers:$db)   QUERIES: 13 (0.0250 seconds)  (Hide)
0.0004   SELECT *
                                
FROM exrates
                                WHERE rate_name 
'USD-PHP' 
0.0004   SELECT *
FROM `employer_jobs`
WHERE `job_id` = 1643623
 LIMIT 1 
0.0003   SELECT *
FROM `employers`
WHERE `employer_id` = 883866
 LIMIT 1 
0.0168   SELECT COUNT(DISTINCT t.id) as cnt
FROM 
`t_thread` `t`
INNER JOIN `t_message` `mON `t`.`id` = `m`.`thread_id`
INNER JOIN `t_message_employer` `eON `m`.`id` = `e`.`message_id`
LEFT JOIN `t_thread_misc` `miscON `t`.`id` = `misc`.`thread_id`
WHERE `t`.`job_id` = 1643623
AND `misc`.`idIS NULL 
0.0005   SELECT e.business_namee.logoe.websitee.rebill_datee.date_added member_datehitsDATEDIFF('2026-06-26',ej.date_added) duration_daysDATEDIFF('2026-06-26',e.rebill_date) duration_rebillej.*, e.deactivate FROM employers eemployer_jobs ej WHERE e.employer_id ej.employer_id AND
                                   ((
e.user_level >= '500' AND ej.date_added <= e.rebill_date)
                                   OR 
e.employer_id '' OR (ej.date_approved <> '2000-01-01' and DATEDIFF('2026-06-26',ej.date_added) <= 14 ))
                                   AND 
e.deactivate != AND ej.deleted AND job_id '1643623' 
0.0009   SELECT *
FROM `employer_jobs_skills` `ejs`
LEFT JOIN `skills_categories` `scON `ejs`.`skill_id` = `sc`.`id`
WHERE `job_id` = 1643623 
0.0021   UPDATE employer_jobs SET hit_counts '***May-11-2026=428***May-12-2026=28***May-13-2026=25***May-14-2026=22***May-15-2026=12***May-16-2026=8***May-17-2026=8***May-18-2026=2***May-19-2026=135***May-20-2026=30***May-21-2026=12***May-22-2026=4***May-23-2026=3***May-24-2026=4***May-25-2026=10***May-26-2026=3***May-27-2026=5***May-28-2026=6***May-29-2026=5***May-30-2026=6***May-31-2026=7***Jun-01-2026=1***Jun-02-2026=3***Jun-03-2026=1***Jun-05-2026=3***Jun-06-2026=5***Jun-07-2026=7***Jun-08-2026=3***Jun-09-2026=2***Jun-10-2026=1***Jun-11-2026=7***Jun-12-2026=5***Jun-13-2026=3***Jun-14-2026=3***Jun-15-2026=5***Jun-16-2026=2***Jun-17-2026=1***Jun-18-2026=6***Jun-19-2026=3***Jun-26-2026=1' WHERE job_id'1643623'  
0.0006   UPDATE employer_jobs SET monthly_hits '***May-2026=762***Jun-2026=62' WHERE job_id'1643623'  
0.0010   SELECT date_sent FROM jobseeker_sent_emails WHERE jobseeker_id '' AND job_id '1643623' AND status LIKE 'sent%' ORDER BY id DESC  
0.0003   SELECT *
FROM `employer_jobs_skills` `ejs`
LEFT JOIN `skills_categories` `scON `ejs`.`skill_id` = `sc`.`id`
WHERE `job_id` = 1643623 
0.0012   SELECT COUNT(*) AS `numrows`
FROM `employer_jobs`
WHERE `employer_id` = '883866'
AND `date_added` >= '2022-06-08' 
0.0003   select from teasers 
0.0002   SELECT FROM skill_categories WHERE skill_cat_id='' 
  HTTP HEADERS  (Show)
  SESSION DATA  (Show)
  CONFIG VARIABLES  (Show)