PowerEventReceivers в Sharepoint 2010

Ранее я писал о замечательном решении PowerEventReceivers. Если же вы захотите использовать его в Sharepoint 2010, вы с толкнетесь с проблемой – при открытии формы редактирования текста скрипта вы получите сообщение “Возникла неожиданная ошибка”, в логе другое сообщение: “Access Denied! Current user is not a farm administrator.”

Дело в том, что данное решение проверяет принадлежность пользователя к группе администраторов фермы с помощью системного вызова “SPFarm.Local.CurrentUserIsAdministrator()”. Но в Sharepoint 2010 этот вызов изменился, в функцию добавилась переменная allowContentApplicationAccess типа bool. Именно её надо выставить в true, чтобы правильно определялась принадлежность к группе из веб-страниц.

Перекомпилированную версию для Sharepoint 2010 вы можете скачать здесь.

Замечание: данная версия пока что не позволяет использовать новые командлеты Sharepoint 2010.

Отправка оповещений о задачах в Sharepoint

Задачи в Sharepoint выведены в отдельный “класс” элементов. Они не просто имеют преднастроенные поля и “служат” рабочим процессам. Они также имеют преднастроенные шаблоны сообщений электронной почты, которые кроме собственно оповещения, имеют возможность также и редактировать задачу прямо из почтового клиента (конечно, если последний поддерживает такую возможность).

Например вот так это выглядит в outlook 2007:

image

image

Данная особенонсть очень удобна, т.к. пользователю не нужно открывать браузер для выполнения каких-то рутинных операций. При этом подгружаются как стандартные формы редактирования задачи, так и созданные в InfoPath (в том числе со встроенным кодом).

Это всё прекрасно до тех пора, пока нам не захочется кастомизировать текст письма. Сделать это мягко скажем не просто, особенно если нужна зависимость текста от текущего сайта и т.д. Кроме этого, по умолчанию оповещения отправляются на создание, изменение и закрытие задачи. Часто необходимы только какие-то определенные события. Поэтому многие отключают автоматические оповещения, и создают собственную систему оповещений. Реализаций несколько (на базе Workflow или обработка событий элемента списка), но все они имеют один недостаток – теряется функционал редактирования задач из почтового клиента.

Т.к. наши пользователи привыкли редактировать задачи из Outlook, пришлось разбираться, как же всё это работает.

Оказалось, что всё достаточно просто – редактирование задач построено на протоколе [MS-OSALER]: Alerts Interop Protocol Specification.

Собственно далее представлена функция на C#, реализующая этот протокол для отправки оповещений для задач в Sharepoint (не пугайтесь количеству строк кода – там много комментариев):

    1 /// <summary>

    2 /// Функция отправляет сообщения о задачи согласно протоколу MS-OSALER

    3 /// </summary>

    4 /// <param name="web">текущий узел</param>

    5 /// <param name="HtmlBody">текст письма</param>

    6 /// <param name="To">Кому</param>

    7 /// <param name="TaskItem">Элемент списка задач</param>

    8 /// <returns>[true] в случае успеха, или [false,"Error_Message"] в случае ошибки</returns>

    9 public object[] SendMail(SPWeb web, string HtmlBody , string To, SPListItem TaskItem)

   10 {

   11     try

   12     {

   13         //Данная секция формируется согласно справки на System.Net.MailAddress

   14         //

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

   16         SPWebApplication webApp = web.Site.WebApplication;

   17         //Формируем почтовое сообщение

   18         MailMessage mess = new MailMessage();

   19         //Берем из настроек адрес ОТ

   20         mess.From = new MailAddress(webApp.OutboundMailSenderAddress, web.Title);

   21         //и адрес для ответов

   22         mess.ReplyTo = new MailAddress(webApp.OutboundMailReplyToAddress);

   23         //тело у нах в формате UTF8

   24         mess.BodyEncoding = Encoding.UTF8;

   25         //и в формате HTML

   26         mess.IsBodyHtml = true;

   27         //Записываем тело письма, оно может абсолютно любым. Хоть пустым

   28         mess.Body = HtmlBody;

   29         //собственно кому мы отправляем письмо

   30         mess.To.Add(To);

   31         //Кодировка темы письма

   32         mess.SubjectEncoding = Encoding.UTF8;

   33         //И сама тема, может быть любой.

   34         mess.Subject = "Задачи — " + TaskItem.Title;

   35 

   36         //Далее иждут обязательные параметы, которые служт для формирования заголовков согласно MS-OSALER

   37         //Attachment — это реализация MIME, так что используем пустое вложение для формирования заголовков MIME

   38         Attachment at = new Attachment(new System.IO.MemoryStream(0), "");

   39         at.ContentType = new System.Net.Mime.ContentType("text/html; charset=utf-8");

   40         at.TransferEncoding = System.Net.Mime.TransferEncoding.QuotedPrintable;

   41         //Получаем домен для формирования MessageId. Вы можете поменять это значение.

   42         string domain = webApp.OutboundMailSenderAddress.Remove(0, webApp.OutboundMailSenderAddress.LastIndexOf(‘@’));

   43         //Формируем MessageID. Оно состоит из обязательной части и случайного ИД сообщения

   44         //(последнее делает почтовый сервер, если MessageID явно не указан в заголовках)

   45         mess.Headers.Add("Message-Id", "<3BD50098E401463AA228377848493927"+Guid.NewGuid().ToString("D")+domain+">");

   46 

   47         //Этот параметр тоже можно изменить, в протоколе он указан как рекомендваный (SHOULD), но где он используется я не нашел

   48         //поэтому сделал также, как в Sharepoint по умолчанию — описание задачи

   49         mess.Headers.Add("X-Sharing-Title", this.ToBase64(TaskItem["Body"].ToString()));

   50         //А вот далее идут параметры, менять которые нельзя.

   51         mess.Headers.Add("X-AlertTitle", this.ToBase64("System"));

   52         mess.Headers.Add("X-AlertId", "{93A2F525-F664-4B02-9AD6-07851B1381C4}:{791979F1-2AB1-427D-9722-41B08012172B}");

   53         mess.Headers.Add("Content-Class", "MSWorkflowTask");

   54 

   55         mess.Headers.Add("X-AlertWebUrl", this.ToBase64(web.Url));

   56         mess.Headers.Add("X-AlertServerType", "STS");

   57 

   58         mess.Headers.Add("X-AlertWebSoap", this.ToBase64(web.Url + "/_vti_bin/alerts.asmx"));

   59         mess.Headers.Add("X-Sharing-Config-Url", "stssync://sts/?ver=1.1&type=tasks&cmd=add-folder&base-url=" + Uri.EscapeDataString(web.Url) + "&list-url=" + Uri.EscapeDataString("Lists/Tasks") + "&guid=" + Uri.EscapeDataString(TaskItem.ParentList.ID.ToString("D")));

   60         mess.Headers.Add("X-Sharing-Remote-Uid", TaskItem.ParentList.ID.ToString("D"));

   61         mess.Headers.Add("X-Sharing-WssBaseUrl", this.ToBase64(web.Url));

   62         mess.Headers.Add("X-Sharing-ItemId", this.ToBase64(TaskItem.ID.ToString()));

   63 

   64         //Заголовок сформирован, можно отправлять.

   65         //Берем адрес почтового сервера из настроек

   66         SmtpClient client = new SmtpClient(webApp.OutboundMailServiceInstance.Server.Address);

   67         client.Credentials = CredentialCache.DefaultNetworkCredentials;

   68         client.Send(mess);

   69         //Это тестовая функция, так что обработка крайне примитивная

   70         return new object[]{ true};

   71     }

   72     catch (Exception er)

   73     { return new object[]{false,er.Message }; }

   74 }

   75 

   76 

   77 string ToBase64(string InputString)

   78 {

   79     //Грубо. Может есть и более красивая реализация. Но эта точно работает.

   80     //также не плохо было бы сделать обработку исключений

   81     return "=?utf-8?B?" + System.Convert.ToBase64String(UTF8Encoding.UTF8.GetBytes(InputString))+ "?=";

   82 }

Думаю комментарий самодостаточен. Данную функцию можно использовать (после доработки конечно) для создания собственной системы оповещений.

Новая версия SCCM Client Check 1.0.0.3

Новая версия тулзы по проверки клиента SCCM
Добавлено:
  • проверка сертификатов компьютера (для Native-режима). Проверяется наличие сертификата на удаленном компьютере, а также его валидность.
  • программу можно использовать из консоли SCCM
Инструкции:
  1. Всё содержимое архива извлечь в одну папку
  2. Поправить в файле SCCMClientCheck.xml путь до SCCMClientCheck.exe (см. тег <FilePath>). Путь может содержать пробелы, кавычки указывать не надо. 
  3. После изменение файл SCCMClientCheck.xml скопировать в папку %PROGRAMFILES%\Microsoft Configuration Manager Console\AdminUI\XmlStorage\Extensions\Actions\7ba8bf44-2344-4035-bdb4-16630291dcf6\ (создать необходимые подпаки при необходимости) на компьютеры, где установлена консоль
  4. Перезапустить консоль, в меню компьютера появится пункт SCCM Client Check

image

Подробнее почитать про внедрение своих команд в меню консоли SCCM можно здесь и здесь

Если у кого-то есть идеи, что можно было бы еще добавить в данную утилиту для облегчения диагностики клиентов – прошу высказываться.

Обновление SCCM Client Check

Выложил обновление программы для проверки клиентских компьютеров на предмет работы агента SCCM.

http://cid-9e1589588902dbaa.skydrive.live.com/embedicon.aspx/SCCMClientCheck/SCCMClientCheck_v1.0.0.2.zip

Добавлено:

  • Возможность открыть любой лог с клиента (кнопка open log file)
  • Возможность закрыть вкладку с логом двойным щелчком мыши (аля-Maxthon)

Исправлены баги:

  • время отображалось формате 12h. Теперь отображается в 24h.

Несколько картинок:

image image image