Wednesday, December 22, 2004

Sample Script for Setting Item-level Security in Reporting Services

http://blogs.msdn.com/bryanke/archive/2004/03/17/91736.aspx
Report Manager is a solid, Web-based administrative tool for Reporting Services, but it is not the end-all-be-all of administrative functionality for a report server. There are many capabilities available through the Web service that Report Manager does not take advantage of. Case in point: Setting a security policy (otherwise known as a role assignment) for an item using Report Manager is a bit cumbersome, especially if the item for which you want to add a policy is nested several folders deep in your report server namespace. Let's take an example. Let's say you have a folder at “/Budgets/Finance” and you would like to give Bob permission to view reports in the Finance folder. You add a new role assignment for Bob and make him a Browser user of the Finance folder. Bob logs into Report Manager hoping to navigate to the Finance folder, but...Bob is not able to see any folders when he logs in. What gives? Well, unfortunately the path to Bob's Finance folder actually contains three items: The Home or root folder (”/”), the Budgets folder and the Finance folder. Because Bob is not allowed to view the root folder or the Budgets folder, he will never see the Finance folder for which he has permissions. Sorry Bob. In order to give Bob Browser permissions on the Finance folder, you must add Bob as a Browser of both the Home and Budgets folders. If you need to add more groups or users to the Finance folder, it can get downright tiresome. Oh, did I mention that every time you add a policy for Bob to one of the folders, the inherited policy is broken. Yes, that means that any users that enjoyed inherited permissions to those items (for example BUILTIN\Administrators or some other administrator group) no longer have any access rights. You will have to re-add inherited permissions as local policies on each of the three folders in our example. Yikes. Fortunately for Bob, Reporting Services offers rs.exe, a scripting utility with complete access to the Reporting Services Web service. You can use this scripting tool to automate certain tasks and to perform administrative functions that may not be easily automated through Report Manager.
The following sample script can be used to add a security policy for a nested folder or report which automatically gives the user permissions up the namespace tree. After using this script, the item is immediately accessible to the user. In addition, you can use this script to keep or delete the current set of policies for the item, including inherited ones. I haven't given the script the whole battery of tests yet, so if you play around with the code, try it on your test server only. If you find any problems or issues, let me know.

'=====================================================================
' File: AddItemSecurity.rss
'
' Summary: Demonstrates a script that can be used with RS.exe to
' set security on an item in Reporting Services.
'
'---------------------------------------------------------------------
' THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
' KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
' IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
' PARTICULAR PURPOSE.
'=====================================================================*/
'
' Variables that are passed on the command line with the -v switch:
' userName - the name of the user for which to add a policy
' roleName - the name of the role to apply for the user (i.e. Browser, Content Manager)
' itemPath - the path of the item for which you want to add the policy (i.e. /SampleReports)
' keepCurrentPolicy - whether to keep the current policy and add the new one
'
' Sample command line:
' rs -i AddItemSecurity.rss -s http://localhost/reportserver -v userName="MyTestUser"
' -v roleName="Browser" -v itemPath="/SampleReports" -v keepCurrentPolicy="True"

Public Sub Main()
Dim isRoot As Boolean = False
Dim inheritParent As Boolean
Dim policies() As Policy
Dim newPolicies() As Policy
Dim policy As New Policy()
Dim roles(0) As Role
roles(0) = New Role()
roles(0).Name = roleName
policy.Roles = roles
policy.GroupUserName = userName

While Not isRoot
' Once the root of the catalog is reached,
' stop applying policies
If itemPath = "/" Then
isRoot = True
End If
policies = rs.GetPolicies(itemPath, inheritParent)

' If the user selects not to keep inherited or current policy,
' empty the policy
If Not keepCurrentPolicy = "True" Then
policies = Nothing
End If
newPolicies = AddNewPolicy(policy, policies)
rs.SetPolicies(itemPath, newPolicies)
itemPath = GetParentPath(itemPath)
End While
Console.WriteLine("Policy successfully set.")
End Sub 'Main


' Method to parse the path of an item and retrieve
' the parent path of an item
Private Function GetParentPath(currentPath As String) As String
Dim delimiter As String = "/"
Dim rx As New System.Text.RegularExpressions.Regex(delimiter)
Dim childPath As String() = rx.Split(currentPath)

Dim parentLength As Integer = childPath.Length - 1
Dim parentPath(parentLength) As String

Dim i As Integer
For i = 0 To parentLength - 1
parentPath(i) = childPath(i)
Next i
If parentPath.Length = 1 Then
Return "/"
Else
Return String.Join("/", parentPath)
End If
End Function 'GetParentPath

' Takes the policy to add and applies it to the current set
' of policies if applicable
Private Function AddNewPolicy(policyToAdd As Policy, policies() As Policy) As Policy()
If Not (policies Is Nothing) Then
Dim policy As Policy
For Each policy In policies
If policy.GroupUserName = policyToAdd.GroupUserName Then
Throw New Exception("The supplied User policy already exists for the item.")
End If
Next policy
Dim list As New System.Collections.ArrayList(policies)
list.Add(policyToAdd)
Return CType(list.ToArray(GetType(Policy)), Policy())
Else
policies = New Policy(0) {}
policies(0) = policyToAdd
Return policies
End If
End Function 'AddNewPolicy
posted on Wednesday, March 17, 2004 11:26 PM
-->

Thursday, December 09, 2004

Command Line SQL RS

This may be useful...

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/rsprog/htm/rsp_prog_soapapi_dev_2g2q.asp

1. Create a command script to run the .rss Reporting Services script.
rs.exe -i c:\sqlrs.rss -s http://servername/reportserver/

2. Create the rss script.

Public Sub Main()

' Render arguments
Dim result As Byte() = Nothing
Dim reportPath As String = "/ReportPath/"
Dim format As String = "Excel"
Dim historyID As String = Nothing
Dim devInfo As String = "0.125inFalse"

' Prepare report parameter.
Dim parameters(0) As ParameterValue
parameters(0) = New ParameterValue()
parameters(0).Name = "Param1Name"
parameters(0).Value = "Param1Value"

Dim credentials As DataSourceCredentials() = Nothing
Dim showHideToggle As String = Nothing
Dim encoding As String
Dim mimeType As String
Dim warnings As Warning() = Nothing
Dim reportHistoryParameters As ParameterValue() = Nothing
Dim streamIDs As String() = Nothing
Dim sh As New SessionHeader()
rs.SessionHeaderValue = sh

Try
result = rs.Render(reportPath, format, historyID, devInfo, parameters, _
credentials, showHideToggle, encoding, mimeType, reportHistoryParameters, warnings, streamIDs)
sh.SessionId = rs.SessionHeaderValue.SessionId
Console.WriteLine("SessionID after call to Render: {0}", rs.SessionHeaderValue.SessionId)
Console.WriteLine("Execution date and time: {0}", rs.SessionHeaderValue.ExecutionDateTime)
Console.WriteLine("Is new execution: {0}", rs.SessionHeaderValue.IsNewExecution)
Catch e As SoapException
Console.WriteLine(e.Detail.OuterXml)
End Try
' Write the contents of the report to an MHTML file.
Try
Dim stream As FileStream = File.Create("report.xls", result.Length)
Console.WriteLine("File created.")
stream.Write(result, 0, result.Length)
Console.WriteLine("Result written to the file.")
stream.Close()
Catch e As Exception
Console.WriteLine(e.Message)
End Try


' Dim items() As CatalogItem
' items = rs.ListChildren("/", True)

' Dim item As CatalogItem
' For Each item In items
' Console.WriteLine(item.Name)
' Next item
End Sub

Converting Crystal to SQL RS

The holy grail of reporting tools?

http://www.rdlcomponents.com/

http://support.businessobjects.com/library/kbase/articles/c2008882.asp