One of the new features in Exchange 2010 is the ability to manage Out-Of-Office settings for mailboxes from EMS. This is made possible by the Get-MailboxAutoReplyConfiguration and Set-MailboxAutoReplyConfiguration cmdlets. Unfortunately, these cmdlets are only available in Exchange 2010. With Exchange 2007 SP2 or higher, using the Exchange EWS Managed API and PowerShell v2, you can write your own advanced functions that emulate the functionality of the auto reply cmdlets included with 2010. In this post, I’ll share a couple of functions that you can use from within EMS that will allow you to do that.

Mailbox Permissions

Before we look at the code, a quick note about permissions. Ideally, we’d like to use Exchange impersonation to access and modify the OOF settings for a user. Unfortunately, EWS impersonation doesn’t work with the GetUserOofSettings and SetUserOofSetting methods (see this post for details). So, you’ll need to use the Add-MailboxPermission cmdlet to assign your account full access to the mailboxes you want to manage. For more details on Exchange Impersonation vs. Delegate Access, also check out this post.

The Get Function

This code assumes the EWS Managed API assembly is located in c:\bin; update the path as needed for your machine. If you have not yet downloaded the EWS Managed API, you can grab it here. This function is designed to return information similar to the Get-MailboxAutoReplyConfiguration cmdlet in Exchange 2010, here is the code:

function Get-EWSOofSettings {
    [CmdletBinding()]
    param(
        [Parameter(Position=0, ValueFromPipelineByPropertyName=$true, Mandatory=$true)]
        [System.String]
        [Alias("Identity")]
        $PrimarySmtpAddress,
        [Parameter(Position=1, Mandatory=$false)]
        [System.String]
        $ver = "Exchange2007_SP1"    
        )

    begin {
        Add-Type -Path "C:\bin\Microsoft.Exchange.WebServices.dll"
        $sid = [System.Security.Principal.WindowsIdentity]::GetCurrent().User.Value
        $user = [ADSI]"LDAP://<SID=$sid>"
    }
    
    process {
        $service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService -Arg $ver
        $service.AutodiscoverUrl($user.Properties.mail)    
        
        if($PrimarySmtpAddress -notmatch "@") {
          $PrimarySmtpAddress = (Get-Recipient $PrimarySmtpAddress).PrimarySMTPAddress.ToString()
        }
        
        $oof = $service.GetUserOofSettings($PrimarySmtpAddress)
        New-Object PSObject -Property @{
            State = $oof.State
            ExternalAudience = $oof.ExternalAudience
            StartTime = $oof.Duration.StartTime
            EndTime = $oof.Duration.EndTime
            InternalReply = $oof.InternalReply
            ExternalReply = $oof.ExternalReply
            AllowExternalOof = $oof.AllowExternalOof
            Identity = (Get-Recipient $PrimarySmtpAddress).Identity
        }
    }
}

Once you have the mailbox permissions worked out and have added the function to your PowerShell session, you can test out the code. The following example shows how you would run the function:

Get-EWSOofSettings -Identity abarlow

The above information is returned for a user with the alias of abarlow. If you’ve worked with the Get-MailboxAutoReplyConfiguration cmdlet in Exchange 2010, you’ll notice that all of the same information is returned.

Finding Users in the Organization with Out-Of-Office Enabled

The Get-EWSOofSettings function is designed to accept pipeline input from the Get-Mailbox cmdet. This means that you could find the settings for multiple users in a single command. For instance, it may be useful to find all users who currently have OOF enabled:

Get-Mailbox | Get-EWSOofSettings | ?{$_.state -eq “Enabled”} | select identity, state

It’s worth mentioning here that if a user has a duration set (start and end time) the state will show as “Scheduled”. In that case, you would simply modify your where clause to ?{($_.state -eq “Enabled”) -or ($_.state -eq “Scheduled”)}

The Set Function

Again, this code assumes the EWS Managed API assembly is located in c:\bin, you’ll need to update the path accordingly. This function is similar to the Set-MailboxAutoReplyConfiguration cmdlet in Exchange 2010.

function Set-EWSOofSettings {
    [CmdletBinding()]
    param(
        [Parameter(Position=0, Mandatory=$true)]
        [System.String]
        $Identity,
        [Parameter(Position=1, Mandatory=$false)]
        [System.String]
        $State,
        [Parameter(Position=2, Mandatory=$false)]
        [System.String]
        $ExternalAudience,
        [Parameter(Position=3, Mandatory=$false)]
        [System.DateTime]
        $StartTime,
        [Parameter(Position=4, Mandatory=$false)]
        [System.DateTime]
        $EndTime,        
        [Parameter(Position=5, Mandatory=$false)]
        [System.String]
        $InternalReply,
        [Parameter(Position=6, Mandatory=$false)]
        [System.String]
        $ExternalReply,
        [Parameter(Position=7, Mandatory=$false)]
        [System.String]
        $ver = "Exchange2007_SP1"
        )

    begin {
        Add-Type -Path "C:\bin\Microsoft.Exchange.WebServices.dll"
        $sid = [System.Security.Principal.WindowsIdentity]::GetCurrent().User.Value
        $user = [ADSI]"LDAP://<SID=$sid>"
    }
    
    process {
        $service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService -arg $ver
        $service.AutodiscoverUrl($user.Properties.mail)    
        
        if($Identity -notmatch "@") {
            $Identity = (Get-Recipient $Identity).PrimarySMTPAddress.ToString()
        }        
        
        $oof = $service.GetUserOofSettings($Identity)
        
        if($StartTime -and $EndTime) {
            $Duration = New-Object Microsoft.Exchange.WebServices.Data.TimeWindow `
            -arg $StartTime,$EndTime
            $PSBoundParameters.Duration = $Duration
            $PSBoundParameters.State = "Scheduled"
            [Void]$PSBoundParameters.remove("StartTime")
            [Void]$PSBoundParameters.remove("EndTime")
        }
        
        foreach($p in $PSBoundParameters.GetEnumerator()) {
            if($p.key -ne "Identity") {
                $oof."$($p.key)" = $p.value                
            }
        }
        $service.SetUserOofSettings($Identity,$oof)
    }
}

Here is an example using the above function to enable out-of-office for a user:

Set-EWSOofSettings -Identity bharris -State Enabled -InternalReply “I am out of the office”

Looking at the function parameters, you can see that several properties can be set including start and end time, internal and external reply, and also external audience.

Here is another example. This will schedule out of office using a start and end time, set the internal and external reply, and configure the external audience to “Known” so that external replies are only sent to recipients in the users contact list:

$start = Get-Date “7/12/2010”
$end = Get-Date “7/15/2010”
Set-EWSOofSettings -Identity jknapp -StartTime $start -EndTime $end -InternalReply “I am out of the office” -ExternalReply “I am out of the office” -ExternalAudience Known

Note that when setting a start and end time, you do not need to provide a value for the state parameter, it will automatically be set to “Scheduled”. And finally, to turn off OOF for a user, set the value for the state parameter to “disabled”.