AMO Wrappers for Securing Analysis Service Cube
Analysis Management Objects (AMO) allows you to programmatically interact with the object model of Analysis Services. The AMO layer interacts with Analysis Services by issuing XMLA commands. In this post I will explain the steps to automate the process of securing an Analysis Service Cube by building wrappers around AMO objects.
The fundamental tasks involved in securing a cube are:
1. Role Creation.
2. Role Membership.
3. Cube Permission.
4. Dimension Permission.
5. Dimension Data Security (mostly optional).
That’s what the AMO Wrappers described in subsequent sections are set out to achieve. A simple implementation of the AMO Wrappers would be as shown below.
Imports BennyAustin.SSAS.Wrappers
Module CallAMOWrapper
Sub Main()
Try
'Instantiate Major Objects
Dim objSec As AMOWrapper = New AMOWrapper("localhost", "Adventure Works DW", "Adventure Works DW")
'Backup AS Database before proceeding...
objSec.BackupDatabase("d:\backups\AW.abf")
Dim roleName As String = "Reader"
'Add New Role
If objSec.AddRole(roleName) Then
'Give Read Permission on Cube to New Role
objSec.GrantCubeRead(roleName)
'Give Read Permission on all Dimensions to the New Role
objSec.GrantDimensionRead(roleName)
'Add Members to the New Role
objSec.AddMemberToRole(roleName, "<domain>\benny.austin")
End If
Catch ex As Exception
'log exception using your exception handler
End Try
End Sub
End Module
IMPORTANT: When passing Database Name and Cube Name to AMO methods, pass the ID instead of the Name. Usually the ID is same as the Name, but not always. For e.g. if you restore a cube from a backup and rename the cube, the ID of the cube is different from the name.
Assembly
This AMO wrapper is a VB assembly. The assembly references AnalysisServices.dll having namespace Microsoft.AnalysisServices and usually located in \Program Files\Microsoft SQL Server\90\SDK\Assemblies.
The skeleton of the AMO wrapper would be as shown below:
Imports Microsoft.AnalysisServices Imports System.String Namespace BennyAustin.SSAS.Wrappers 'AMOWrapper '////////////////////////////////////////////////////////////////////////////// ' AMOWrapper: Wrapper class built around Analysis Management Objects (AMO). ' Primarily caters to automate permissions on cube. ' Exceptions are thrown to the caller method. ' Caller method needs to handle exceptions thrown from this class. ' ' Namespace : BennyAustin.SSAS.Wrappers ' ' ' Author: Benny Austin ' ' Revisions: ' Initial Version '////////////////////////////////////////////////////////////////////////////// Public Class AMOWrapper End Class End Namespace
Major Objects
Before we could start working with the Security classes, the fundamental objects must be instantiated as the starting point. Analysis Server, Analysis Service Database and Cube are the fundamental objects and are also called as Major Objects. The code for instantiating the Major Objects are given below along with the associated Getter and Setter methods. Exception is thrown to the caller method by raising AMOException.
GetServer()
'Get instance of Analysis Server Public Function GetServer(ByVal parmConnectionString) As Server Dim objServer As Server = New Server() Try objServer.Connect(parmConnectionString) Catch ServerNotFoundException As ConnectionException Throw ServerNotFoundException Catch GenericAMOException As AmoException Throw GenericAMOException End Try Return objServer End Function 'Property - ServerName Private Property Server() As String Get Return _ServerName End Get Set(ByVal value As String) _ServerName = value End Set End Property 'Property - ServerObject Private Property ServerObj() As Server Get Return _ServerObj End Get Set(ByVal value As Server) _ServerObj = value End Set End Property
GetDatabase()
'Get instance of Database
Public Function GetDatabase(ByVal parmDatabase As String) As Database
Dim DatabaseNotFoundException As AmoException = New AmoException("Analysis Service Database " + parmDatabase + " not found in Analysis Server " + Me.ServerObj.Name)
Dim objDatabase As Database
Try
objDatabase = Me.ServerObj.Databases.FindByName(parmDatabase)
Catch GenericAMOException As AmoException
Throw GenericAMOException
End Try
If objDatabase Is Nothing Then
Throw DatabaseNotFoundException
End If
Return objDatabase
End Function
'Property - DatabaseName
Private Property Database() As String
Get
Return _Database
End Get
Set(ByVal value As String)
_Database = value
End Set
End Property
'Property - DatabaseObject
Private Property DatabaseObj() As Database
Get
Return _DatabaseObj
End Get
Set(ByVal value As Database)
_DatabaseObj = value
End Set
End Property
GetCube()
'Get instance of Cube
Public Function GetCube(ByVal parmCube As String) As Cube
Dim CubeNotFoundException As AmoException = New AmoException("Cube " + parmCube + _
" not found in Analysis Service Database " + _
Me.DatabaseObj.Name + " at Analysis Server " + Me.ServerObj.Name)
Dim objCube As Cube
Try
objCube = Me.DatabaseObj.Cubes(parmCube)
Catch GenericAMOException As AmoException
Throw GenericAMOException
End Try
If objCube Is Nothing Then
Throw CubeNotFoundException
End If
Return objCube
End Function
'Property - CubeName
Private Property Cube() As String
Get
Return _CubeName
End Get
Set(ByVal value As String)
_CubeName = value
End Set
End Property
'Property - CubeObject
Private Property CubeObj() As Cube
Get
Return _CubeObj
End Get
Set(ByVal value As Cube)
_CubeObj = value
End Set
End Property
Constructor
Constructor is a good place to instantiate the Major Objects by calling the GetServer(), GetDatabase() and GetCube() methods created in the previous section.
IMPORTANT: The major objects must be instantiated in this sequence only – Server, Database, Cube
'Constructor Public Sub New(ByVal parmServer As String, _ ByVal parmDatabaseName As String, _ ByVal parmCubeName As String) Me.Server = parmServer Me.Database = parmDatabaseName Me.Cube = parmCubeName 'Instantiates major AMO objects Try Me.ServerObj = GetServer(parmServer) Me.DatabaseObj = GetDatabase(parmDatabaseName) Me.CubeObj = GetCube(parmCubeName) Catch ex As ConnectionException 'raise AMO connection exception Throw ex Catch GenericAMOException As AmoException Throw GenericAMOException End Try End Sub
Destructor
The Destructor performs mopping up operation. The Major Objects are disposed in the correct sequence and the existing Analysis Server session is disconnected.
Public Overloads Sub Finalize() If Me.ServerObj.Connected Then Me.CubeObj.Dispose() Me.DatabaseObj.Dispose() Me.ServerObj.Disconnect() Me.ServerObj.Dispose() End If MyBase.Finalize() End Sub

July 30, 2009 at 00:15
[...] Action in Analysis ServicesCustom SSIS Data Flow Component – Credit Card Number ValidatorAMO Wrappers for Securing Analysis Service CubeHow to Clone an Excel PivotTable?Comparison of KPI Types in SharePoint Server 2007Debugging Custom [...]
January 25, 2010 at 13:56
Hi,
This question has been bugging me for a long time. How can you identify who are the currently connected users on your Analysis Services?
Any insight would be appreciated.
Thanks in advance
January 25, 2010 at 14:26
I think speaking or writing it out loud made me think about it more. Then it downed on me to use SQL Profiler!
… why didn’t I think of this before?!?!
I’m proud and ashamed at the same time in finding out this simple answer to my own question.