Welcome to TechNet Blogs Sign in | Join | Help

Как вызывать команды Exchange Management Shell из C#

Иногда возникает необходимость вызывать команды Exchange Management Shell из кода. Например, вы можете управлять транспортными агентами из вашего собственного кода, да и вообще этому можно придумать множество применений

  • Создадим новый консольный проект
  • Добавим reference на сборку System.Management.Automation.dll (обычно в C:\Program Files\Reference Assemblies\Microsoft\WindowsPowerShell\v1.0\)

Следующий пример кода выводит список транспортных агентов начинающихся с буквы “J” – эквивалентно вызову Get-TransportAgent –Identity “J*”

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using System.Management.Automation;
using System.Management.Automation.Host;
using System.Management.Automation.Runspaces;

namespace CallExchangeManagementShellCommands
{
    class Program
    {
        static void Main(string[] args)
        {
            // Подключаем команды для работы с Exchange
            RunspaceConfiguration runspaceConfig = RunspaceConfiguration.Create();
            PSSnapInException snapInException = null;
            runspaceConfig.AddPSSnapIn("Microsoft.Exchange.Management.PowerShell.Admin", out snapInException);

            Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfig);
            runspace.Open();

            // Создаем pipeline в рамках которого будут выполняться команды
            Pipeline pipeline = runspace.CreatePipeline();

            // Создаем новую команду
            Command command1 = new Command("Get-TransportAgent");
            
            // Добавляем к ней нужные параметры
            command1.Parameters.Add(new CommandParameter("Identity","J*"));

            // Добавляем команду к pipeline
            pipeline.Commands.Add(command1);

            // Вызываем команду и получаем список с результатом выполнения команды
            Collection<PSObject> command1Results = pipeline.Invoke();

            // Пробегаемся по результатам и выводим нужные на экран
            foreach (var result in command1Results)
            {
                Console.WriteLine(String.Format("Agent \"{0}\" Enabled={1}", 
                    result.Properties["Identity"].Value, 
                    result.Properties["Enabled"].Value));
            }
        }
    }
}
Posted by Stanislav Chistyakov | 0 Comments
Filed under:

Управление транспортными агантами (Часть 2)

 

Я уже рассказывал как управлять (устанавливать, удалять, включать, отключать, получать список) транспортными агентами, используя Exchange Management Shell - http://blogs.technet.com/stas/archive/2008/03/07/exchange-management-shell.aspx#3251873

Иногда возникают вопросы, как это можно сделать не через Exchange Management Shell, а, например, обычного bat файла или шедулера

Небольшое вступление

 

PowerShell позиционируется как супер мега штука, которая позволяет администраторам легко управлять почти всем используя командную строку. Используя PowerShell, можно писать очень гибкие сценарии, в которых можно вызывать существующие команды, команды разработанные самостоятельно или другими компаниями, а так же напрямую обращаться к .NET Framework

Exchange Management Shell построен на базе PowerShell. Фактически это и есть PowerShell, в котором дополнительно загружены команды для управления Exchange.

Пример

 

Допустим у нас есть скрипт под Exchange Management Shell для установки транспортного агента:

Если мы хотим запустить этот скрипт из командной строки или из bat файла, то необходимо просто правильно сформировать команду. Для запуска обычного PowerShell скрипта можно использовать синтаксис

powershell “Путь к скрипту”.

Для того, чтобы наш экземпляр PowerShell мог получить доступ к командам Exchange необходимо добавить нужный параметр  (полный список параметром можно посмотреть набрав powershell /?)

Итого у нас получается следующая команда:

powershell -PSConsoleFile "C:\Program Files\Microsoft\Exchange Server\Bin\ExShell.psc1" -Command "Путь к скрипту"

Изменения порта для Send Connector

В Exchange 2007 при создании Send Connector из Exchange Management Console нельзя указать порт отличный от заданного по умолчанию, но это можно сделать через Exchange Management Shell:

Set-SendConnector "Название Send Connector" –Port “Номер порта”

Как удалять сообщения, используя транспортный агент (Routing Agent)

При разработке транспортного агента часто необходимо удалять некоторые из сообщений. Это очень легко сделать:

public class SampleAgent : RoutingAgent
{
    public SampleAgent(SmtpServer server)
    {
        this.OnSubmittedMessage += new SubmittedMessageEventHandler(this.OnSubmittedMessageHandler);
    }

    private void OnSubmittedMessageHandler(SubmittedMessageEventSource source, QueuedMessageEventArgs e)
    {
        MailItem mailItem = args.MailItem;

        if (/* Проверяем нужно ли нам удалять это сообщение */)
        {
            source.Delete();
        }
    }
}

Русский Windows Vista Service Pack 1 выпущен!!!

Наконец вышел Vista Service Pack 1 для русской Windows Vista

Пакет можно загрузить с Центра Загрузки Windows (http://www.microsoft.com/downloads/details.aspx?FamilyID=f559842a-9c9b-4579-b64a-09146a0ba746&DisplayLang=ru)

Как в транспортном агенте на EDGE сервере определить входящее письмо или исходящее?

Недавно пришлось столкнуться с этим вопросом, и добрые люди помогли найти ответ. Все оказалось достаточно просто:

public class SampleAgentFactory : RoutingAgentFactory
{
    public override RoutingAgent CreateAgent(SmtpServer server)
    {
        return new SampleAgent(server);
    }
}

public class SampleAgent : RoutingAgent
{
    private SmtpServer _server;

    public SampleAgent(SmtpServer server)
    {
        _server = server;
        this.OnSubmittedMessage += new SubmittedMessageEventHandler(this.OnSubmittedMessageHandler);
    }

    private void OnSubmittedMessageHandler(SubmittedMessageEventSource source, QueuedMessageEventArgs e)
    {
        AcceptedDomain acceptedDomain = _server.AcceptedDomains.Find(e.MailItem.FromAddress);
        if (acceptedDomain != null && acceptedDomain.IsInCorporation)
        {
            // Письмо идет наружу
        }
        else
        {
            // Письмо идет внутрь
        }
    }
}

Управление транспортными агентами из Exchange Management Shell

Периодически возникают вопросы о том как управлять транспортными агентами. Тут все очень просто  - для этого можно пользоваться cmdlet-ами в Exchange Management Shell.

Всего этих команд не очень много:

  • Install-TransportAgent - зарегистрировать агент в Exchange Server
  • Uninstall-TransportAgent - удалить регистрацию агента в Exchange Server
  • Enable-TransportAgent - сделать агент активным в Exchange Server
  • Disable-TransportAgent - сделать агент неактивным в Exchange Server
  • Get-TransportAgent - получить информацию об установленных агентах (либо выбранном агенте)
  • Set-TransportAgent - изменить параметры (сейчас это только приоритет) транспортного агента в Exchange Server
  • Полное описание можно найти по следующей ссылке:
    http://technet.microsoft.com/en-us/library/aa998620(EXCHG.80).aspx

    Постер по архитектуре Exchange 2007

    Замечательный постер, дающий базовое представление архитектуры Exchange 2007

    image

    http://www.microsoft.com/downloads/details.aspx?FamilyId=FDCDF6E5-DE47-4B58-8086-282101BCDDE9&displaylang=en

    Posted by Stanislav Chistyakov | 0 Comments
    Filed under:

    Публикация Exchange 2007 через ISA 2006

    Наткнулся на интересную статью, которая детально описывает детали публикации Exchange 2007 через ISA 2006:

    Publishing Exchange Server 2007 with ISA Server 2006
    http://www.microsoft.com/technet/isa/2006/deployment/exchange.mspx
    Posted by Stanislav Chistyakov | 0 Comments
    Filed under:

    Постеры по компонентам Windows Server 2008

    Недавно наткнулся на постеры по компонентам Windows Server 2008. Достаточно удобно и понятно, особенно для людей типа меня, которым программирование ближе чем администрирование, и уж если дело дошло до обзора компонентов операционной системы, то лучше воспользоваться красивыми картинками с минимумом текста

    По ссылке можно скачать

    • Windows Server 2008 Active Directory Components
    • Windows Server 2008 Feature Components

    http://www.microsoft.com/downloads/details.aspx?FamilyID=c2b9e44e-0bbd-47cb-bc09-b3d48be7f867&displaylang=en

    image

    image

    Хранение настроек Custom Transport Agent для Exchange 2007

    При разработке транспортных агентов часто необходимо хранить какие-либо настройки этого агента. Т.к. агент - обычная Class Library на .NET, то логично использовать стандартный app.config файл. Наша Class Library будет использоваться одним из сервисов Exchange 2007 и, соответственно, настройки надо вносить в app.config этого сервиса..... Это не всегда удобно, и хочется иметь файл настроек рядом с самой dll агента.

    Например, мы разрабатываем агент, который записывает каждое почтовое сообщение в базу данных (я рассказывал о таких агентах в предыдущей статье), и в config файле должна быть connection string для подключения к базе, и мы хотим чтобы DLL агента и config файл были рядом

    image

    В .NET мы можем подключать внешние конфигурационные файлы:

    void OnRoutedMessageHandler(RoutedMessageEventSource source, QueuedMessageEventArgs args)
    {
        try
        {
            // Узнаем где расположена текущая сборка
            String assempbyLocation = Assembly.GetExecutingAssembly().Location;
    
            // Открываем наш конфигурационный файл
            Configuration config = ConfigurationManager.OpenExeConfiguration(assempbyLocation);
    
            // Читаем необходимую информацию из нашего конфигурационного файла
            String connString = config.ConnectionStrings.ConnectionStrings["Имя строки подключения"].ConnectionString;
    
            // Запись в базу 
        }
        catch (Exception ex)
        {
            // Обработка ошибок
        }
    }

    Это позволяет избежать изменения конфигурационных файлов самого Exchange 2007, что уменьшает вероятность все сломать :)

    Custom логирование почтовых сообщений в Exchange 2007

    Стандартное логирование почтовых сообщений в Exchange 2007 является весьма мощным механизмом, достаточным в большинстве случаев, но иногда нужно что-то большее. Например, если у вас есть задача записывать определенную информацию о каждом сообщении в базу данных...... Это может быть необходимо для построения каких-либо статистических отчетов или специальное требование системы безопасности и т.д.

    Для этой задачи идеально подходят транспортные агенты, о которых я начал рассказывать в предыдущей статье, ведь если мы развернем Routing Agent на HUB сервере Exchange 2007, то через него будут проходить все почтовые сообщения, даже если они пересылаются между пользователями, почтовые ящики которых находятся на одном Mailbox сервере Exchange 2007. Более того, внутри агента мы можете получить любую информацию о почтовом сообщении, а не довольствоваться лишь определенными полями из логов

    Разработка транспортных агентов для Exchange 2007

    Зачем вообще нужны транспортные агенты?

    Агенты встраиваются в Exchange и позволяют вам реализовать некоторые обработчики событий. При срабатывании агента вы имеете полный доступ к полям письма и можете вносить в само письмо некоторые изменения

    Какие бывают агенты и чем они отличаются?

    В Exchange 2007 есть два разных типа транспортных агентов:

    • SMTP Receive Agent - позволяет реагировать на события, возникающие при получении письма по SMTP
    • Routing Agent - позволяет реагировать на события, возникающие при роутинге письма

    Как написать агент?

    Если у вас есть настроенная девелоперская среда и на ваших HUB и EDGE серверах развернута Visual Studio 2005 (хм... лучше конечно Visual Studio 2008), то вы либо счастливчик, либо ..... даже придумать не могу :)

    Если же у вас на компьютере стоит только Visual Studio, а почтовые сервера стоят отдельно, то достаточно скопировать на себе файлы Microsoft.Exchange.Data.Transport.dll и Microsoft.Exchange.Data.Common.dll с HUB или EDGE сервера из папки C:\Program Files\Microsoft\Exchange Server\Public

    Теперь приступим к непосредственному созданию нового агента. Пусть это будет Routing Agent

    1. Запускаем студию
    2. Создаем новый проект Class Library
    3. Добавляем к проекту References на Microsoft.Exchange.Data.Transport.dll, Microsoft.Exchange.Data.Common.dll (мы уже позаботились чтобы эти файлы были на компьютере)
    4. Реализуем класс, унаследоманный от RoutingAgent. Это наш агент:
    5. //------------------------------------------------------------------------
      //  Custom Routing agent
      //------------------------------------------------------------------------
      public class CustomRoutingAgent : RoutingAgent
      {
          public CustomRoutingAgent()
          {
              this.OnRoutedMessage += OnRoutedMessageHandler;
          }
         
         
      void OnRoutedMessageHandler(RoutedMessageEventSource source, QueuedMessageEventArgs args)
          {
              try
              {
                  MailItem mailItem = args.MailItem;
                  //-------------------------------------------------------------
                  //  Все.... мы получили доступ к полям письма. Например:
                  //  mailItem.Message.MessageId - идентификатор письма
                  //  mailItem.Message.To - коллекция получателей
                  //  mailItem.Message.Attachments - коллекция аттачментов
                  //  и т.д. все поля перед нами
                  //-------------------------------------------------------------
              }
              catch (Exception ex)
              {
                  // Обрабатываем исключения
                  EventLog eventLog = new EventLog();
                  eventLog.Source = "MSExchangeTransport";
                  eventLog.WriteEntry("CustomRoutingAgentAgent:\n" + ex.ToString(),
                      EventLogEntryType.Error, 0);
              }
          }
      }

    6. Реализуем класс, унаследованный от RoutingAgentFactory. Это просто фабрика, которая будет создавать экземпляр нашего агента
    7. //------------------------------------------------------------------------
      //  Routing agent factory
      //------------------------------------------------------------------------
      public class CustomRoutingAgentFactory : RoutingAgentFactory
      {
          public override RoutingAgent CreateAgent(SmtpServer server)
          {
              return new CustomRoutingAgent();
          }
      }

    С точки зрения разработки это все..... Ничего лишнего

    Развернем этот компонент на HUB сервере. Воспользуемся командами Management Shell

    Установка агента:
    Install-TransportAgent -Name "MyCustomAgent" -TransportAgentFactory "MyAgents.CustomRoutingAgentFactory" -AssemblyPath "C:\myagents\MyAgent.dll"

    Включение агента:
    Enable-TransportAgent -Name "MyCustomAgent"

    Где брать дополнительную информацию?

    Т.к. транспортный агент относится к разработке, то всю информацию можно найти в SDK:
    http://msdn2.microsoft.com/en-us/library/aa579185.aspx

     
    Page view tracker