8

We are currently using SSIS 2012. Is there any way for a user to view execution reports under SSIS Catalog without being ssis_admin or sysadmin?

This is for production environment and we don't want people to manipulate SSIS Catalog projects.

Thanks!

10

Here is our solution (believe me it will work perfectly!)

After investigating the procedure about how the execution reports are stored, we found that every time a job runs, the internal.executions table in SSISDB will be updated. And in order to view the execution report of this run, we need to run something like below:

EXEC SSISDB.catalog.grant_permission 
    @object_type = 4, 
    @object_id = @execution_id, 
    @principal_ID =  13, 
    @permission_type = 1;

This stored procedure will grant a role/user a certain access to an object in database. @object_type means on which type of object you need permissions on (4 means operation); @object_id means the specific object we want to access to; @principal_ID means who want to get the access; permission_type means what kind of access we want to have (1 means read only). For more information, please refer to catalog.grant_permission (SSISDB Database)

Our target is to create a trigger that every time a job runs -- meaning the internal.executions table gets inserted -- using the above SP to grant a role the permission to that operation information.

Then, let's follow the below steps to setup execution report viewing permissions:

  1. Create a user the trigger will be executed as. This user should be able to execute a trigger in SSISDB and have access to SSIS Catalog. In our case, we give it db_owner role and ssis_admin under SSISDB.

    USE [master]
    GO
    CREATE LOGIN [ssis_job_viewer] FROM WINDOWS WITH DEFAULT_DATABASE=[master]
    GO
    USE [SSISDB]
    GO
    CREATE USER [ssis_job_viewer] FOR LOGIN [ssis_job_viewer]
    GO
    USE [SSISDB]
    GO
    ALTER ROLE [db_owner] ADD MEMBER [ssis_job_viewer]
    GO
    USE [SSISDB]
    GO
    ALTER ROLE [ssis_admin] ADD MEMBER [ssis_job_viewer]
    GO
    
  2. Create a role [package_execution_viewer]. This role will be used in the stored procedure we mentioned above.

    USE [SSISDB]
    GO
    CREATE ROLE [package_execution_viewer]
    GO
    
  3. Add users to [package_execution_viewer]

    USE [SSISDB]
    GO
    ALTER ROLE [package_execution_viewer] ADD MEMBER [user1]
    GO
    USE [SSISDB]
    GO
    ALTER ROLE [package_execution_viewer] ADD MEMBER [user2]
    GO
    
  4. Get the principle_id of package_execution_viewer role. This id will be used in above SP also.

    SELECT * from sys.database_principals
    GO
    
  5. Create trigger to grant permission for package_execution_viewer

    USE [SSISDB]
    GO
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    CREATE TRIGGER [internal].[update_viewer_perms]
    ON [internal].[executions]
    WITH EXECUTE AS 'ssis_job_viewer'
    AFTER INSERT
    AS
    declare @execution_id bigint
    BEGIN
    select @execution_id = execution_id from inserted
    EXEC SSISDB.catalog.grant_permission 
        @object_type = 4, 
        @object_id = @execution_id, 
        @principal_ID =  13, 
        @permission_type = 1   **--Note the principal_id needs to be changed**
    END
    GO
    

All set. This way we can let people access to the execution reports without making them as ssis_admin. Try it out and share any thoughts to this post!

7

With the caveat that I'm not a security person...

There is no predefined database role other than ssis_admin that is special to the SSISDB. That allows one to do all the SSIS things but that's clearly more power than a support person should have.

There are two schemas, internal and catalog. Catalog is meant for us, end users to interact with the SSISDB while internal is, to quote a great manual

IST NICHT FÜR DER GEFINGERPOKEN UND MITTENGRABEN!

I fired up profiler and watched as I clicked through the execution reports and the subreports. All the queries are in-line queries against the catalog schema. The procs and function that are in catalog schema all appear to be related to the maintenance and administration of the packages so if you crated a role that

You can run with Martin's answer to grant access to all the catalog based views but as I'm lazy,

I'd try something like this. I Create a role called LookIt, add my member(s) to it and then give them SELECT permission to the entire catalog schema

USE [SSISDB]
GO
CREATE ROLE [LookIt]
GO
USE [SSISDB]
GO
ALTER ROLE [LookIt] ADD MEMBER [MyPeople]
GO
use [SSISDB]
GO
GRANT SELECT ON SCHEMA::[catalog] TO [LookIt]
GO

Edit 2015-10-08

Rejoice, for those of you looking at SQL Server 2016. There is a new SSIS role coming that will allow non-privileged users the ability to use the native reporting tools. That role is called ssis_logreader Granting membership to that role will allow users to access all the reporting without granting them the ability to administer the SSIS instance or the entire server.

3

Very simply... Comment out the WHERE clause in these two views:

SSISDB.catalog.executions
SSISDB.catalog.event_messages

Done.

Change the view catalog.event_messages by commenting out the WHERE clause:

--WHERE opmsg.[operation_id] in (SELECT [id] FROM [internal]. 
--[current_user_readable_operations]) OR (IS_MEMBER('ssis_admin') = 1) OR 
--(IS_SRVROLEMEMBER('sysadmin') = 1)

Do the same to the view Catalog.executions.

I have not encountered any side effects yet and have had it in place for 3 months in both PROD and QA environments.

3

Commenting out the WHERE clause in these views from SSISDB:

  • SSISDB.catalog.executions
  • SSISDB.catalog.event_messages
  • SSISDB.Catalog.folders

and provide the DB_READER access to the user/group in SSISDB. Validated/Verified in SQL 2012/2014

1

So this is an issues that I have run into over the last few days, and I have to say this post has definitely helped, although none of the answer were exactly what helped.

So like this post states, I wanted to give access to view the canned Integration Services Catalog reports, without having to grant the SSIS_admin role in an environment where it isn't needed. And thanks to billinkc for helping me find the answer. Like he said, they fixed this issue in SQL 2016 by adding a database role that allows you to do what we are wanting. That gave me the idea of just copying what SQL 2016 did on the earlier versions. So here is what you have to do:

  • Create a database role inside SSISDB. I named mine ssis_logreader for consistency.
  • Change the logic of the following SSISDB Views to contain OR (IS_MEMBER('ssis_logreader') = 1) in the where clause.
  • [catalog].[operations]

    [catalog].[operation_messages]

    [catalog].[event_message_context]

    [catalog].[event_messages]

    [catalog].[executable_statistics]

    [catalog].[executables]

    [catalog].[execution_component_phases]

    [catalog].[execution_data_statistics]

    [catalog].[execution_data_taps]

    [catalog].[execution_parameter_values]

    [catalog].[execution_property_override_values]

    [catalog].[executions]

    [catalog].[extended_operation_info]

    [catalog].[operation_messages]

    [catalog].[operations]

    [catalog].[packages]

    [catalog].[projects]

    [catalog].[validations]

  • Then add the user and/or user groups to that database role.

Once you have done that, it should take care of your problems.

I have also attached a script that will do all but the last step. Be warned though, it is nearly 700 lines long

Thanks.

USE SSISDB
GO


CREATE ROLE [ssis_logreader]
GO


----------------------------------------------------------------------------------------------
USE [SSISDB]
GO

/****** Object:  View [catalog].[operations]    Script Date: 10/5/2016 8:38:56 AM ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO


ALTER VIEW [catalog].[operations]
AS
SELECT     [operation_id], 
           [operation_type], 
           [created_time],
           [object_type],
           [object_id],
           [object_name],
           [status], 
           [start_time], 
           [end_time], 
           [caller_sid], 
           [caller_name], 
           [process_id],
           [stopped_by_sid],
           [stopped_by_name],
           [server_name],
           [machine_name]
FROM       internal.[operations]
WHERE      [operation_id] in (SELECT [id] FROM [internal].[current_user_readable_operations])
           OR (IS_MEMBER('ssis_admin') = 1)
           OR (IS_SRVROLEMEMBER('sysadmin') = 1)
           OR (IS_MEMBER('ssis_logreader') = 1)


GO

-----------------------------------------------------------------------------------------------------------
USE [SSISDB]
GO

/****** Object:  View [catalog].[operation_messages]    Script Date: 10/5/2016 8:38:32 AM ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO


ALTER VIEW [catalog].[operation_messages]
AS
SELECT     [operation_message_id], 
           [operation_id], 
           [message_time],
           [message_type],  
           [message_source_type], 
           [message], 
           [extended_info_id]
FROM       [internal].[operation_messages] 
WHERE      [operation_id] in (SELECT [id] FROM [internal].[current_user_readable_operations])
           OR (IS_MEMBER('ssis_admin') = 1)
           OR (IS_SRVROLEMEMBER('sysadmin') = 1)
           OR (IS_MEMBER('ssis_logreader') = 1)


GO
-----------------------------------------------------------------------------------------------------------------------


USE [SSISDB]
GO

/****** Object:  View [catalog].[event_message_context]    Script Date: 10/5/2016 8:12:27 AM ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO



ALTER VIEW [catalog].[event_message_context]
AS
SELECT     [context_id],
           [event_message_id],
           [context_depth],
           [package_path],
           [context_type],
           [context_source_name],
           [context_source_id],
           [property_name],
           [property_value]
FROM       [internal].[event_message_context]
WHERE      [operation_id] IN (SELECT [id] FROM [internal].[current_user_readable_operations])
           OR (IS_MEMBER('ssis_admin') = 1)
           OR (IS_SRVROLEMEMBER('sysadmin') = 1)
           OR (IS_MEMBER('ssis_logreader') = 1)


GO


-----------------------------------------------------------------------------------------------------------------------

USE [SSISDB]
GO

/****** Object:  View [catalog].[event_messages]    Script Date: 10/5/2016 8:13:44 AM ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO



ALTER VIEW [catalog].[event_messages]
AS
SELECT     opmsg.[operation_message_id] AS [event_message_id],
           opmsg.[operation_id], 
           opmsg.[message_time],
           opmsg.[message_type],
           opmsg.[message_source_type],  
           opmsg.[message], 
           opmsg.[extended_info_id],
           eventmsg.[package_name],
           eventmsg.[event_name],

           message_source_name = 
                      CASE 
                        WHEN (opmsg.message_source_type = 10) THEN 'ISServerExec' 
                        WHEN (opmsg.message_source_type = 20) THEN 'Transact-SQL stored procedure'
                        ELSE eventmsg.message_source_name
                    END,
           eventmsg.[message_source_id],
           eventmsg.[subcomponent_name],
           eventmsg.[package_path],
           eventmsg.[execution_path],
           eventmsg.[threadID],
           eventmsg.[message_code]
FROM       [internal].[operation_messages] opmsg LEFT JOIN [internal].[event_messages] eventmsg
           ON opmsg.[operation_message_id] = eventmsg.[event_message_id]
WHERE      opmsg.[operation_id] IN (SELECT [id] FROM [internal].[current_user_readable_operations])
           OR (IS_MEMBER('ssis_admin') = 1)
           OR (IS_SRVROLEMEMBER('sysadmin') = 1)
           OR (IS_MEMBER('ssis_logreader') = 1)


GO


----------------------------------------------------------------------------------------------------------------------

USE [SSISDB]
GO

/****** Object:  View [catalog].[executable_statistics]    Script Date: 10/5/2016 8:14:02 AM ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO



ALTER VIEW [catalog].[executable_statistics]
AS
SELECT     [statistics_id], 
           [execution_id],
           [executable_id], 
           [execution_path], 
           [start_time],
           [end_time],
           [execution_duration], 
           [execution_result],
           [execution_value]
FROM       [internal].[executable_statistics]
WHERE      [execution_id] IN (SELECT id FROM [internal].[current_user_readable_operations])
           OR (IS_MEMBER('ssis_admin') = 1)
           OR (IS_SRVROLEMEMBER('sysadmin') = 1)
           OR (IS_MEMBER('ssis_logreader') = 1)



GO


----------------------------------------------------------------------------------------------------------------------

USE [SSISDB]
GO

/****** Object:  View [catalog].[executables]    Script Date: 10/5/2016 8:14:22 AM ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO



ALTER VIEW [catalog].[executables]
AS
SELECT DISTINCT    
           execl.[executable_id], 
           execs.[execution_id], 
           execl.[executable_name], 
           execl.[executable_guid],
           execl.[package_name],
           execl.[package_path]
FROM       ([internal].[executions] execs INNER JOIN [internal].[executable_statistics] stat 
           ON execs.[execution_id] = stat.[execution_id]) INNER JOIN [internal].[executables] execl
           ON stat.[executable_id] = execl.[executable_id] 
WHERE      execs.[execution_id] IN (SELECT id FROM [internal].[current_user_readable_operations])
           OR (IS_MEMBER('ssis_admin') = 1)
           OR (IS_SRVROLEMEMBER('sysadmin') = 1)
           OR (IS_MEMBER('ssis_logreader') = 1)


GO

-------------------------------------------------------------------------------------------------------------------------

USE [SSISDB]
GO

/****** Object:  View [catalog].[execution_component_phases]    Script Date: 10/5/2016 8:24:40 AM ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO


ALTER VIEW [catalog].[execution_component_phases]
AS
SELECT   startPhase.[phase_stats_id] AS [phase_stats_id],
         startPhase.[execution_id] AS [execution_id],
         startPhase.[package_name] AS [package_name],
         startPhase.[task_name] AS [task_name],
         startPhase.[subcomponent_name] AS [subcomponent_name],
         startPhase.[phase] AS [phase],
         startPhase.[phase_time] AS [start_time],
         endPhase.[phase_time] AS [end_time],
         startPhase.[execution_path] AS [execution_path]
FROM     [internal].[execution_component_phases] startPhase LEFT JOIN [internal].[execution_component_phases] endPhase
         ON startPhase.[phase_stats_id] != endPhase.[phase_stats_id]
         AND startPhase.[execution_id] = endPhase.[execution_id]
         AND startPhase.[sequence_id] = endPhase.[sequence_id]
WHERE    startPhase.[is_start] = 'True' AND (endPhase.[is_start] = 'False' OR endPhase.[is_start] IS NULL)
         AND (startPhase.[execution_id] IN (SELECT [id] FROM [internal].[current_user_readable_operations])
         OR (IS_MEMBER('ssis_admin') = 1)
         OR (IS_SRVROLEMEMBER('sysadmin') = 1))
         OR (IS_MEMBER('ssis_logreader') = 1)

GO

--------------------------------------------------------------------------------------------------------------------------

USE [SSISDB]
GO

/****** Object:  View [catalog].[execution_data_statistics]    Script Date: 10/5/2016 8:25:01 AM ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO


ALTER VIEW [catalog].[execution_data_statistics]
AS
SELECT    [data_stats_id],
          [execution_id],
          [package_name],
          [task_name],
          [dataflow_path_id_string],
          [dataflow_path_name],
          [source_component_name],
          [destination_component_name],
          [rows_sent],
          [created_time],
          [execution_path]
FROM      [internal].[execution_data_statistics]
WHERE     [execution_id] IN (SELECT [id] FROM [internal].[current_user_readable_operations])
          OR (IS_MEMBER('ssis_admin') = 1)
          OR (IS_SRVROLEMEMBER('sysadmin') = 1)
          OR (IS_MEMBER('ssis_logreader') = 1)

GO

----------------------------------------------------------------------------------------------------------------------------

USE [SSISDB]
GO

/****** Object:  View [catalog].[execution_data_taps]    Script Date: 10/5/2016 8:25:36 AM ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO


ALTER VIEW [catalog].[execution_data_taps]
AS
SELECT    [data_tap_id],
          [execution_id],
          [package_path],
          [dataflow_path_id_string],
          [dataflow_task_guid],
          [max_rows],
          [filename]
FROM      [internal].[execution_data_taps]
WHERE     [execution_id] IN (SELECT [id] FROM [internal].[current_user_readable_operations])
          OR (IS_MEMBER('ssis_admin') = 1)
          OR (IS_SRVROLEMEMBER('sysadmin') = 1)
          OR (IS_MEMBER('ssis_logreader') = 1)

GO

--------------------------------------------------------------------------------------------------------------------------

USE [SSISDB]
GO

/****** Object:  View [catalog].[execution_parameter_values]    Script Date: 10/5/2016 8:26:01 AM ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO



ALTER VIEW [catalog].[execution_parameter_values]
AS
SELECT     [execution_parameter_id], 
           [execution_id],
           [object_type], 
           [parameter_data_type], 
           [parameter_name], 
           [parameter_value], 
           [sensitive],
           [required],
           [value_set], 
           [runtime_override]
FROM       [internal].[execution_parameter_values]
WHERE      [execution_id] IN (SELECT [id] FROM [internal].[current_user_readable_operations])
           OR (IS_MEMBER('ssis_admin') = 1)
           OR (IS_SRVROLEMEMBER('sysadmin') = 1)
           OR (IS_MEMBER('ssis_logreader') = 1)

GO

------------------------------------------------------------------------------------------------------------------

USE [SSISDB]
GO

/****** Object:  View [catalog].[execution_property_override_values]    Script Date: 10/5/2016 8:26:24 AM ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO



ALTER VIEW [catalog].[execution_property_override_values]
AS
SELECT     [property_id], 
           [execution_id],
           [property_path], 
           [property_value], 
           [sensitive]
FROM       [internal].[execution_property_override_values]
WHERE      [execution_id] IN (SELECT [id] FROM [internal].[current_user_readable_operations])
           OR (IS_MEMBER('ssis_admin') = 1)
           OR (IS_SRVROLEMEMBER('sysadmin') = 1)
           OR (IS_MEMBER('ssis_logreader') = 1)

GO

--------------------------------------------------------------------------------------------------------------------

USE [SSISDB]
GO

/****** Object:  View [catalog].[executions]    Script Date: 10/5/2016 8:26:52 AM ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO




ALTER VIEW [catalog].[executions]
AS
SELECT     execs.[execution_id], 
           execs.[folder_name], 
           execs.[project_name], 
           execs.[package_name],
           execs.[reference_id],
           execs.[reference_type], 
           execs.[environment_folder_name], 
           execs.[environment_name], 
           execs.[project_lsn], 
           execs.[executed_as_sid], 
           execs.[executed_as_name], 
           execs.[use32bitruntime],  
           opers.[operation_type], 
           opers.[created_time],  
           opers.[object_type], 
           opers.[object_id],
           opers.[status], 
           opers.[start_time], 
           opers.[end_time],  
           opers.[caller_sid], 
           opers.[caller_name], 
           opers.[process_id], 
           opers.[stopped_by_sid], 
           opers.[stopped_by_name],
           opers.[operation_guid] AS [dump_id],
           opers.[server_name],
           opers.[machine_name],
           ossysinfos.[total_physical_memory_kb],
           ossysinfos.[available_physical_memory_kb],
           ossysinfos.[total_page_file_kb],
           ossysinfos.[available_page_file_kb],
           ossysinfos.[cpu_count]
FROM       [internal].[executions] execs INNER JOIN [internal].[operations] opers 
           ON execs.[execution_id]= opers.[operation_id]
           LEFT JOIN [internal].[operation_os_sys_info] ossysinfos
           ON ossysinfos.[operation_id]= execs.[execution_id]
WHERE      opers.[operation_id] IN (SELECT id FROM [internal].[current_user_readable_operations])
           OR (IS_MEMBER('ssis_admin') = 1)
           OR (IS_SRVROLEMEMBER('sysadmin') = 1)
           OR (IS_MEMBER('ssis_logreader') = 1)

GO

--------------------------------------------------------------------------------------------------------------------

USE [SSISDB]
GO

/****** Object:  View [catalog].[extended_operation_info]    Script Date: 10/5/2016 8:27:45 AM ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO



ALTER VIEW [catalog].[extended_operation_info]
AS
SELECT     [info_id], 
           [operation_id], 
           [object_name], 
           [object_type],
           [reference_id],
           [status], 
           [start_time], 
           [end_time]
FROM       [internal].[extended_operation_info]
WHERE      [operation_id] IN (SELECT [id] FROM [internal].[current_user_readable_operations])
           OR (IS_MEMBER('ssis_admin') = 1)
           OR (IS_SRVROLEMEMBER('sysadmin') = 1)
           OR (IS_MEMBER('ssis_logreader') = 1)


GO

--------------------------------------------------------------------------------------------------------------------------

USE [SSISDB]
GO

/****** Object:  View [catalog].[operation_messages]    Script Date: 10/5/2016 8:29:30 AM ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO



ALTER VIEW [catalog].[operation_messages]
AS
SELECT     [operation_message_id], 
           [operation_id], 
           [message_time],
           [message_type],  
           [message_source_type], 
           [message], 
           [extended_info_id]
FROM       [internal].[operation_messages] 
WHERE      [operation_id] IN (SELECT [id] FROM [internal].[current_user_readable_operations])
           OR (IS_MEMBER('ssis_admin') = 1)
           OR (IS_SRVROLEMEMBER('sysadmin') = 1)
           OR (IS_MEMBER('ssis_logreader') = 1)

GO

-------------------------------------------------------------------------------------------------------------------------------

USE [SSISDB]
GO

/****** Object:  View [catalog].[operations]    Script Date: 10/5/2016 8:29:55 AM ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO



ALTER VIEW [catalog].[operations]
AS
SELECT     [operation_id], 
           [operation_type], 
           [created_time],
           [object_type],
           [object_id],
           [object_name],
           [status], 
           [start_time], 
           [end_time], 
           [caller_sid], 
           [caller_name], 
           [process_id],
           [stopped_by_sid],
           [stopped_by_name],
           [server_name],
           [machine_name]
FROM       internal.[operations]
WHERE      [operation_id] IN (SELECT [id] FROM [internal].[current_user_readable_operations])
           OR (IS_MEMBER('ssis_admin') = 1)
           OR (IS_SRVROLEMEMBER('sysadmin') = 1)
           OR (IS_MEMBER('ssis_logreader') = 1)

GO

----------------------------------------------------------------------------------------------------------------------------

USE [SSISDB]
GO

/****** Object:  View [catalog].[packages]    Script Date: 10/5/2016 8:31:07 AM ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO



ALTER VIEW [catalog].[packages]
AS
SELECT     pkgs.[package_id], 
           pkgs.[name], 
           pkgs.[package_guid], 
           pkgs.[description],
           pkgs.[package_format_version], 
           pkgs.[version_major],  
           pkgs.[version_minor], 
           pkgs.[version_build], 
           pkgs.[version_comments], 
           pkgs.[version_guid], 
           pkgs.[project_id],
           pkgs.[entry_point],
           pkgs.[validation_status],
           pkgs.[last_validation_time]
FROM       [internal].[packages] pkgs INNER JOIN [internal].[projects] proj ON 
           (pkgs.[project_version_lsn] = proj.[object_version_lsn] 
           AND pkgs.[project_id] = proj.[project_id]) INNER JOIN
           [internal].[object_versions] vers ON ( vers.[object_type] =20 AND
           vers.[object_id] = proj.[project_id] 
           AND vers.[object_version_lsn] = proj.[object_version_lsn])

WHERE      pkgs.[project_id] IN (SELECT [id] FROM [internal].[current_user_readable_projects])
           OR (IS_MEMBER('ssis_admin') = 1)
           OR (IS_SRVROLEMEMBER('sysadmin') = 1)
           OR (IS_MEMBER('ssis_logreader') = 1)

GO

-------------------------------------------------------------------------------------------------------------------

USE [SSISDB]
GO

/****** Object:  View [catalog].[projects]    Script Date: 10/5/2016 8:31:31 AM ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO



ALTER VIEW [catalog].[projects]
AS
SELECT     proj.[project_id],
           [internal].[folders].[folder_id],
           proj.[name],
           proj.[description],
           proj.[project_format_version], 
           proj.[deployed_by_sid], 
           proj.[deployed_by_name], 
           proj.[last_deployed_time], 
           proj.[created_time],
           proj.[object_version_lsn],  
           proj.[validation_status], 
           proj.[last_validation_time]

FROM       [internal].[object_versions] ver INNER JOIN
           [internal].[projects] proj ON (ver.[object_id] = proj.[project_id]
           AND ver.[object_version_lsn] = proj.[object_version_lsn]) INNER JOIN
           [internal].[folders] ON proj.[folder_id] = [internal].[folders].[folder_id]
WHERE      (ver.[object_status] = 'C') 
           AND (ver.[object_type]= 20) 
           AND (
                  proj.[project_id] IN (SELECT [id] FROM [internal].[current_user_readable_projects])
                  OR (IS_MEMBER('ssis_admin') = 1)
                  OR (IS_SRVROLEMEMBER('sysadmin') = 1)
                  OR (IS_MEMBER('ssis_logreader') = 1)
                )


GO
-------------------------------------------------------------------------------------------------------------------

USE [SSISDB]
GO

/****** Object:  View [catalog].[validations]    Script Date: 10/5/2016 8:31:54 AM ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO



ALTER VIEW [catalog].[validations]
AS
SELECT     vals.[validation_id], 
           vals.[environment_scope], 
           vals.[validate_type],
           vals.[folder_name],
           vals.[project_name],         
           vals.[project_lsn],
           vals.[use32bitruntime],
           vals.[reference_id], 
           opers.[operation_type],
           opers.[object_name],  
           opers.[object_type], 
           opers.[object_id], 
           opers.[start_time], 
           opers.[end_time], 
           opers.[status], 
           opers.[caller_sid], 
           opers.[caller_name], 
           opers.[process_id],
           opers.[stopped_by_sid], 
           opers.[stopped_by_name],
           opers.[operation_guid] AS [dump_id],
           opers.[server_name],
           opers.[machine_name]
FROM       [internal].[validations] vals INNER JOIN [internal].[operations] opers 
           ON vals.[validation_id] = opers.[operation_id]
WHERE      opers.[operation_id] IN (SELECT [id] FROM [internal].[current_user_readable_operations])
           OR (IS_MEMBER('ssis_admin') = 1)
           OR (IS_SRVROLEMEMBER('sysadmin') = 1)
           OR (IS_MEMBER('ssis_logreader') = 1)

GO

-------------------------------------------------------------------------------------------------------------------
  • This is very nice. I too opted to create the role for consistency with how I will approach this when we move to 2016. Thank you for the script. – Jason May 14 '18 at 22:56
  • You are welcome. And in reality you can name the role whatever you want, I went with ssis_logreader for consistency with later versions – Chap Wolff May 16 '18 at 20:48
1

On SQL Server 2014

There appears to be a simpler solution.

  1. In the Security folder, create a login (either User or AD Group).
  2. Set Server Roles to "Public"
  3. Set User Mapping to "SSISDB"
  4. In Integration Services Catalogs, navigate to the folder that contains the packages that you want to run reports on
  5. Right click and select "Properties"
  6. Select "Permissions"
  7. Select "Browse"
  8. Select the new user/group that was created on step 1
  9. Grant "Read" and "Read Objects" permissions.

You're done.

Note: I have tested this on SQL Server 2014 and it works. I am sure it will work on 2012 and up.

0

I had the same issue. After looking at the underlining query with the focus on the where clause..

    WHERE      opmsg.[operation_id] in (SELECT [id] FROM [internal].   [current_user_readable_operations])
       OR (IS_MEMBER('ssis_admin') = 1)
       OR (IS_SRVROLEMEMBER('sysadmin') = 1)

As the query checks for membership to the ssis_admin role. I decided to grant my report_reader role to the ssis_admin database role.

Executing the query standalone I was given a select permission error. So, I granted the role select permissions to the catalog and internal schemas.

GRANT SELECT ON SCHEMA::[catalog] TO ssis_admin;
GRANT SELECT ON SCHEMA::[internal] TO ssis_admin;

Hope this helps someone.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.