Статья размещена автором Бетке Сергей Сергеевич

PowerShell: пишем Exchange командлеты для Exchange 2003, оформляем модуль

В предыдущей статье показал пример написания командлеты Enable-DistributionGroup. В этой статье приведу код отдельного модуля, в котором будет определена наша командлета. В дальнейшем текст модуля в этой статье буду дополнять другими командлетами по мере того, как они мне будут требоваться.

Также приведу варианты решения без использования CDOEXM и удалённых сессий соответственно.


Первая редакция модуля

P.S. Текущая версия модуля доступна в моём SVN репозитории, доступ на чтение — svn_sysadm, пароль — svn.

Саму функцию, с которой начнём наш модуль, я уже приводил предыдущей статье. Итак, модуль в его первой редакции:

function enable-DistributionGroup {
    param (
        [Parameter(
            Mandatory=$true, 
            Position=0, 
            ValueFromPipeline=$true
        )] 
        [string] 
        $Identity
    )
    begin {
        $session = new-PSSession `
            -computerName 'server-12';
    }
    process {
        invoke-command `
            -session $session `
            -scriptBlock {
                $DG = [ADSI]"LDAP://$Indentity";
                $DG.MailEnable();
                $DG.SetInfo();
                $DG = $null;
            }
    }
    end {
        remove-PSSession $session;
    }
}

Export-ModuleMember `
    enable-DistributionGroup

Сохраняем в ITG.Exchange.psm1.

Используем SVN

На этом этапе в функционале мы ничего не изменили. PowerShell: пишем Exchange командлеты для Exchange 2003, оформляем модуль Теперь обеспечим его использование с контролем версий посредством TortoiseSVN. Создаю для этих целей отдельную папку. Структура каталогов показана на рисунке справа. Теперь используем наш модуль в сценарии, который мы рассматривали в предыдущей статье. Для сценария создадим отдельную структуру папок (PowerShell: пишем Exchange командлеты для Exchange 2003, оформляем модульрисунок слева). При этом каталог модуля ITG.Exchange и сам модуль явно копировать не следует. Воспользуемся возможностями subversion, конкретно – svn:externals. Итак, правой кнопкой на папке нашего проекта (PhonesToDistGroups\trunk), свойства, свойства Subversion, и добавляем свойство svn:externals так, как показано на рисунке справаPowerShell: пишем Exchange командлеты для Exchange 2003, оформляем модуль. После чего делаем svn commit, svn update – и видим папку ITG.Exchange в папке нашего проекта, как мы и заказывали. Но эта папка и её содержимое будет обновляться при обновлении модуля в его папке, что и требовалось.

Применение модуля

Если Вы имеете Exchange 2007 или старше, Snapin для powershell Microsoft.Exchange у Вас уже установлен, и для использования командлет Exchange Вами ничего не требуется. Для использования наших собственных командлет (синтаксис которых мы будем максимально приближать к “родным” командлетам Exchange) нам потребуется импортировать модуль в наш сценарий. Сделаем:

<# 
    .Synopsis 
        Создаём группы рассылки по телефонам (telephoneNumber) и включаем в них только те учётные записи,
        для которых в атрибуте telephoneNumber указан соответствующих телефонный номер. 
...
#> 
  
param ( 
...
) 
  
import-module ActiveDirectory
import-module .\ITG.Exchange\ITG.Exchange.psm1 # -force

...

Так мы используем наш модуль в собственном сценарии. И нам не придётся тащить код из сценария в сценарий, обеспечим, так сказать, нормализацию кода.

P.S. параметр –force, закомментированный выше, может быть крайне полезен на этапе отладки модуля , так как без него модуль, если Вы его меняете, не будет перезагружаться в рамках одной сессии powershell. Поэтому на период отладки модуля (не сценария) я всегда этот параметр добавляю.

Первые итоги

Итак, мы создали модуль, разместили его в subversion репозитории, подключили его папку к папке проекта, и использовали модуль в сценарии.

В дальнейшем в этой статье планирую публиковать полную редакцию модуля по мере его пополнения. И в ближайшие дни планирую переписать фукнцию enable-DistributionGroup с целью её максимально полного соответствия интерфейсу командлета, а также с поддержкой параметров –confirm и –WhatIf.

Вариант без CDOEXM и удалённых сессий

Воспользовался материалом статьи на эту тему и хочу попробовать написать ту же функцию, но уже без удалённых сессий и CDOEXM:

function enable-DistributionGroup {
<# 
    .Synopsis 
        Добавляем необходимые Exchange аттрибуты существующей distribution group (mail enable). 
    .Description 
        Добавляем необходимые Exchange аттрибуты существующей distribution group (mail enable). 
    .Parameter Identity
        Параметр Identity задает идентификатор группы рассылки в одном из следующих видов:
        GUID 
        DN
        Домен\Имя_учетной_записи
    .Alias 
        Параметр Alias определяет псевдоним электронной почты для группы. Если он не задан, будет использован sAMAccountName
    .DisplayName 
        Параметр DisplayName определяет краткое имя для группы рассылки.
    .Example 
        enable-DistributionGroup -Identity "CN=Подписка,OU=itg,DC=novgaro,DC=ru"
#> 
  
    [CmdletBinding(
        SupportsShouldProcess = $true,
        ConfirmImpact = 'Low'
    )]
    param (
        [Parameter(
            Mandatory=$true, 
            Position=0, 
            ValueFromPipeline=$true
        )] 
        [string] 
        $Identity,
        [Parameter(
            Mandatory=$false, 
            Position=1, 
            ValueFromPipeline=$false
        )] 
        [string]
        $Alias,
        [Parameter(
            Mandatory=$false, 
            Position=2,
            ValueFromPipeline=$false
        )] 
        [string]
        $DisplayName
    )
    process {
        $group = Get-ADGroup `
            -Identity $Identity `
            -property mailNickname, sAMAccountName;
        if (!($group.mailNickname)) { # группа не mail-enabled
            if ($alias) {
                $props = @{mailNickname = $alias;};
            } else {
                $props = @{mailNickname = $group.sAMAccountName;};
            }
            if ($displayName) {
                $props += @{displayName = $displayName;};
            };
            if ($pscmdlet.ShouldProcess($group, "mail enable")) {
                Set-ADGroup `
                    -Identity $group `
                    -Replace $props;
            };
        };
    }
}

Export-ModuleMember `
    enable-DistributionGroup

Как выяснилось, заполнить атрибут mailNickName достаточно, остальное доделает за нас RUS. И работает этот код куда быстрее.

Полезные ссылки

Отзывы » (2)

  1. Нашёл и более красивые варианты. Итого, первая группа решений — использование CDOEXM таким вот странным способом (или без powershell remoting и его проблем, если Вы не используете ADpowershell). Вторая группа решений — самостоятельная установка необходимых атрибутов в AD через ADSI в надежде, что всё остальное сделает RUS. Сейчас этот вариант и использую, и всё прекрасно работает. И третья группа решений — используем WMI объекты exchange 2003 через powershell. И легко, и инкапсуляция не нарушена. Наткнулся на этот вариант здесь.
    Однако, как то я странно искал в первый раз решения. Сегодня нашёл ещё одну статью с массой ссылок по данному вопросу dmitrysotnikov.wordpress.com.

  2. Обнаружил изумительную по сути статью об использовании командлет ADpowershell (и не только) через powershell remoting неявно!: http://www.oszone.net/13106/Windows-PowerShell.

Опубликовать комментарий

XHTML: Вы можете использовать следующие HTML теги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Tags Связь с комментариями статьи:
RSS комментарии
Обратная ссылка