Некоторое время назад получил крайне экзотическую задачу – необходимо было посчитать число писем отправленных и полученных некоторой группой сотрудников за каждый день прошедшего месяца и вывести эту информацию в виде удобном для обработки. Так как необходимо посчитать число писем за определённый день, то необходимо использовать командлет Get-MessageTrackingLog, причём считать будем только события “RECEIVE”. Письма, в которых сотрудник будет указан в получателях, считаются им полученными, в которых отправителем – отправленными (Капитан Очевидность умер от зависти). Данные можно поместить в две переменные $Received и $Sent:
# block1 $Received = Get-TransportServer | Get-MessageTrackingLog -ResultSize unlimited -Start $TmpDate -End $TmpDate.AddDays(1) -EventId "RECEIVE" -Recipients $SMTP | Measure-Object; $Sent = Get-TransportServer | Get-MessageTrackingLog -ResultSize unlimited -Start $TmpDate -End $TmpDate.AddDays(1) -EventId "RECEIVE" -Sender $SMTP | Measure-Object;
Здесь в переменных $TmpDate будет находиться дата, на которую мы считаем письма, а в $SMTP – адрес конкретного сотрудника. Для удобства хранения полученной информации создадим новый объект, который будет хранить адрес сотрудника, указанную дату, число полученных и отправленных писем (спасибо Вадимсу Подансу за подсказку, как это можно сделать):
# block 2 $tmpObject = New-Object psobject -Property @{ smtp = $SMTP; date = $TmpDate.ToShortDateString(); rcount = $Received.Count; scount = $Sent.Count; }
Осталось указанное выше завернуть в цикл и с шагом в один день, до тех пор, пока не упрёмся в последний нужный день посчитать письма:
$StartDate = Get-Date "01.01.2012"; $EndDate = $StartDate.AddMonths(1); # block 3 $TmpDate = $StartDate; While ($TmpDate -ne $EndDate) { <block 1> <block 2> $TmpDate = $TmpDate.AddDays(1); $tmpObject | select smtp, date, rcount, scount; }
Здесь $StartDate – дата, с которой начинаем считать (в эту переменную можно значение ввести через Get-Date, как это сделал я, можно через Read-Host, можно любым другим способом), $EndDate – дата, на которой заканчиваем считать письма (у меня она смещена на один месяц, по сравнению со $StartDate, но можно её указать любым другим способом). В конце собранные данные выводятся на экран, но вывод можно сделать в файл (File-Out, например).
Осталось теперь данные собрать по всем сотрудникам. Для этого их почтовые адреса передаём в переменную-массив и по каждому члену массива делаем обсчёт.
$SMTPs = "user1@domain.com", "user2@domain.com"; ForEach ($SMTP in $SMTPs) { <block 3>; }
Почтовые адреса в переменную можно передать прямым списком (как написано у меня), можно импортировать из csv-файла через Import-Csv. Итоговый скрипт выглядит следующим образом:
$StartDate = Get-Date "01.05.2012"; $EndDate = $StartDate.AddMonths(1); $SMTPs = "user1@domain.com", "user2@domain.com"; ForEach ($SMTP in $SMTPs) { $TmpDate = $StartDate; While ($TmpDate -ne $EndDate) { $Received = Get-TransportServer | Get-MessageTrackingLog -ResultSize unlimited -Start $TmpDate -End $TmpDate.AddDays(1) -EventId "RECEIVE" -Recipients $SMTP | Measure-Object; $Sent = Get-TransportServer | Get-MessageTrackingLog -ResultSize unlimited -Start $TmpDate -End $TmpDate.AddDays(1) -EventId "RECEIVE" -Sender $SMTP | Measure-Object; $tmpObject = New-Object psobject -Property @{ smtp = $SMTP; date = $TmpDate.ToShortDateString(); rcount = $Received.Count; scount = $Sent.Count; } $TmpDate = $TmpDate.AddDays(1); $tmpObject | select smtp, date, rcount, scount; } }
Есть одна тонкость, которую следует помнить – данные в логах по умолчанию хранятся за последние 30 дней. Поэтому, чтобы иметь возможность посчитать письма на более ранние даты необходимо срок хранения увеличить, например до 90 дней:
Set-TransportServer -Identity ServerName -MessageTrackingLogMaxAge 90.00:00:00
Стас молодец. А что это за конструкции? В смысле . Так разве можно?
While ($TmpDate -ne $EndDate) {
И, кстати, на сильно экзотическую задачу не особо и тянет, так. … рутина Exchange Server. 🙂
Паш, у нас в переменной $TmpDate хранится дата, на которую мы обсчитываем количество писем. Она меняется от $StartDate до $EndDate с шагом в сутки (функция AddDays(1)), причём нам на первый день следующего месяца считать не надо ($EndDate получается из $StartDate смещением на месяц с помощью функции AddMonths(1)). Поэтому и получается, что $TmpDate не должна принимать значение $EndDate. Отсюда и берётся конструкция While ($TmpDate -ne $EndDate).
Если твой вопрос относительно использования операнда -ne между переменными типа Date – то его можно использовать.
# block1
$Received = Get-TransportServer | Get-MessageTrackingLog -ResultSize unlimited
-Start $TmpDate -End $TmpDate.AddDays(1) -EventId “RECEIVE” -Recipients $SMTP |
Measure-Object;
$Sent = Get-TransportServer | Get-MessageTrackingLog -ResultSize unlimited
-Start $TmpDate -End $TmpDate.AddDays(1) -EventId “RECEIVE” -Sender $SMTP |
Measure-Object;
Мне кажется но это две одинаковые переменные? наверно -EventId “RECEIVE” должен отличаться?