Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
kewalaka committed Jun 4, 2017
2 parents b439ab6 + ebe2d64 commit ad63ebf
Show file tree
Hide file tree
Showing 5 changed files with 529 additions and 63 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@

- Changes to xSQLServerDatabase
- Changed the readme, SQLInstance should have been SQLInstanceName.
- Changes to xSQLServerRSConfig
- BREAKING CHANGE: removed $SQLAdminCredential parameter. Use common parameter PsDscRunAsCredential (WMF 5.0+) to run the resource under different credentials. PsDscRunAsCredential Windows account must be a sysadmin on SQL Server (issue #568).
- Fixed virtual directory creation for SQL Server 2016.
- Added unit tests (issue #295).
- Added support for configuring URL reservations and virtual directory names (issue #570)

## 7.1.0.0

Expand Down
272 changes: 212 additions & 60 deletions DSCResources/MSFT_xSQLServerRSConfig/MSFT_xSQLServerRSConfig.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,29 @@ function Get-TargetResource
[System.String]
$RSSQLInstanceName,

[parameter(Mandatory = $true)]
[System.Management.Automation.PSCredential]
$SQLAdminCredential
[parameter()]
[System.String]
$ReportServerVirtualDir,

[parameter()]
[System.String]
$ReportsVirtualDir,

[parameter()]
[System.String[]]
$ReportServerReservedUrl,

[parameter()]
[System.String[]]
$ReportsReservedUrl
)

if(Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\RS" -Name $InstanceName -ErrorAction SilentlyContinue)
{
$InstanceKey = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\RS" -Name $InstanceName).$InstanceName
$SQLVersion = ((Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\$InstanceKey\Setup" -Name "Version").Version).Split(".")[0]
$RSConfig = Invoke-Command -ComputerName . -Credential $SQLAdminCredential -ScriptBlock {
$SQLVersion = $args[0]
$InstanceName = $args[1]
$RSConfig = Get-WmiObject -Class MSReportServer_ConfigurationSetting -Namespace "root\Microsoft\SQLServer\ReportServer\RS_$InstanceName\v$SQLVersion\Admin"
$RSConfig
} -ArgumentList @($SQLVersion,$InstanceName)
$SQLVersion = [int]((Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\$InstanceKey\Setup" -Name "Version").Version).Split(".")[0]

$RSConfig = Get-WmiObject -Class MSReportServer_ConfigurationSetting -Namespace "root\Microsoft\SQLServer\ReportServer\RS_$InstanceName\v$SQLVersion\Admin"
if($RSConfig.DatabaseServerName.Contains("\"))
{
$RSSQLServer = $RSConfig.DatabaseServerName.Split("\")[0]
Expand All @@ -48,6 +56,27 @@ function Get-TargetResource
$RSSQLInstanceName = "MSSQLSERVER"
}
$IsInitialized = $RSConfig.IsInitialized

if($IsInitialized)
{
# SSRS Web Portal application name changed in SQL Server 2016
# https://docs.microsoft.com/en-us/sql/reporting-services/breaking-changes-in-sql-server-reporting-services-in-sql-server-2016
$RMApplicationName = if ($SQLVersion -ge 13) { 'ReportServerWebApp' } else { 'ReportManager'}

$ReportServerVirtualDir = $RSConfig.VirtualDirectoryReportServer
$ReportsVirtualDir = $RSConfig.VirtualDirectoryReportManager

$reservedUrls = $RSConfig.ListReservedUrls()

$ReportServerReservedUrl = @()
$ReportsReservedUrl = @()

for($i = 0; $i -lt $reservedUrls.Application.Count; ++$i)
{
if($reservedUrls.Application[$i] -eq "ReportServerWebService") { $ReportServerReservedUrl += $reservedUrls.UrlString[$i] }
if($reservedUrls.Application[$i] -eq "$RMApplicationName") { $ReportsReservedUrl += $reservedUrls.UrlString[$i] }
}
}
}
else
{
Expand All @@ -58,6 +87,10 @@ function Get-TargetResource
InstanceName = $InstanceName
RSSQLServer = $RSSQLServer
RSSQLInstanceName = $RSSQLInstanceName
ReportServerVirtualDir = $ReportServerVirtualDir
ReportsVirtualDir = $ReportsVirtualDir
ReportServerReservedUrl = $ReportServerReservedUrl
ReportsReservedUrl = $ReportsReservedUrl
IsInitialized = $IsInitialized
}

Expand All @@ -82,70 +115,145 @@ function Set-TargetResource
[System.String]
$RSSQLInstanceName,

[parameter(Mandatory = $true)]
[System.Management.Automation.PSCredential]
$SQLAdminCredential
[parameter()]
[System.String]
$ReportServerVirtualDir,

[parameter()]
[System.String]
$ReportsVirtualDir,

[parameter()]
[System.String[]]
$ReportServerReservedUrl,

[parameter()]
[System.String[]]
$ReportsReservedUrl
)

if(Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\RS" -Name $InstanceName -ErrorAction SilentlyContinue)
{
Invoke-Command -ComputerName . -Credential $SQLAdminCredential -ScriptBlock {
# this is a separate PS session, need to load Common Code again
Import-Module $using:currentPath\..\..\xSQLServerHelper.psm1 -Verbose -ErrorAction Stop
# smart import of the SQL module
Import-SQLPSModule
$InstanceKey = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\RS" -Name $InstanceName).$InstanceName
$SQLVersion = [int]((Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\$InstanceKey\Setup" -Name "Version").Version).Split(".")[0]
if($InstanceName -eq "MSSQLSERVER")
{
$RSServiceName = "ReportServer"
if([string]::IsNullOrEmpty($ReportServerVirtualDir)) { $ReportServerVirtualDir = "ReportServer" }
if([string]::IsNullOrEmpty($ReportsVirtualDir)) { $ReportsVirtualDir = "Reports" }
$RSDatabase = "ReportServer"
}
else
{
$RSServiceName = "ReportServer`$$InstanceName"
if([string]::IsNullOrEmpty($ReportServerVirtualDir)) { $ReportServerVirtualDir = "ReportServer_$InstanceName" }
if([string]::IsNullOrEmpty($ReportsVirtualDir)) { $ReportsVirtualDir = "Reports_$InstanceName" }
$RSDatabase = "ReportServer`$$InstanceName"
}
if($RSSQLInstanceName -eq "MSSQLSERVER")
{
$RSConnection = "$RSSQLServer"
}
else
{
$RSConnection = "$RSSQLServer\$RSSQLInstanceName"
}
$Language = (Get-WMIObject -Class Win32_OperatingSystem -Namespace root/cimv2 -ErrorAction SilentlyContinue).OSLanguage
$RSConfig = Get-WmiObject -Class MSReportServer_ConfigurationSetting -Namespace "root\Microsoft\SQLServer\ReportServer\RS_$InstanceName\v$SQLVersion\Admin"

$InstanceName = $args[0]
$RSSQLServer = $args[1]
$RSSQLInstanceName = $args[2]
$InstanceKey = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\RS" -Name $InstanceName).$InstanceName
$SQLVersion = ((Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\$InstanceKey\Setup" -Name "Version").Version).Split(".")[0]
if($InstanceName -eq "MSSQLSERVER")
{
$RSServiceName = "ReportServer"
$RSVirtualDirectory = "ReportServer"
$RMVirtualDirectory = "Reports"
$RSDatabase = "ReportServer"
}
else
{
$RSServiceName = "ReportServer`$$InstanceName"
$RSVirtualDirectory = "ReportServer_$InstanceName"
$RMVirtualDirectory = "Reports_$InstanceName"
$RSDatabase = "ReportServer`$$InstanceName"
}
if($RSSQLInstanceName -eq "MSSQLSERVER")
{
$RSConnection = "$RSSQLServer"
}
else
{
$RSConnection = "$RSSQLServer\$RSSQLInstanceName"
}
$Language = (Get-WMIObject -Class Win32_OperatingSystem -Namespace root/cimv2 -ErrorAction SilentlyContinue).OSLanguage
$RSConfig = Get-WmiObject -Class MSReportServer_ConfigurationSetting -Namespace "root\Microsoft\SQLServer\ReportServer\RS_$InstanceName\v$SQLVersion\Admin"
if($RSConfig.VirtualDirectoryReportServer -ne $RSVirtualDirectory)
# SSRS Web Portal application name changed in SQL Server 2016
# https://docs.microsoft.com/en-us/sql/reporting-services/breaking-changes-in-sql-server-reporting-services-in-sql-server-2016
$RMApplicationName = if ($SQLVersion -ge 13) { 'ReportServerWebApp' } else { 'ReportManager'}

if(!$RSConfig.IsInitialized)
{
New-VerboseMessage -Message "Initializing Reporting Services on $RSSQLServer\$RSSQLInstanceName."

if($ReportServerReservedUrl -eq $null) { $ReportServerReservedUrl = @("http://+:80") }
if($ReportsReservedUrl -eq $null) { $ReportsReservedUrl = @("http://+:80") }

if($RSConfig.VirtualDirectoryReportServer -ne $ReportServerVirtualDir)
{
$null = $RSConfig.SetVirtualDirectory("ReportServerWebService",$RSVirtualDirectory,$Language)
$null = $RSConfig.ReserveURL("ReportServerWebService","http://+:80",$Language)
New-VerboseMessage -Message "Setting report server virtual directory on $RSSQLServer\$RSSQLInstanceName to $ReportServerVirtualDir."
$null = $RSConfig.SetVirtualDirectory("ReportServerWebService",$ReportServerVirtualDir,$Language)
$ReportServerReservedUrl | ForEach-Object {
New-VerboseMessage -Message "Adding report server URL reservation on $RSSQLServer\$RSSQLInstanceName`: $_."
$null = $RSConfig.ReserveURL("ReportServerWebService",$_,$Language)
}
}
if($RSConfig.VirtualDirectoryReportManager -ne $RMVirtualDirectory)
if($RSConfig.VirtualDirectoryReportManager -ne $ReportsVirtualDir)
{
$null = $RSConfig.SetVirtualDirectory("ReportManager",$RMVirtualDirectory,$Language)
$null = $RSConfig.ReserveURL("ReportManager","http://+:80",$Language)
New-VerboseMessage -Message "Setting reports virtual directory on $RSSQLServer\$RSSQLInstanceName to $ReportServerVirtualDir."
$null = $RSConfig.SetVirtualDirectory($RMApplicationName,$ReportsVirtualDir,$Language)
$ReportsReservedUrl | ForEach-Object {
New-VerboseMessage -Message "Adding reports URL reservation on $RSSQLServer\$RSSQLInstanceName`: $_."
$null = $RSConfig.ReserveURL($RMApplicationName,$_,$Language)
}
}
$RSCreateScript = $RSConfig.GenerateDatabaseCreationScript($RSDatabase,$Language,$false)

# Determine RS service account
$RSSvcAccountUsername = (Get-WmiObject -Class Win32_Service | Where-Object {$_.Name -eq $RSServiceName}).StartName
$RSRightsScript = $RSConfig.GenerateDatabaseRightsScript($RSSvcAccountUsername,$RSDatabase,$false,$true)

# smart import of the SQL module
Import-SQLPSModule
Invoke-Sqlcmd -ServerInstance $RSConnection -Query $RSCreateScript.Script
Invoke-Sqlcmd -ServerInstance $RSConnection -Query $RSRightsScript.Script
$RSConfig.SetDatabaseConnection($RSConnection,$RSDatabase,2,"","")
$RSConfig.InitializeReportServer($RSConfig.InstallationID)

} -ArgumentList @($InstanceName,$RSSQLServer,$RSSQLInstanceName)
$null = $RSConfig.SetDatabaseConnection($RSConnection,$RSDatabase,2,"","")
$null = $RSConfig.InitializeReportServer($RSConfig.InstallationID)
}
else
{
$currentConfig = Get-TargetResource @PSBoundParameters

if(![string]::IsNullOrEmpty($ReportServerVirtualDir) -and ($ReportServerVirtualDir -ne $currentConfig.ReportServerVirtualDir))
{
New-VerboseMessage -Message "Setting report server virtual directory on $RSSQLServer\$RSSQLInstanceName to $ReportServerVirtualDir."

# to change a virtual directory, we first need to remove all URL reservations,
# change the virtual directory and re-add URL reservations
$currentConfig.ReportServerReservedUrl | ForEach-Object { $null = $RSConfig.RemoveURL("ReportServerWebService",$_,$Language) }
$RSConfig.SetVirtualDirectory("ReportServerWebService",$ReportServerVirtualDir,$Language)
$currentConfig.ReportServerReservedUrl | ForEach-Object { $null = $RSConfig.ReserveURL("ReportServerWebService",$_,$Language) }
}

if(![string]::IsNullOrEmpty($ReportsVirtualDir) -and ($ReportsVirtualDir -ne $currentConfig.ReportsVirtualDir))
{
New-VerboseMessage -Message "Setting reports virtual directory on $RSSQLServer\$RSSQLInstanceName to $ReportServerVirtualDir."

# to change a virtual directory, we first need to remove all URL reservations,
# change the virtual directory and re-add URL reservations
$currentConfig.ReportsReservedUrl | ForEach-Object { $null = $RSConfig.RemoveURL($RMApplicationName,$_,$Language) }
$RSConfig.SetVirtualDirectory($RMApplicationName,$ReportsVirtualDir,$Language)
$currentConfig.ReportsReservedUrl | ForEach-Object { $null = $RSConfig.ReserveURL($RMApplicationName,$_,$Language) }
}

if(($ReportServerReservedUrl -ne $null) -and ((Compare-Object -ReferenceObject $currentConfig.ReportServerReservedUrl -DifferenceObject $ReportServerReservedUrl) -ne $null))
{
$currentConfig.ReportServerReservedUrl | ForEach-Object {
$null = $RSConfig.RemoveURL("ReportServerWebService",$_,$Language)
}

$ReportServerReservedUrl | ForEach-Object {
New-VerboseMessage -Message "Adding report server URL reservation on $RSSQLServer\$RSSQLInstanceName`: $_."
$null = $RSConfig.ReserveURL("ReportServerWebService",$_,$Language)
}
}

if(($ReportsReservedUrl -ne $null) -and ((Compare-Object -ReferenceObject $currentConfig.ReportsReservedUrl -DifferenceObject $ReportsReservedUrl) -ne $null))
{
$currentConfig.ReportsReservedUrl | ForEach-Object {
$null = $RSConfig.RemoveURL($RMApplicationName,$_,$Language)
}

$ReportsReservedUrl | ForEach-Object {
New-VerboseMessage -Message "Adding reports URL reservation on $RSSQLServer\$RSSQLInstanceName`: $_."
$null = $RSConfig.ReserveURL($RMApplicationName,$_,$Language)
}
}
}
}

if(!(Test-TargetResource @PSBoundParameters))
Expand Down Expand Up @@ -173,13 +281,57 @@ function Test-TargetResource
[System.String]
$RSSQLInstanceName,

[parameter(Mandatory = $true)]
[System.Management.Automation.PSCredential]
$SQLAdminCredential
[parameter()]
[System.String]
$ReportServerVirtualDir,

[parameter()]
[System.String]
$ReportsVirtualDir,

[parameter()]
[System.String[]]
$ReportServerReservedUrl,

[parameter()]
[System.String[]]
$ReportsReservedUrl
)

$result = (Get-TargetResource @PSBoundParameters).IsInitialized
$result = $true

$currentConfig = Get-TargetResource @PSBoundParameters

if(!$currentConfig.IsInitialized)
{
New-VerboseMessage -Message "Reporting services $RSSQLServer\$RSSQLInstanceName are not initialized."
$result = $false
}

if(![string]::IsNullOrEmpty($ReportServerVirtualDir) -and ($ReportServerVirtualDir -ne $currentConfig.ReportServerVirtualDir))
{
New-VerboseMessage -Message "Report server virtual directory on $RSSQLServer\$RSSQLInstanceName is $($currentConfig.ReportServerVirtualDir), should be $ReportServerVirtualDir."
$result = $false
}

if(![string]::IsNullOrEmpty($ReportsVirtualDir) -and ($ReportsVirtualDir -ne $currentConfig.ReportsVirtualDir))
{
New-VerboseMessage -Message "Reports virtual directory on $RSSQLServer\$RSSQLInstanceName is $($currentConfig.ReportsVirtualDir), should be $ReportsVirtualDir."
$result = $false
}

if(($ReportServerReservedUrl -ne $null) -and ((Compare-Object -ReferenceObject $currentConfig.ReportServerReservedUrl -DifferenceObject $ReportServerReservedUrl) -ne $null))
{
New-VerboseMessage -Message "Report server reserved URLs on $RSSQLServer\$RSSQLInstanceName are $($currentConfig.ReportServerReservedUrl -join ', '), should be $($ReportServerReservedUrl -join ', ')."
$result = $false
}

if(($ReportsReservedUrl -ne $null) -and ((Compare-Object -ReferenceObject $currentConfig.ReportsReservedUrl -DifferenceObject $ReportsReservedUrl) -ne $null))
{
New-VerboseMessage -Message "Reports reserved URLs on $RSSQLServer\$RSSQLInstanceName are $($currentConfig.ReportsReservedUrl -join ', ')), should be $($ReportsReservedUrl -join ', ')."
$result = $false
}

$result
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ class MSFT_xSQLServerRSConfig : OMI_BaseResource
[Key, Description("Name of the SQL Server Reporting Services instance to be configured.")] String InstanceName;
[Required, Description("Name of the SQL Server to host the Reporting Service database.")] String RSSQLServer;
[Required, Description("Name of the SQL Server instance to host the Reporting Service database.")] String RSSQLInstanceName;
[Required, EmbeddedInstance("MSFT_Credential"), Description("Credential to be used to perform the configuration.")] String SQLAdminCredential;
[Write, Description("Report Server virtual directory name. Optional.")] String ReportServerVirtualDir;
[Write, Description("Report Manager/Report Web App virtual directory name. Optional.")] String ReportsVirtualDir;
[Write, Description("Report Server reserved URLs. Optional.")] String ReportServerReservedUrl[];
[Write, Description("Report Manager/Report Web App reserved URLs. Optional.")] String ReportsReservedUrl[];
[Read, Description("Is the Reporting Services instance initialized.")] Boolean IsInitialized;
};
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -867,7 +867,7 @@ This resource is used to create a server role, when Ensure is set to 'Present'.

### xSQLServerRSConfig

No description.
Initializes and configures SQL Reporting Services server.

#### Requirements

Expand All @@ -879,7 +879,10 @@ No description.
* **[String] InstanceName** _(Key)_: Name of the SQL Server Reporting Services instance to be configured.
* **[String] RSSQLServer** _(Required)_: Name of the SQL Server to host the Reporting Service database.
* **[String] RSSQLInstanceName** _(Required)_: Name of the SQL Server instance to host the Reporting Service database.
* **[PSCredential] SQLAdminCredential** _(Required)_: Credential to be used to perform the configuration.
* **[String] ReportServerVirtualDir** _(Write)_: Report Server Web Service virtual directory. Optional.
* **[String] ReportsVirtualDir** _(Write)_: Report Manager virtual directory. Optional.
* **[String[]] ReportServerReservedUrl** _(Write)_: Report Server URL reservations. Optional. If not specified, "http://+:80" URL reservation will be used.
* **[String[]] ReportsReservedUrl** _(Write)_: Report Manager URL reservations. Optional. If not specified, "http://+:80" URL reservation will be used.

#### Read-Only Properties from Get-TargetResource

Expand Down
Loading

0 comments on commit ad63ebf

Please sign in to comment.