Monday, April 06, 2015

Configure the default calendar view in OWA in Exchange 2013 and Exchange Online using EWS and Powershell

If you are after a higher level of control over the default setting in OWA, EWS offers you the ability to configure many of the default setting by modifying the FAI (folder associated Item) configuration item that controls that setting. One example of a setting that you can modify is the default view of the calendar in OWA  eg  the following setting


When are user makes a change to this setting in OWA, the setting is stored in an FAI item with an Item Class of OWA.ViewStateConfiguration in a roaming dictionary property called CalendarViewTypeDesktop.

The values for each of the setting are

1 = Day
2 = Week
3 = Work week
4 = Month

The following script first checks to see if the OWA.ViewStateConfiguration config item exists (on a new mailbox if the user has never logged into OWA it probably wont exist).

To use this script you run it with the name of the Mailbox you want to run it against and the value for the enum you want to use eg to set the default as Work week use

./SetOWACalendarView.ps1 mailbox@domain.com 3

I've put a download of this script here

The code itself looks like

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
## Get the Mailbox to Access from the 1st commandline argument
$MailboxName = $args[0]

$CalendarSetting = $args[1]

## Load Managed API dll  
###CHECK FOR EWS MANAGED API, IF PRESENT IMPORT THE HIGHEST VERSION EWS DLL, ELSE EXIT
$EWSDLL = (($(Get-ItemProperty -ErrorAction SilentlyContinue -Path Registry::$(Get-ChildItem -ErrorAction SilentlyContinue -Path 'Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Exchange\Web Services'|Sort-Object Name -Descending| Select-Object -First 1 -ExpandProperty Name)).'Install Directory') + "Microsoft.Exchange.WebServices.dll")
if (Test-Path $EWSDLL)
    {
    Import-Module $EWSDLL
    }
else
    {
    "$(get-date -format yyyyMMddHHmmss):"
    "This script requires the EWS Managed API 1.2 or later."
    "Please download and install the current version of the EWS Managed API from"
    "http://go.microsoft.com/fwlink/?LinkId=255472"
    ""
    "Exiting Script."
    exit
    } 
  
## Set Exchange Version  
$ExchangeVersion = [Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2013  
  
## Create Exchange Service Object  
$service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService($ExchangeVersion)  
  
## Set Credentials to use two options are availible Option1 to use explict credentials or Option 2 use the Default (logged On) credentials  
  
#Credentials Option 1 using UPN for the windows Account  
$psCred = Get-Credential  
$creds = New-Object System.Net.NetworkCredential($psCred.UserName.ToString(),$psCred.GetNetworkCredential().password.ToString())  
$service.Credentials = $creds      
#$service.TraceEnabled = $true
#Credentials Option 2  
#service.UseDefaultCredentials = $true  
  
## Choose to ignore any SSL Warning issues caused by Self Signed Certificates  
  
## Code From http://poshcode.org/624
## Create a compilation environment
$Provider=New-Object Microsoft.CSharp.CSharpCodeProvider
$Compiler=$Provider.CreateCompiler()
$Params=New-Object System.CodeDom.Compiler.CompilerParameters
$Params.GenerateExecutable=$False
$Params.GenerateInMemory=$True
$Params.IncludeDebugInformation=$False
$Params.ReferencedAssemblies.Add("System.DLL") | Out-Null

$TASource=@'
  namespace Local.ToolkitExtensions.Net.CertificatePolicy{
    public class TrustAll : System.Net.ICertificatePolicy {
      public TrustAll() { 
      }
      public bool CheckValidationResult(System.Net.ServicePoint sp,
        System.Security.Cryptography.X509Certificates.X509Certificate cert, 
        System.Net.WebRequest req, int problem) {
        return true;
      }
    }
  }
'@ 
$TAResults=$Provider.CompileAssemblyFromSource($Params,$TASource)
$TAAssembly=$TAResults.CompiledAssembly

## We now create an instance of the TrustAll and attach it to the ServicePointManager
$TrustAll=$TAAssembly.CreateInstance("Local.ToolkitExtensions.Net.CertificatePolicy.TrustAll")
[System.Net.ServicePointManager]::CertificatePolicy=$TrustAll

## end code from http://poshcode.org/624
  
## Set the URL of the CAS (Client Access Server) to use two options are availbe to use Autodiscover to find the CAS URL or Hardcode the CAS to use  
  
#CAS URL Option 1 Autodiscover  
$service.AutodiscoverUrl($MailboxName,{$true})  
"Using CAS Server : " + $Service.url   
   
#CAS URL Option 2 Hardcoded  
  
#$uri=[system.URI] "https://casservername/ews/exchange.asmx"  
#$service.Url = $uri    
  
## Optional section for Exchange Impersonation  
  
#$service.ImpersonatedUserId = new-object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress, $MailboxName) 

#Check for existing Item  
$folderid= new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Root,$MailboxName)     
$SfSearchFilter = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.ItemSchema]::ItemClass,"IPM.Configuration.OWA.ViewStateConfiguration")  
$ivItemView =  New-Object Microsoft.Exchange.WebServices.Data.ItemView(1)  
$ivItemView.Traversal =  [Microsoft.Exchange.WebServices.Data.ItemTraversal]::Associated  
$fiResults = $service.FindItems($folderid,$SfSearchFilter,$ivItemView)  
if($fiResults.Items.Count -eq 0){  
    Write-Host ("No Config Item found, create new Item")  
    $UMConfig = New-Object Microsoft.Exchange.WebServices.Data.UserConfiguration -ArgumentList $service  
    $UMConfig.Save("OWA.ViewStateConfiguration",$folderid)  
}  
else{  
    Write-Host ("Existing Config Item Found");  
}  
#Specify the Root folder where the FAI Item is  
$UsrConfig = [Microsoft.Exchange.WebServices.Data.UserConfiguration]::Bind($service, "OWA.ViewStateConfiguration", $folderid, [Microsoft.Exchange.WebServices.Data.UserConfigurationProperties]::All)  
if($UsrConfig.Dictionary.ContainsKey("CalendarViewTypeDesktop")){  
    $UsrConfig.Dictionary["CalendarViewTypeDesktop"] = $CalendarSetting  
}  
else{  
    $UsrConfig.Dictionary.Add("CalendarViewTypeDesktop",$CalendarSetting)  
}
$UsrConfig.Update()  
"Mailbox Updated"

5 comments:

Mike the Great said...

This seems cool, but is very 'vbscript-like'. I made a couple of quick modifications to make it more 'ps-like'. I think error-handling would be helpful too (like checking if the MailboxName value(s) is(are) correctly formatted.

<#
.DESCRIPTION
Takes one or more e-mail addresses and changes the default calendar view in OWA.
.PARAMETER MailboxName
Required parameter. One or more e-mail addreses
.PARAMETER CalendarSetting
Integer representation of the desired calendar view. the values are:
1 = Day
2 = Week
3 = Work week
4 = Month
.EXAMPLE
.\SetOWACalendarView.ps1 mailbox@domain.com 3
Sets the default calendar view of mailbox@domain.com to 'work week'.
#>
[CmdletBinding()]
param(
[Parameter(Mandatory=$True)]
[string[]]$MailboxName,

[ValidateSet("1","2","3","4")]
[int]$CalendarSetting
)
...
Foreach ($mailbox in $MailboxName) {
...
}

Mike the Great said...

Oh, the $CalendarSetting parameter should be set to mandatory too.

Anonymous said...

Hello,

the script is working great, thank you! Is it also possible to change the default publish calender view?

Anonymous said...

Using the PS script from the comments (thanks, MtG!), I can't get the syntax correct for the follow-up comment regarding $CalendarSetting param being mandatory. Can someone post what this closing argument should be?

Anonymous said...

I see the proper close now, the mandatory flag is just to ensure the command issued a calendar view integer. My question then follows the previous anonymous comment, how to make this alter the default calendar view for internet published calendars from OWA?