使用EWS API在其他邮箱中创建文件夹

本文关键字:创建 文件夹 其他 EWS API 使用 | 更新日期: 2023-09-27 18:12:17

我尝试在其他邮箱中创建联系人文件夹。由于Powershell不能做到这一点,我在MSDN站点下载了一个c#示例:

https://code.msdn.microsoft.com/exchange/exchange - 2013 -创造- 35 - e4948c/view/discussions #内容

然后我将createFolder_CS.cs修改为:

    class Ex15_CreateFolder_CS
    {
    static ExchangeService service = Service.ConnectToService(UserDataFromConsole.GetUserData(), new TraceListener());
    static void Main(string[] args)
        {
        CreateFolder(service, "Test", WellKnownFolderName.MsgFolderRoot);
        Console.WriteLine("'r'n");
        Console.WriteLine("Press or select Enter...");
        Console.Read();
        }
    static void CreateFolder(ExchangeService service, string DisplayName, WellKnownFolderName DestinationFolder)
        {
        // Instantiate the Folder object.
        Folder folder = new ContactsFolder(service);
        // Specify the name of the new folder.
        folder.DisplayName = DisplayName;
        // Create the new folder in the specified destination folder.
        folder.Save(DestinationFolder);
        Console.WriteLine("Folder created:" + folder.DisplayName);
        }
    }

更改后,我启动了程序。我输入了我的电子邮箱和密码,它就在我的邮箱里创建了联系人文件夹。但是当我使用不同的电子邮件地址时,程序无法运行。

我编译了它,并以(其他用户)域/exchange-admin的身份启动了exe文件,但它仍然不能用于另一个邮箱。

所以我读到一些关于ImpersonatedUserId的内容,但这已经包含在程序中。

也许你可以给我一些提示如何使它工作,因为我是c#的初学者?

使用EWS API在其他邮箱中创建文件夹

代码的问题是您没有告诉它您要将新文件夹保存在哪个邮箱中。你需要使用FolderId重载来指定这个否则它总是会保存到运行的凭据的邮箱例如,modify You sub like

        static void CreateFolder(ExchangeService service, string DisplayName, WellKnownFolderName DestinationFolder,String TargetMailboxSMTPAddress)
    {
    // Instantiate the Folder object.
    Folder folder = new ContactsFolder(service);
    // Specify the name of the new folder.
    folder.DisplayName = DisplayName;

     FolderId ParentFolder = new FolderId(DestinationFolder,TargetMailboxSMTPAddress);
    // Create the new folder in the specified destination folder.
    folder.Save(ParentFolder);
    Console.WriteLine("Folder created:" + folder.DisplayName);
    }

如果您想使用模拟,那么您只需要在代码中再添加一行

service.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress,TargetMailboxSMTPAddress);

您需要分配ApplicationImpersonation RBAC角色才能使用此https://msdn.microsoft.com/en-us/library/office/bb204095(v=exchg.140).aspx

如果你创建一个在Powershell中运行的控制台应用程序,我建议你只使用Powershell中的托管API,例如这里有一个脚本模块,将使用托管API在邮箱中创建文件夹

function Connect-Exchange{ 
    param( 
        [Parameter(Position=0, Mandatory=$true)] [string]$MailboxName,
        [Parameter(Position=1, Mandatory=$true)] [PSCredential]$Credentials
    )  
    Begin
         {
        Load-EWSManagedAPI
        ## Set Exchange Version  
        $ExchangeVersion = [Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2013_SP1
        ## 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  
         #$service.TraceEnabled = $true
        ## Choose to ignore any SSL Warning issues caused by Self Signed Certificates  
        Handle-SSL  
        ## 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})  
        Write-host ("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) 
        if(!$service.URL){
            throw "Error connecting to EWS"
        }
        else
        {       
            return $service
        }
    }
}
function Load-EWSManagedAPI{
    param( 
    )  
    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
            } 
    }
}
function Handle-SSL{
    param( 
    )  
    Begin
    {
        ## 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
    }
}
function Get-FolderFromPath{
    param (
            [Parameter(Position=0, Mandatory=$true)] [string]$FolderPath,
            [Parameter(Position=1, Mandatory=$true)] [string]$MailboxName,
            [Parameter(Position=2, Mandatory=$true)] [Microsoft.Exchange.WebServices.Data.ExchangeService]$service,
            [Parameter(Position=3, Mandatory=$false)] [Microsoft.Exchange.WebServices.Data.PropertySet]$PropertySet
          )
    process{
        ## Find and Bind to Folder based on Path  
        #Define the path to search should be seperated with '  
        #Bind to the MSGFolder Root  
        $folderid = new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::MsgFolderRoot,$MailboxName)   
        $tfTargetFolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$folderid)  
        #Split the Search path into an array  
        $fldArray = $FolderPath.Split("'") 
         #Loop through the Split Array and do a Search for each level of folder 
        for ($lint = 1; $lint -lt $fldArray.Length; $lint++) { 
            #Perform search based on the displayname of each folder level 
            $fvFolderView = new-object Microsoft.Exchange.WebServices.Data.FolderView(1) 
            if(![string]::IsNullOrEmpty($PropertySet)){
                $fvFolderView.PropertySet = $PropertySet
            }
            $SfSearchFilter = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.FolderSchema]::DisplayName,$fldArray[$lint]) 
            $findFolderResults = $service.FindFolders($tfTargetFolder.Id,$SfSearchFilter,$fvFolderView) 
            if ($findFolderResults.TotalCount -gt 0){ 
                foreach($folder in $findFolderResults.Folders){ 
                    $tfTargetFolder = $folder                
                } 
            } 
            else{ 
                Write-host ("Error Folder Not Found check path and try again")  
                $tfTargetFolder = $null  
                break  
            }     
        }  
        if($tfTargetFolder -ne $null){
            return [Microsoft.Exchange.WebServices.Data.Folder]$tfTargetFolder
        }
        else{
            throw ("Folder Not found")
        }
    }
}

####################### 
<# 
.SYNOPSIS 
 Creates a Folder in a Mailbox using the  Exchange Web Services API 
.DESCRIPTION 
  Creates a Folder in a Mailbox using the  Exchange Web Services API 
  Requires the EWS Managed API from https://www.microsoft.com/en-us/download/details.aspx?id=42951
.EXAMPLE
    Example 1 To create a Folder named test in the Root of the Mailbox
     Create-Folder -Mailboxname mailbox@domain.com -NewFolderName test
    Example 2 To create a Folder as a SubFolder of the Inbox
     Create-Folder -Mailboxname mailbox@domain.com -NewFolderName test -ParentFolder ''Inbox'
     Example 3 To create a new Folder Contacts SubFolder of the Contacts Folder
     Create-Folder -Mailboxname mailbox@domain.com -NewFolderName test -ParentFolder ''Contacts' -FolderClass IPF.Contact
#> 
########################
function Create-Folder{
    param( 
        [Parameter(Position=0, Mandatory=$true)] [string]$MailboxName,
        [Parameter(Position=1, Mandatory=$true)] [PSCredential]$Credentials,
        [Parameter(Position=2, Mandatory=$true)] [String]$NewFolderName,
        [Parameter(Position=3, Mandatory=$false)] [String]$ParentFolder,
        [Parameter(Position=4, Mandatory=$false)] [String]$FolderClass
    )  
    Begin
     {
        $service = Connect-Exchange -MailboxName $MailboxName -Credentials $Credentials
        $NewFolder = new-object Microsoft.Exchange.WebServices.Data.Folder($service)  
        $NewFolder.DisplayName = $NewFolderName 
        if(([string]::IsNullOrEmpty($folderClass))){
            $NewFolder.FolderClass = "IPF.Note"
        }
        else{
            $NewFolder.FolderClass = $folderClass
        }
        $EWSParentFolder = $null
        if(([string]::IsNullOrEmpty($ParentFolder))){
            # Bind to the MsgFolderRoot folder  
            $folderid= new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::MsgFolderRoot,$MailboxName)   
            $EWSParentFolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$folderid)
        }
        else{
            $EWSParentFolder =  Get-FolderFromPath -MailboxName $MailboxName -service $service -FolderPath $ParentFolder
        }
        #Define Folder Veiw Really only want to return one object  
        $fvFolderView = new-object Microsoft.Exchange.WebServices.Data.FolderView(1)  
        #Define a Search folder that is going to do a search based on the DisplayName of the folder  
        $SfSearchFilter = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.FolderSchema]::DisplayName,$NewFolderName)  
        #Do the Search  
        $findFolderResults = $service.FindFolders($EWSParentFolder.Id,$SfSearchFilter,$fvFolderView)  
        if ($findFolderResults.TotalCount -eq 0){  
            Write-host ("Folder Doesn't Exist")  
            $NewFolder.Save($EWSParentFolder.Id)  
            Write-host ("Folder Created")  
        }  
        else{  
            Write-error ("Folder already Exist with that Name")  
        }  

     }
}