Во многих проектах требуется инсталляционный скрипт либо пакет, который выполняет обновление серверной части приложения. Необходимость, в первую очередь, обусловлена отсутствием прямого доступа к производственному серверу у разработчиков.
Инсталлятор в виде скрипта лучше всего подходит для установки без явного входа на сервер (RDP). Также скрипт может быть выполнен в виде одного загрузчика, который и выполнит все остальное. В текущих проектах мы реализовали что-то наподобие PsGet[1], только для внутреннего билд-сервера.
Приложение большое и состоит из ряда компонентов, одним из которых является модуль отчетности, построенный на базе SSRS.
Для управления сервером отчетности Майкрософт предоставила разработчикам вэб-сервис ReportingService2005.asmx[2].
Начальная установка и настройка сервера отчетности не входит в ответственность разработчиков и выполняется командами с определенной ответственностью. Также мы не создаем Data Sources, т.к. они могут содержать конфиденциальную информацию (такую как пароли для подключения).
В результате, упомянутые выше настройки, а также распределение доступа скрипту делать не нужно. Остается только добавлять и обновлять сами отчеты.
PowerShell 2.0 предоставляет возможность создание прокси для работы с вэб-сервисом через команду New-WebServiceProxy[3].
Достаточно указать путь к описанию сервиса на WSDL[4]. У нас используется Windows Authentication, поэтому в подключении укажем ключ UseDefaultCredential. В самом прокси сервиса также необходимо указать способ аутентификации.
Параметр $ssrsHost содержит полный путь, на который настроен наш сервис (обычно, servername/ReportServer).
Для того чтобы создать либо обновить отчет, существует метод CreateReport[5].
В качестве параметров он принимает имя отчета, имя родительской папки (папки позволяют группировать отчеты и задавать к ним различные политики безопасности), флаг необходимости перезаписи, бинарный контент файла отчета и доболнительные свойства (обычно не используются, можно передать $null).
Метод возвращает коллекцию сообщений об ошибках и предупреждениях.
Из них мы будем игнорировать сообщения о Data Sources.
Вызов будет выглядеть как:
Таким образом добавление отчета можно обернуть в функцию:
Представленная реализация решает задачу добавления и обновления одного отчета и может быть использована в подобном коде:
Вызов вэб-сервисов через PowerShell является тривиальной задачей.
Сам вэб-сервис для SSRS предоставляет гораздо больше возможностей, например, добавление/изменение Data Source посредством метода CreateDataSource[6].
В текущем проекте у нас реализован объемный модуль расширений.
Так, обновлять отчеты можно также по условию, например, на основе времени последней модификации файлов[7]:
Иногда необходимо обновлять Data Source у отчета, для чего используется метод SetItemDataSources.
Часто требуется сбрасывать кэш у отчета (метод FlushCache).
В общем, все просто и расширяемо.
Инсталлятор в виде скрипта лучше всего подходит для установки без явного входа на сервер (RDP). Также скрипт может быть выполнен в виде одного загрузчика, который и выполнит все остальное. В текущих проектах мы реализовали что-то наподобие PsGet[1], только для внутреннего билд-сервера.
Приложение большое и состоит из ряда компонентов, одним из которых является модуль отчетности, построенный на базе SSRS.
Для управления сервером отчетности Майкрософт предоставила разработчикам вэб-сервис ReportingService2005.asmx[2].
Предварительные установки
Начальная установка и настройка сервера отчетности не входит в ответственность разработчиков и выполняется командами с определенной ответственностью. Также мы не создаем Data Sources, т.к. они могут содержать конфиденциальную информацию (такую как пароли для подключения).
В результате, упомянутые выше настройки, а также распределение доступа скрипту делать не нужно. Остается только добавлять и обновлять сами отчеты.
Подключение к сервису
PowerShell 2.0 предоставляет возможность создание прокси для работы с вэб-сервисом через команду New-WebServiceProxy[3].
Достаточно указать путь к описанию сервиса на WSDL[4]. У нас используется Windows Authentication, поэтому в подключении укажем ключ UseDefaultCredential. В самом прокси сервиса также необходимо указать способ аутентификации.
function Connect-ReportingService([string]$ssrsHost)
{
$reportingServiceUrl = $ssrsHost + "ReportService2005.asmx?wsdl"
$reportingService= New-WebServiceProxy $reportingServiceUrl -UseDefaultCredential -namespace ReportingWebService
$reportingService.UseDefaultCredentials = $true
$reportingService
}
Параметр $ssrsHost содержит полный путь, на который настроен наш сервис (обычно, servername/ReportServer).
Добавление отчета
Для того чтобы создать либо обновить отчет, существует метод CreateReport[5].
В качестве параметров он принимает имя отчета, имя родительской папки (папки позволяют группировать отчеты и задавать к ним различные политики безопасности), флаг необходимости перезаписи, бинарный контент файла отчета и доболнительные свойства (обычно не используются, можно передать $null).
Метод возвращает коллекцию сообщений об ошибках и предупреждениях.
Из них мы будем игнорировать сообщения о Data Sources.
Вызов будет выглядеть как:
(Connect-ReportingService $ssrsHost).CreateReport($report, $ssrsFolder, $true, $reportBits, $null)
Таким образом добавление отчета можно обернуть в функцию:
function Deploy-Report([string]$ssrsHost, [string]$reportDir, [string]$report, [string]$ssrsFolder)
{
<#
здесь указан относительный путь, по которому
находится отчет (специфично для конкретного проекта)
#>
$relativeReportLocation = "..\RS\$($report).rdl"
# проверяем наличие файла
if (-not (Test-Path $reportFile))
{
$message = "Report file '{0}' was not found!" -f $reportFile
Write-Warning $message
return
}
# считываем файл отчета
[byte[]]$reportBits = [System.IO.File]::ReadAllBytes($reportFile)
# собственно, добавление отчета и получение результата
$warnings = (Connect-ReportingService $ssrsHost).CreateReport($report, $ssrsFolder, $true, $reportBits, $null)
# очищаем сообщения от "лишних"
$cleanedWarnings = $warnings | ? { -not $_.Message.Contains("data source") }
# вывод результата на экран (в зависимости от количества ошибок)
if(!$cleanedWarnings)
{
$result = "Report '{0}' published successfully with no warnings" -f $report
Write-Host $result
Write-Host ""
}
else
{
$warningHeader = "Report '{0}' published with warnings: " -f $report
Write-Host $warningHeader
$cleanedWarnings | % {
Write-Warning $_.Message
}
Write-Host ""
}
}
Выводы
Представленная реализация решает задачу добавления и обновления одного отчета и может быть использована в подобном коде:
ls "..\RS\*.rdl") | % { $_.Name.Replace(".rdl", "") } | % { Deploy-Report $ssrsHost $reportDir $report $ssrsFolder }
Вызов вэб-сервисов через PowerShell является тривиальной задачей.
Сам вэб-сервис для SSRS предоставляет гораздо больше возможностей, например, добавление/изменение Data Source посредством метода CreateDataSource[6].
Расширения, которые можно сделать
В текущем проекте у нас реализован объемный модуль расширений.
Так, обновлять отчеты можно также по условию, например, на основе времени последней модификации файлов[7]:
# получаем существующий список отчетов (рекурсивно)
$deployedReports = (Connect-ReportingService $config).ListChildren($ssrsFolder, 1)
[hashtable]$deployedReportsMap = @{}
$deployedReports | % { $deployedReportsMap[$_.Name + '.rdl'] = $_ }
ls "..\RS\*.rdl") `
| ? {
( -not $deployedReportsMap.ContainsKey($_.Name)) -or
$deployedReportsMap[$_.Name].ModifiedDate -lt $_.LastWriteTime
} `
| % { $_.Name.Replace(".rdl", "") } `
| % { Deploy-Report $ssrsHost $reportDir $report $ssrsFolder }
Иногда необходимо обновлять Data Source у отчета, для чего используется метод SetItemDataSources.
Часто требуется сбрасывать кэш у отчета (метод FlushCache).
В общем, все просто и расширяемо.
- psget.net
- msdn.microsoft.com/en-us/library/reportservice2005.reportingservice2005.aspx
- technet.microsoft.com/en-us/library/dd315258.aspx
- www.w3.org/TR/wsdl
- msdn.microsoft.com/en-us/library/reportservice2005.reportingservice2005.createreport.aspx
- msdn.microsoft.com/en-us/library/reportservice2005.reportingservice2005.createdatasource.aspx
- метод ListChildren: msdn.microsoft.com/en-us/library/reportservice2005.reportingservice2005.listchildren.aspx