Exchange Server Share

… Information sharing on Exchange Server …

How To: Schedule PowerShell Script for an Exchange Task

This is commonly asked question, How to schedule a PowerShell script to run an Exchange task automatically? Here is the procedure to get it done.

Let’s take an example, I want to schedule a PowerShell script for auditing purpose, which scans whole environment & finds mailboxes which has some Send-As permission assigned and send the CSV formatted report to email id every Monday 9:00AM.

1. Set the PowerShell environment.

We need to set environment to run custom PS1 script which we created because by default PowerShell doesn’t allow to run it.

By default Execution Policy is ‘Restricted’ which means it does not load configuration files to run custom scripts. We need to change it to ‘RemoteSigned’ to run locally created PS1 scripts however RemoteSigned policy requires PowerShell script that may be downloaded must be signed.

This is one time activity so if you have already set the execution policy to RemoteSigned earlier then you can skip this step.

Run below command in ESM to set the execution policy.

Set-ExecutionPolicy RemoteSigned


2. Create a Script file (.PS1 file).

Here is the script to get the Send-As report in email.

# Send-As.ps1 - Get the report of all mailboxes with Send-As permission assigned on email.
# Created by - Amit Tank 
#Adding Exchange Snap In to execute Exchange CmdLets in this script
Add-PSSnapin Microsoft.Exchange.Management.PowerShell.Admin
#Get Send-As permission report to CSV file
Get-Mailbox | Get-ADPermission | where { ($_.ExtendedRights -like “*Send-As*”) -and ($_.IsInherited -eq $false) -and -not ($_.User -like “NT AUTHORITY\SELF”) } | Select Identity, User, Deny | Export-CSV c:\send-As.csv
#Send an email
$FromAddress = ""
$ToAddress = ""
$MessageSubject = "Send-As Audit Report"
$MessageBody = "Attached is CSV file for Send-As audit report"
$SendingServer = "HubTransportServerName"
$SMTPMessage = New-Object System.Net.Mail.MailMessage $FromAddress, $ToAddress, $MessageSubject, $MessageBody
$Attachment = New-Object Net.Mail.Attachment("c:\Send-As.csv")
$SMTPClient = New-Object System.Net.Mail.SMTPClient $SendingServer

Note: Change the FromAddress, ToAddress and ExchangeServerName in above script as per your environment if you are going to use same script.

It requires to add Exchange Management Snap-In to recognize Exchange CmdLets in PowerShell so make sure that below line is added into script.

Add-PSSnapin Microsoft.Exchange.Management.PowerShell.Admin

You can refer below article for more detail about one liner cmdlet on getting a CSV formatted report of Send-As permissions assigned mailboxes.

How To: Find All Mailboxes with Send-As

3. Create a CMD/Bat file to execute the script.

Create a CMD/Bat file to execute PowerShell and pass the path of script with ‘-command’ switch.

Powershell -command "& {C:\Scripts\Send-As\Send-As.ps1 }"



4. Create a Schedule Task.

Create a schedule task and give the Bat file path to run. Set the password which has proper permission to execute the Exchange CmdLets available in script file.


Schedule this to run every week at specified time (9:00AM).


Well all things are set, now this mechanism runs every Monday 9:00AM and it will send a required report to mentioned email id.

Written by Amit Tank

December 8, 2008 at 3:31 pm

7 Responses

Subscribe to comments with RSS.

  1. VERY cool.

    Will be using this pretty soon!

    Chris Lehr

    December 10, 2008 at 10:27 am

  2. […] How To: Schedule PowerShell Script for an Exchange Task […]

  3. For exchange auditing I can recommend a tool called change auditor for exchange that we’ve been using in our company for some time.

    It can audit and alert on all critical changes to exchange environment like, for example, security and policy changes, distribution list changes and more.

    Gene Young

    January 16, 2009 at 4:04 pm

  4. Hi Amit,

    Can we send mutiple attachments through the above script. And this is great script.

    Sunil Bansal.

    Sunil Bansal

    July 11, 2009 at 1:58 am

  5. @Sunil: You can add multiple attachments by this way…

    Remove these two line…
    $Attachment = New-Object Net.Mail.Attachment(“c:\Send-As.csv”)

    Add this portion instead…
    $file1 = “C:\Send-As1.CSV”
    $file2 = “C:\Send-As2.CSV”
    $file3 = “C:\Send-As3.CSV”
    $file4 = “C:\Send-As4.CSV”

    $file1,$file2,$file3,$file4 | foreach-object{
    $Attachment = New-Object System.Net.Mail.Attachment $_

    Amit Tank

    July 11, 2009 at 7:18 pm

  6. Excellent thanks Amit, I have put together an exchange mailbox move script. We have hundreds of new users every week created in a staging DB. So this script goes and checks to see the smallest database and moves the mailbox there to try and keep things even. Let me know if you want me to post.


    September 3, 2009 at 12:51 pm

  7. Great Script …

    Santanu Biswas

    November 16, 2009 at 1:35 pm

Comments are closed.

%d bloggers like this: