如何将会议导入office365(EWS和Powershell?)

How to import meetings into office365 (EWS and Powershell?)

我需要帮助将 bookings/meetings 导入 o​​ffice365。我可以将预订信息从我们的旧 web-based 系统导出到 csv,但需要一种方法来导入到 office365 中的 exchange。

我发现的最有前途的方法是使用 Exchange Web 服务通过 powershell 连接到云,然后使用模拟 re-reate 预订作为新创建的房间邮箱的适当用户。但如果有更好的方法,我愿意接受其他建议。

我目前在使用 EWS 和 powershell(如:http://mikepfeiffer.net/2011/01/creating-calendar-items-with-powershell-and-the-ews-managed-api/)时遇到的问题是,当我尝试连接时出现自动发现错误。这仍然可以使用 Office 365 吗?

更新: 嗨 Glen Scales,

非常感谢您提供的示例,看起来很有希望,但是当我 运行 您上面的代码时,我仍然遇到自动发现错误,下面是具体错误和我正在逐步执行的操作的描述.我希望我做的事情显然是错误的,你将能够纠正我

我正在 运行正在使用 Powershell 并使用我们的凭证连接到 o365,如下所示:

$loginUserName = "admin@domain.onmicrosoft.com"
$PWord = ConvertTo-SecureString –String "secret" –AsPlainText -Force
$Credential = New-Object –TypeName System.Management.Automation.PSCredential –ArgumentList $loginUserName, $PWord
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $Credential -Authentication Basic -AllowRedirection
Import-PSSession $Session
Connect-MsolService -Credential $Credential

然后加载您的函数并尝试这样的测试命令:

$Start = Get-Date
$End = (Get-Date).AddHours(1)

Create-Appointment -MailboxName mymailbox@domain.com -Subject "Test appointment" -Start $Start -End $End -Body "Test Body" -Credentials $Credential -Location "sdfkjhsdfjh"

错误:

Exception calling "AutodiscoverUrl" with "2" argument(s): "The Autodiscover service couldn't be located."
At \blahblah\bookings.ps1:100 char:3
+         $service.AutodiscoverUrl($MailboxName,{$true})
+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : AutodiscoverLocalException

Using CAS Server : 
Exception calling "Bind" with "2" argument(s): "The Url property on the ExchangeService object must be set."
At \blahblah\bookings.ps1:114 char:3
+         $Calendar = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$folde ...
+    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : ServiceLocalException

Exception calling "Save" with "2" argument(s): "Value cannot be null.
Parameter name: destinationFolderId"
At \blahblah\bookings.ps1:127 char:3
+         $Appointment.Save($Calendar.Id,[Microsoft.Exchange.WebServices.Data.SendInvita ...
+    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : ArgumentNullException

您需要确保在 Office365 中使用凭据,否则您将收到自动发现错误,例如这样的事情应该有效

####################### 
<# 
.SYNOPSIS 
 Create an Appointment from Commandline using Powershell and the Exchange Web Services API in a Mailbox in Exchange Online 
 
.DESCRIPTION 
  Create an Appointment from Commandline using Powershell and the Exchange Web Services API in a Mailbox in Exchange Online 
 
 Requires the EWS Managed API from https://www.microsoft.com/en-us/download/details.aspx?id=42951

.EXAMPLE
 PS C:\>Create-Appointment  -MailboxName user.name@domain.com -Subject AppointmentName -Start (Get-Date) -End (Get-Date).AddHours(1) -Body "Test Body" -Credential (Get-Credential) -Location "Coffee Shop"

 This Example creates an appointment in a Mailboxes Calendar folder
#> 
function Create-Appointment 
{ 
    [CmdletBinding()] 
    param( 
     [Parameter(Position=0, Mandatory=$true)] [string]$MailboxName,
   [Parameter(Position=1, Mandatory=$true)] [string]$Subject,
  [Parameter(Position=2, Mandatory=$true)] [DateTime]$Start,
  [Parameter(Position=3, Mandatory=$true)] [DateTime]$End,
  [Parameter(Position=4, Mandatory=$true)] [string]$Location,
  [Parameter(Position=5, Mandatory=$true)] [string]$Body,
  [Parameter(Position=6, Mandatory=$true)] [PSCredential]$Credentials
    )  
  Begin
   {
  ## 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]::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($Credentials.UserName.ToString(),$Credentials.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)
  $Appointment = New-Object Microsoft.Exchange.WebServices.Data.Appointment -ArgumentList $service  
  #Set Start Time  
  $Appointment.Start = $Start 
  #Set End Time  
  $Appointment.End = $End
  #Set Subject  
  $Appointment.Subject = $Subject
  #Set the Location  
  $Appointment.Location = $Location
  #Set any Notes  
  $Appointment.Body = $Body
  #Create Appointment will save to the default Calendar  
  $Appointment.Save($Calendar.Id,[Microsoft.Exchange.WebServices.Data.SendInvitationsMode]::SendToNone)  

 }
}