none
Exchange 2013: Read specific dates (with categorie vacation) in foreign mailboxes? RRS feed

  • Question

  • Hi there,

    we would like to output a list of all holidays in a list.
    We have to search through all existing mailboxes and filter the entries with the category "vacation".

    Is there a way using PowerShell or otherwise a list of all vacation days to create?

    In any calendar read access is possible

    Someone an idea or code example?

    Thanks in advance,
    regards,

    Coyo

    Tuesday, July 22, 2014 12:30 PM

Answers

  • You could do this with EWS, however with calendar appointments you need to use a Start and End time so any recurrences will expand (depending how the vacations have been entered in the calendar). So if you want to filter by another property you'll just need to filter the results that come back eg

    ## Get the Mailbox to Access from the 1st commandline argument
    
    $MailboxName = $args[0]
    
    ## Load Managed API dll  
    Add-Type -Path "C:\Program Files\Microsoft\Exchange\Web Services\2.1\Microsoft.Exchange.WebServices.dll"  
      
    ## Set Exchange Version  
    $ExchangeVersion = [Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010_SP2  
      
    ## 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      
      
    #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) 
    # Bind to the Calendar Folder
    $folderid= new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Calendar,$MailboxName)   
    $Calendar = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$folderid)
    
    $StartDate = (Get-Date).AddYears(-1)
    $EndDate = (Get-Date)
    
    #Define ItemView to retrive just 1000 Items    
    $cvCalendarview = new-object Microsoft.Exchange.WebServices.Data.CalendarView($StartDate,$EndDate)   
    $fiItems = $null    
    $fiItems = $service.FindAppointments($Calendar.Id,$cvCalendarview)    
    foreach($Item in $fiItems.Items){      
    	if($Item.Categories.Contains("vacation")){
    		Write-Host($Item.Start.ToString() + " : " + $Item.Subject)
    	}
    }    

    If you don't need the expansion you could use AQS to filter on the category like

    $AQSString = "System.Category:vacation"
    #Define ItemView to retrive just 1000 Items    
    $ivItemView =  New-Object Microsoft.Exchange.WebServices.Data.ItemView(1000)    
    $fiItems = $null    
    do{    
        $fiItems = $service.FindItems($Calendar.Id,$AQSString,$ivItemView)    
        #[Void]$service.LoadPropertiesForItems($fiItems,$psPropset)  
        foreach($Item in $fiItems.Items){      
    				Write-Host($Item.Start.ToString() + " : " + $Item.Subject)  
        }    
        $ivItemView.Offset += $fiItems.Items.Count    
    }while($fiItems.MoreAvailable -eq $true)  

    Cheers
    Glen

    Wednesday, July 23, 2014 6:53 AM

All replies

  • You could do this with EWS, however with calendar appointments you need to use a Start and End time so any recurrences will expand (depending how the vacations have been entered in the calendar). So if you want to filter by another property you'll just need to filter the results that come back eg

    ## Get the Mailbox to Access from the 1st commandline argument
    
    $MailboxName = $args[0]
    
    ## Load Managed API dll  
    Add-Type -Path "C:\Program Files\Microsoft\Exchange\Web Services\2.1\Microsoft.Exchange.WebServices.dll"  
      
    ## Set Exchange Version  
    $ExchangeVersion = [Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010_SP2  
      
    ## 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      
      
    #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) 
    # Bind to the Calendar Folder
    $folderid= new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Calendar,$MailboxName)   
    $Calendar = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$folderid)
    
    $StartDate = (Get-Date).AddYears(-1)
    $EndDate = (Get-Date)
    
    #Define ItemView to retrive just 1000 Items    
    $cvCalendarview = new-object Microsoft.Exchange.WebServices.Data.CalendarView($StartDate,$EndDate)   
    $fiItems = $null    
    $fiItems = $service.FindAppointments($Calendar.Id,$cvCalendarview)    
    foreach($Item in $fiItems.Items){      
    	if($Item.Categories.Contains("vacation")){
    		Write-Host($Item.Start.ToString() + " : " + $Item.Subject)
    	}
    }    

    If you don't need the expansion you could use AQS to filter on the category like

    $AQSString = "System.Category:vacation"
    #Define ItemView to retrive just 1000 Items    
    $ivItemView =  New-Object Microsoft.Exchange.WebServices.Data.ItemView(1000)    
    $fiItems = $null    
    do{    
        $fiItems = $service.FindItems($Calendar.Id,$AQSString,$ivItemView)    
        #[Void]$service.LoadPropertiesForItems($fiItems,$psPropset)  
        foreach($Item in $fiItems.Items){      
    				Write-Host($Item.Start.ToString() + " : " + $Item.Subject)  
        }    
        $ivItemView.Offset += $fiItems.Items.Count    
    }while($fiItems.MoreAvailable -eq $true)  

    Cheers
    Glen

    Wednesday, July 23, 2014 6:53 AM
  • it works

    thank you very much.

    regards,

    Coyo

    Thursday, July 24, 2014 6:10 AM