Чистим Sharepoint Workflow Time Service cache


Обычно я делаю заметки себя, когда решаю какую-то проблему. В тот раз ничего записал, и когда спустя много времени понадобилось почистить кэш Workflow Time сервиса, использовал первую же ссылку из поиска с кривым описанием и получил проблему. В общем удалил папку с именем GUID и сервис заклинило. (Вообще удивительно как в Sharepoint всё сделано ненадежно.)

Правильная процедура:
  1. Остановить Workflow Time сервис на всех серверах (если это вообще возможно дождаться по времени).
  2. На всех серверах заходим в папку C:\ProgramData\Microsoft\SharePoint\Config\<guid>\
  3. В файле Cache.ini ставим значение 1, а остальные XML файлы удаляем.
  4. Запускаем Workflow Time сервис на всех серверах и ждем (как минимум 5 минут), когда в папке появятся XML файлы.
Решение проблемы с удаленной папкой Guid

Можно просто восстановить папку. Но для этого нужен какой-то софт, потом долго сканировать диск.

Можно создать эту папку заново, только вот как узнать Guid? Оказывается это можно сделать. Для этого выполняем следующий запрос на база конфигурации Sharepoint:

SELECT Id FROM Objects WHERE Properties like '%SPConfigurationDatabase%';

У меня там оказалось два значения (второе видимо осталось из-за того, что сервис пересоздавался когда-то вручную). Первое не сработало, зато второе прокатило.

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

  1. SharePoint service stuck on stopping/starting – guidesharepoint (wordpress.com)
  2. sharepoint service instance start stop stuck | SharePointTechnicalSupport
  3. SharePoint: Timerservice not starting jobs – TantumPoint (wordpress.com)
  4. When the Configuration Cache Folder Goes Missing… · The SharePoint Farm

Отчёт по событиям из календарей Outlook


Для управления рабочим временем (Time management) существует множество подходов и программных продуктов их поддерживающих.

Самое простое средство для планирования и управления рабочим временем это календари Outlook. Outlook обладает хорошими возможностями для управления рабочим временем (Time management) на базе календарей даже без всяких надстроек. Существует много статей и книг по этому вопросу.

Проблема в том, что календари ведутся автономно. А что если нужен ответ на простой вопрос: «Насколько много сотрудники неоправдано отвлекаются на совещания?». Неужели для этого придется закупать bи внедрять систему Time management и настраивать систему отчётов?

Посмотрим как можно собрать информацию из календарей пользователей, используя Exchange Server API.

Во-первых, нам нужна учётная запись, которая будет формировать отчёт. Этой учётной записи нужны права доступа ко всем календарям. Как их предоставить? Можно назначить права доступа командлетом или захватить права на почтовую базу (в стиле Exchange Server 2003). Самый правильный подход — использовать RBAC. Нам нужна имперсонализация:

New-ManagementRoleAssignment -Role ApplicationImpersonation -User <имя нашей учётки>

Разновидностей отчётов может быть бесконечное множество. Поэтому мы запустим PowerShell от имени учётой записи, для которой мы настроили имперсонализацию, и выгрузим все события из всех календарей со всеми свойствами в файл в CSV формате. Затем эту информацию можно загрузить в базу данных или Excel для анализа.

$StartDate = Get-Date 1/1/2020
$EndDate = Get-Date 1/31/2020

# Исправьте этот путь для вашей версии Exchange Server
# Это вообще не нужно для EWS
Add-Type -Path "C:\Program Files\Microsoft\Exchange Server\V15\Bin\Microsoft.Exchange.WebServices.Auth.dll"
$Service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2013_SP1)

$result = Get-MailBox -ResultSize Unlimited | ForEach-Object {

  $SmtpAddress = $_.PrimarySmtpAddress.Address

  Write-Host "MailBox: $SmtpAddress"

  $Service.ImpersonatedUserId = New-Object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress, $SmtpAddress);

  [void]$Service.AutodiscoverUrl($SmtpAddress)

  # Bind to the calendar folder of the mailbox
  $FolderId = new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Calendar,$SmtpAddress)
  $Calendar = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($Service,$FolderId)

  # Define the calendar view
  $CalendarView = New-Object Microsoft.Exchange.WebServices.Data.CalendarView($StartDate,$EndDate)
  $Calendarview.MaxItemsReturned = 1000 	# 1000 is the maximum number of items that can be returned in a CalendarView

  $AppointmentItems = @()
  $AppointmentItems = $Service.FindAppointments($Calendar.Id,$CalendarView)

  if ($AppointmentItems.TotalCount -eq 0)
  {
      #Write-Host "MailBox: $SmtpAddress : AppointmentItems is empty."
      #return;
  } 

  $properties = New-Object Microsoft.Exchange.WebServices.Data.PropertySet(
      [Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties,
      [Microsoft.Exchange.WebServices.Data.AppointmentSchema]::RequiredAttendees,
      [Microsoft.Exchange.WebServices.Data.AppointmentSchema]::OptionalAttendees);

  $res = $service.LoadPropertiesForItems($AppointmentItems, $properties)
  $service.LoadPropertiesForItems($AppointmentItems, $properties)

} | Select-Object -ExpandProperty Item -Property @{name="User"; expression={ $SmtpAddress }},@{name="Count"; expression={ CountMembers $_ }} |
    Select-Object -Property * -ExcludeProperty Body |
    Export-CSV -Path all_items.csv -NoTypeInformation

function CountMembers ($item) {
    $count = 0

    $item.Item.RequiredAttendees |
        ForEach-Object {
           $count += if ($_.MailboxType -eq "PublicGroup") { (Get-ADGroup -Identity $_.Name -Properties members).Members.Count } else { 1 }
        }

    $item.Item.OptionalAttendees |
        ForEach-Object {
           $count += if ($_.MailboxType -eq "PublicGroup") { (Get-ADGroup -Identity $_.Name -Properties members).Members.Count } else { 1 }
        }

    return $count
}

Как бонус скрипт подсчитывает число участников собраний.

Я не буду описывать, как создать какой-то конкретный отчёт в Excel на основе этой информации — это не благодарное дело. Используя фильтры Excel, вы можете найти организаторов собраний, выделить собрания по уникальному идентификтору, вычислить длительность собраний, построить сравнительные графики рабочего времени и много чего ещё.

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

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

  1. New-ManagementRoleAssignment
  2. Configure impersonation
  3. Auditing Exchange Rooms for Double Bookings
  4. Create appointments and meetings by using EWS in Exchange 2013

Узнать время жизни продукта


Хотите узнать, когда заканчивается поддержка продукта, в частности PowerShell, смотрите на сайте https://endoflife.date/powershell