script to list all database level permissions in a Database

  • I found this script online..

    SELECT prin.[name] [User], sec.state_desc + ' ' + sec.permission_name [Permission]

    FROM [sys].[database_permissions] sec

    JOIN [sys].[database_principals] prin

    ON sec.[grantee_principal_id] = prin.[principal_id]

    WHERE sec.class = 0

    ORDER BY [User], [Permission];

    but the results are this: 2 columns - User and Permission

    User Permission

    User1 GRANT CONNECT

    User2 GRANT CONNECT

    not very useful. IS there a way in SQL Server (2005/2008/2012) to run a script against a Database that will show all users that have permissions to that Database and the type of permissions??? read\write\update etc...

  • This is my script, feel free to use it, I'm constantly updating and improving it

    SET NOCOUNT ON

    DECLARE @sql NVARCHAR(MAX)

    DECLARE @majver INT

    DECLARE @minver INT

    DECLARE @build VARCHAR(16)

    SET @sql = ''

    SET @build = CAST(SERVERPROPERTY('ProductVersion') AS VARCHAR(16))

    SET @majver = PARSENAME(@build, 4)

    SET @minver = PARSENAME(@build, 2)

    SELECT @sql =

    '--======================================================================================' + CHAR(10) +

    '--==== IMPORTANT: Before executing these scripts check the details to ensure they ====' + CHAR(10) +

    '--==== are valid. For instance when crossing domains ====' + CHAR(10) +

    '--======================================================================================' + CHAR(10)

    PRINT @sql

    SET @sql = ''

    --=======================================================

    --Check the database encrytion state

    --=======================================================

    IF CAST(@majver AS INT) >= 10

    BEGIN

    IF (SELECT count(*) FROM sys.databases WHERE database_id = DB_ID() AND is_encrypted = 1) = 0

    BEGIN

    SELECT @sql = '/*Database ' + QUOTENAME(DB_NAME(DB_ID())) + ' is not TDE protected*/'

    END

    ELSE

    BEGIN

    SELECT @sql =

    CASE

    WHEN encryption_state <> 0 THEN '/*Database ' + QUOTENAME(DB_NAME(DB_ID())) +

    ' is TDE protected, ensure you have a backup of the certificate that the database is protected with,

    including the certificates public and private key passswords*/' + CHAR(13) + CHAR(13) +

    '/*Important: You must create a master key on your new instance first, do this now using the script below.' +

    CHAR(10) + '===================================================================================' +

    CHAR(13) + '*!Don''t forget to change the password before executing!*/' + CHAR(13) + CHAR(13) +

    'CREATE MASTER KEY ENCRYPTION BY PASSWORD = ''P@ssw0rd1''' + CHAR(13)

    WHEN encryption_state = 0 THEN @sql + CHAR(13)

    END

    FROM sys.dm_database_encryption_keys

    WHERE database_id = DB_ID()

    END

    PRINT @sql + CHAR(13) + CHAR(13)

    END

    ELSE IF CAST(@majver AS INT) <= 9

    BEGIN

    PRINT 'before 2008'

    end

    SET @sql = ''

    --========================================================

    --script any certificates in the database

    --========================================================

    IF (SELECT COUNT(*) FROM sys.certificates) = 0

    BEGIN

    SELECT @sql = @sql + '/*No certificates found*/'

    PRINT @sql + CHAR(13) + CHAR(13)

    END

    ELSE

    BEGIN

    SELECT @sql = '/*Scripting all user certificates' + CHAR(10) +

    '===================================================================================*/' + CHAR(13) + CHAR(13)

    SELECT @sql = @sql + 'CREATE CERTIFICATE ' + name +

    ' ENCRYPTION BY PASSWORD = ''P@ssw0rd1''

    WITH SUBJECT = ''' + issuer_name + ''',

    EXPIRY_DATE = ''' + CONVERT(NVARCHAR(25), expiry_date, 120) + '''' + CHAR(13)

    FROM sys.certificates

    PRINT @sql + CHAR(13) + CHAR(13)

    END

    SET @sql = ''

    --======================================================

    --Script the database users

    --======================================================

    SELECT principal_id INTO #users FROM sys.database_principals WHERE type IN ('U', 'G', 'S') AND principal_id > 4

    IF (SELECT COUNT(*) FROM #users) = 0

    BEGIN

    SELECT @sql = @sql + '/*No database users found*/'

    PRINT @sql + CHAR(13) + CHAR(13)

    END

    ELSE

    BEGIN

    SET CONCAT_NULL_YIELDS_NULL OFF

    DECLARE @uid INT

    SELECT @sql = '/*Scripting all database users and schemas' + CHAR(10) +

    '===================================================================================' + CHAR(13) +

    'Note: these are the users found in the database, but they may not all be valid, check them first*/' +

    CHAR(13) + CHAR(13)

    WHILE (SELECT TOP 1 principal_id FROM #users) IS NOT NULL

    BEGIN

    SELECT TOP 1 @uid = principal_id FROM #users

    SELECT @sql = @sql + 'IF (SELECT name FROM sys.database_principals WHERE name = ''' +

    dp.name + ''') IS NULL' + CHAR(13) + 'BEGIN' + CHAR(13) + CHAR(9) +

    'CREATE USER ' + QUOTENAME(dp.name) +

    CASE

    WHEN SUSER_SNAME(dp.sid) IS NULL THEN ' WITHOUT LOGIN'

    ELSE ' FOR LOGIN ' + QUOTENAME(SUSER_SNAME(dp.sid))

    END +

    CASE

    WHEN dp.type <> 'G' AND dp.default_schema_name IS NULL THEN ' WITH DEFAULT_SCHEMA = [dbo]'

    WHEN dp.type IN ('G', 'C', 'K') THEN ''

    ELSE ' WITH DEFAULT_SCHEMA = [' + dp.default_schema_name + ']'

    END + CHAR(13) + 'END'

    FROM sys.database_principals dp LEFT OUTER JOIN

    sys.schemas sch ON dp.principal_id = sch.principal_id

    WHERE dp.principal_id = @uid AND dp.[type] IN ('U', 'G', 'S') AND dp.principal_id > 4

    GROUP BY dp.name, dp.type, dp.sid, dp.default_schema_name

    PRINT @sql + CHAR(10)

    DELETE FROM #users WHERE principal_id = @uid

    SELECT @sql = ''

    END

    DROP TABLE #users

    END

    SELECT @sql = ''

    --========================================================

    --Script any users that are protected by a cert

    --========================================================

    IF (SELECT count(*) FROM sys.database_principals dp INNER JOIN sys.certificates c ON dp.sid = c.sid

    WHERE dp.type = 'C' AND dp.principal_id > 4) = 0

    BEGIN

    SELECT @sql = @sql + '/*No certificated users found*/'

    PRINT @sql + CHAR(13) + CHAR(13)

    END

    ELSE

    BEGIN

    SELECT @sql = '/*Scripting all certificated database users' + CHAR(10) +

    '===================================================================================*/' + CHAR(13) + CHAR(9)

    SELECT @sql = @sql + 'CREATE USER ' + QUOTENAME(dp.name) + ' FOR CERTIFICATE ' + c.name

    FROM sys.database_principals dp INNER JOIN sys.certificates c ON dp.sid = c.sid

    WHERE dp.type = 'C' AND dp.principal_id > 4

    PRINT @sql + CHAR(13) + CHAR(13)

    END

    SET @sql = ''

    --========================================================

    --script database roles from the database

    --========================================================

    IF (SELECT COUNT(*) FROM sys.database_principals WHERE type = 'R' AND is_fixed_role <> 1 AND principal_id > 4) = 0

    BEGIN

    SELECT @sql = @sql + '/*No database roles found*/'

    PRINT @sql + CHAR(13) + CHAR(13)

    END

    ELSE

    BEGIN

    SELECT @sql = '/*Scripting all database roles' + CHAR(10) +

    '===================================================================================*/' + CHAR(13)

    SELECT @sql = @sql + 'IF (SELECT name FROM sys.database_principals WHERE name = ''' + dp.name +

    ''' AND type = ''R'') IS NULL' + CHAR(13) + 'BEGIN' + CHAR(13) + CHAR(9) +

    'CREATE ROLE ' + QUOTENAME(dp.name) + ' AUTHORIZATION ' + QUOTENAME(dp2.name) + CHAR(13) + 'END' + CHAR(13)

    FROM sys.database_principals dp INNER JOIN sys.database_principals dp2

    ON dp.owning_principal_id = dp2.principal_id

    WHERE dp.type = 'R' AND dp.is_fixed_role <> 1 AND dp.principal_id > 4

    PRINT @sql + CHAR(13) + CHAR(13)

    END

    SET @sql = ''

    --=======================================================

    --script all schema permissions

    --=======================================================

    SELECT @sql = '/*Scripting all user schema permissions' + CHAR(10) +

    '===================================================================================*/' + CHAR(13)

    --Script the permission grants on the schemas

    SELECT @sql = @sql + CHAR(13) + dp.state_desc COLLATE latin1_general_ci_as + ' ' +

    dp.permission_name + ' ON ' + dp.class_desc + '::' + QUOTENAME(sch.name) +

    ' TO ' + QUOTENAME(dp2.name) + ' AS ' + QUOTENAME(dp3.name)

    FROM sys.database_permissions dp

    INNER JOIN sys.schemas sch ON dp.grantor_principal_id = sch.principal_id

    INNER JOIN sys.database_principals dp2 ON dp.grantee_principal_id = dp2.principal_id

    INNER JOIN sys.database_principals dp3 ON dp.grantor_principal_id = dp3.principal_id

    WHERE dp.class = 3

    PRINT @sql + CHAR(13) + CHAR(13)

    SET @sql = ''

    --=========================================================

    --script Application roles from the database

    --=========================================================

    IF (SELECT COUNT(*) FROM sys.database_principals WHERE type = 'A') = 0

    BEGIN

    SELECT @sql = @sql + '/*No application roles found*/'

    PRINT @sql + CHAR(13) + CHAR(13)

    END

    ELSE

    BEGIN

    SELECT @sql = '/*Scripting all application roles' + CHAR(10) +

    '===================================================================================*/' + CHAR(13)

    SELECT @sql = @sql + 'CREATE APPLICATION ROLE ' + dp.name + ' WITH DEFAULT_SCHEMA = ' +

    QUOTENAME(dp.default_schema_name) + ', PASSWORD = N''P@ssw0rd1''' + CHAR(10)

    FROM sys.database_principals dp

    WHERE dp.type = 'A' AND dp.is_fixed_role <> 1 AND dp.principal_id > 4

    PRINT @sql + CHAR(13) + CHAR(13)

    END

    SET @sql = ''

    --===============================================================

    --got the roles so now we need to get any nested role permissions

    --===============================================================

    IF (SELECT COUNT(*) from sys.database_principals dp inner join sys.database_role_members drm

    ON dp.principal_id = drm.member_principal_id inner join sys.database_principals dp2

    ON drm.role_principal_id = dp2.principal_id WHERE dp.type = 'R') = 0

    BEGIN

    SELECT @sql = + '/*No nested roles found*/'

    PRINT @sql + CHAR(13) + CHAR(13)

    END

    ELSE

    BEGIN

    SELECT @sql = '/*Scripting all nested roles' + CHAR(10) +

    '===================================================================================*/' + CHAR(13)

    SELECT @sql = @sql + 'EXEC sp_addrolemember ''' + dp2.name + ''', ''' + dp.name + '''' + CHAR(10)

    FROM sys.database_principals dp

    INNER JOIN sys.database_role_members drm

    ON dp.principal_id = drm.member_principal_id

    INNER JOIN sys.database_principals dp2

    ON drm.role_principal_id = dp2.principal_id

    WHERE dp.type = 'R'

    PRINT @sql + CHAR(13) + CHAR(13)

    END

    SET @sql = ''

    --================================================================

    --Scripting all user connection grants

    --================================================================

    IF(SELECT COUNT(*) FROM sys.database_permissions dpm INNER JOIN sys.database_principals dp

    ON dpm.grantee_principal_id = dp.principal_id WHERE dp.principal_id > 4 AND dpm.class = 0 AND dpm.type = 'CO') = 0

    BEGIN

    SELECT @sql = + '/*No database connection GRANTS found*/'

    PRINT @sql + CHAR(13) + CHAR(13)

    END

    ELSE

    BEGIN

    SELECT @sql = '/*Scripting all database and connection GRANTS' + CHAR(10) +

    '===================================================================================*/' + CHAR(13)

    SELECT @sql = @sql + dpm.state_desc COLLATE Latin1_General_CI_AS + ' ' +

    dpm.permission_name COLLATE Latin1_General_CI_AS + ' TO ' + QUOTENAME(dp.name) + CHAR(13)

    FROM sys.database_permissions dpm INNER JOIN sys.database_principals dp

    ON dpm.grantee_principal_id = dp.principal_id

    WHERE dp.principal_id > 4 AND dpm.class = 0 --AND dpm.type = 'CO'

    PRINT @sql + CHAR(13) + CHAR(13)

    END

    SET @sql = ''

    --=================================================================

    --Now all the object level permissions

    --=================================================================

    IF(SELECTCOUNT(*) FROM sys.database_permissions dbpe INNER JOIN sys.database_principals dbpr

    ON dbpr.principal_id = dbpe.grantee_principal_id INNER JOIN sys.objects obj

    ON dbpe.major_id = obj.object_id WHERE obj.type NOT IN ('IT','S','X')) = 0

    BEGIN

    SELECT @sql = + '/*No database user object GRANTS found*/'

    PRINT @sql + CHAR(13) + CHAR(13)

    END

    ELSE

    BEGIN

    SELECT @sql = '/*Scripting all database user object GRANTS' + CHAR(10) +

    '===================================================================================*/' + CHAR(13)

    --SELECT @sql = @sql + 'USE ' + QUOTENAME(DB_NAME(DB_ID())) + CHAR(13) --+ 'GO'

    PRINT @sql --+ CHAR(10)

    SET @sql = ''

    IF OBJECT_ID('tempdb..#objgrants') IS NOT NULL

    BEGIN

    DROP TABLE #objgrants

    END

    CREATE TABLE #objgrants(

    state_descVARCHAR(60)

    , perm_nameNVARCHAR(128)

    , sch_nameNVARCHAR(128)

    , maj_IDNVARCHAR(128)

    , nameNVARCHAR(128)

    , pr_nameNVARCHAR(128)

    )

    DECLARE @state_desc VARCHAR(60)

    DECLARE @perm_name NVARCHAR(128), @sch_name NVARCHAR(128), @maj_ID NVARCHAR(128)

    DECLARE @name NVARCHAR(128), @pr_name NVARCHAR(128)

    INSERT INTO #objgrants

    SELECT CASE dbpe.[state] WHEN 'W' THEN 'GRANT'

    ELSE dbpe.state_desc COLLATE Latin1_General_CI_AS

    END AS [state_desc]

    , dbpe.permission_name COLLATE Latin1_General_CI_AS AS perm_name

    , sch.name AS sch_name

    , OBJECT_NAME(dbpe.major_id) AS maj_ID

    , dbpr.name AS name

    , CASE dbpe.[state] WHEN 'W' THEN '] WITH GRANT OPTION'

    ELSE ']' END AS pr_name

    FROM sys.database_permissions dbpe INNER JOIN sys.database_principals dbpr

    ON dbpr.principal_id = dbpe.grantee_principal_id

    INNER JOIN sys.objects obj ON dbpe.major_id = obj.object_id

    INNER JOIN sys.schemas sch ON obj.schema_id = sch.schema_id

    WHERE obj.type NOT IN ('IT','S','X')

    ORDER BY dbpr.name, obj.name

    WHILE (SELECT COUNT(*) FROM #objgrants) > 0

    BEGIN

    SELECT TOP 1 @state_desc = state_desc, @perm_name = perm_name, @sch_name = sch_name,

    @maj_ID = maj_ID, @name = name, @pr_name = pr_name FROM #objgrants

    SELECT @sql = @sql + @state_desc + ' ' + @perm_name +

    ' ON [' + @sch_name + '].[' + @maj_ID + '] TO [' + @name + @pr_name

    PRINT @sql

    SET @sql = ''

    DELETE FROM #objgrants WHERE state_desc = @state_desc AND perm_name = @perm_name

    AND sch_name = @sch_name AND maj_ID = @maj_ID AND name = @name AND pr_name = @pr_name

    END

    PRINT CHAR(13)

    DROP TABLE #objgrants

    END

    SET @sql = ''

    --=================================================================

    --Now script all the database roles the user have permissions to

    --=================================================================

    IF(SELECT COUNT(*) FROM sys.database_principals dp

    INNER JOIN sys.database_role_members drm ON dp.principal_id = drm.role_principal_id

    INNER JOIN sys.database_principals dp2 ON drm.member_principal_id = dp2.principal_id

    WHERE dp2.principal_id > 4 AND dp2.type <> 'R') = 0

    BEGIN

    SELECT @sql = + '/*No database user role GRANTS found*/'

    PRINT @sql + CHAR(13) + CHAR(13)

    END

    ELSE

    BEGIN

    SELECT @sql = '/*Scripting all database user role permissions' + CHAR(10) +

    '===================================================================================*/' + CHAR(13)

    --SELECT @sql = @sql + 'USE ' + QUOTENAME(DB_NAME(DB_ID())) + CHAR(13) + CHAR(10)

    SELECT @sql = @sql + 'EXEC sp_addrolemember ''' + dp.name + ''', ''' + dp2.name + '''' + CHAR(13)

    FROM sys.database_principals dp

    INNER JOIN sys.database_role_members drm ON dp.principal_id = drm.role_principal_id

    INNER JOIN sys.database_principals dp2 ON drm.member_principal_id = dp2.principal_id

    WHERE dp2.principal_id > 4 AND dp2.type <> 'R'

    PRINT @sql + CHAR(13) + CHAR(13)

    END

    SET @sql = ''

    SELECT @sql = '--Finished!' + CHAR(13) + '--Please ensure you check the script output before executing' +

    CHAR(13) + '--against your target database.'

    PRINT @sql

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

    "Ya can't make an omelette without breaking just a few eggs" 😉

  • Thanks, someone provided this and it did the trick

    SET ANSI_NULLS ON

    SET QUOTED_IDENTIFIER ON

    SET ANSI_PADDING ON

    -- CREATING A TEMP TABLE TO LOAD WITH DATABASE ROLES

    CREATE TABLE [TEMPDB].[DBO].[DB_ROLES]

    ( [DBNAME] [SYSNAME] ,

    [USERNAME] [SYSNAME] , [DB_OWNER] [VARCHAR](3) ,

    [DB_ACCESSADMIN] [VARCHAR](3) ,

    [DB_SECURITYADMIN] [VARCHAR](3) ,

    [DB_DDLADMIN] [VARCHAR](3) ,

    [DB_DATAREADER] [VARCHAR](3) ,

    [DB_DATAWRITER] [VARCHAR](3) ,

    [DB_DENYDATAREADER] [VARCHAR](3) ,

    [DB_DENYDATAWRITER] [VARCHAR](3) ,

    [DT_CREATE] [DATETIME] NOT NULL,

    [DT_UPDATE] [DATETIME] NOT NULL,

    [DT_REPORT] [DATETIME] NOT NULL CONSTRAINT [DF__DBROLES__CUR_DAT__3A179ED3] DEFAULT (GETDATE()) ) ON [PRIMARY];

    INSERT INTO [TEMPDB].[DBO].[DB_ROLES] EXEC SP_MSFOREACHDB ' SELECT ''?'' AS DBNAME,

    USERNAME, MAX(CASE ROLENAME WHEN ''DB_OWNER'' THEN ''YES'' ELSE ''NO'' END) AS DB_OWNER,

    MAX(CASE ROLENAME WHEN ''DB_ACCESSADMIN '' THEN ''YES'' ELSE ''NO'' END) AS DB_ACCESSADMIN ,

    MAX(CASE ROLENAME WHEN ''DB_SECURITYADMIN'' THEN ''YES'' ELSE ''NO'' END) AS DB_SECURITYADMIN,

    MAX(CASE ROLENAME WHEN ''DB_DDLADMIN'' THEN ''YES'' ELSE ''NO'' END) AS DB_DDLADMIN,

    MAX(CASE ROLENAME WHEN ''DB_DATAREADER'' THEN ''YES'' ELSE ''NO'' END) AS DB_DATAREADER,

    MAX(CASE ROLENAME WHEN ''DB_DATAWRITER'' THEN ''YES'' ELSE ''NO'' END) AS DB_DATAWRITER,

    MAX(CASE ROLENAME WHEN ''DB_DENYDATAREADER'' THEN ''YES'' ELSE ''NO'' END) AS DB_DENYDATAREADER,

    MAX(CASE ROLENAME WHEN ''DB_DENYDATAWRITER'' THEN ''YES'' ELSE ''NO'' END) AS DB_DENYDATAWRITER,

    CREATEDATE,

    UPDATEDATE,

    GETDATE()

    FROM (

    SELECT B.NAME AS USERNAME, C.NAME AS ROLENAME, B.CREATEDATE, B.UPDATEDATE

    FROM

    [?].DBO.SYSMEMBERS A JOIN [?].DBO.SYSUSERS B ON A.MEMBERUID = B.UID

    JOIN [?].DBO.SYSUSERS C ON A.GROUPUID = C.UID )S

    GROUP BY USERNAME, CREATEDATE, UPDATEDATE

    ORDER BY USERNAME'

    SELECT SERVERPROPERTY('SERVERNAME') AS [SERVERNAME],

    B.NAME AS [LOGINNAME],

    CASE B.SYSADMIN WHEN '1' THEN 'YES' ELSE 'NO' END AS SYSADMIN,

    CASE B.SECURITYADMIN WHEN '1' THEN 'YES' ELSE 'NO' END AS SECURITYADMIN,

    CASE B.SETUPADMIN WHEN '1' THEN 'YES' ELSE 'NO' END AS SETUPADMIN,

    CASE B.PROCESSADMIN WHEN '1' THEN 'YES' ELSE 'NO' END AS PROCESSADMIN,

    CASE B.DISKADMIN WHEN '1' THEN 'YES' ELSE 'NO' END AS DISKADMIN,

    CASE B.DBCREATOR WHEN '1' THEN 'YES' ELSE 'NO' END AS DBCREATOR,

    CASE B.BULKADMIN WHEN '1' THEN 'YES' ELSE 'NO' END AS BULKADMIN, B.DBNAME AS [DEFAULT_DBNAME],

    A.* INTO #LOGINS FROM [TEMPDB].[DBO].[DB_ROLES]

    A RIGHT JOIN MASTER..SYSLOGINS B ON A.USERNAME=B.NAME

    --WHERE B.ISNTUSER=1 --INCLUDE TO EXCLUDE THE SQL LOGINS

    SELECT * FROM #LOGINS ORDER BY [LOGINNAME]

    DROP TABLE [TEMPDB].[DBO].[DB_ROLES]

    DROP TABLE #LOGINS

  • That won't dump specific permission grants, which is what you requested

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

    "Ya can't make an omelette without breaking just a few eggs" 😉

  • Perry Whittle (8/6/2015)


    This is my script, feel free to use it, I'm constantly updating and improving it

    Oddly enough, I just started looking for such a thing. Timing couldn't be better. Thanks, Perry. I'll check it out.

    --Jeff Moden


    RBAR is pronounced "ree-bar" and is a "Modenism" for Row-By-Agonizing-Row.
    First step towards the paradigm shift of writing Set Based code:
    ________Stop thinking about what you want to do to a ROW... think, instead, of what you want to do to a COLUMN.

    Change is inevitable... Change for the better is not.


    Helpful Links:
    How to post code problems
    How to Post Performance Problems
    Create a Tally Function (fnTally)

  • Jeff Moden (8/10/2015)


    Thanks, Perry. I'll check it out.

    You're welcome Jeff

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

    "Ya can't make an omelette without breaking just a few eggs" 😉

  • Here is something I wrote the other day to grab DB_NAME, LOGIN_NAME, DB_ROLE for all databases on the instance.

    if object_id('tempdb..#db_roles') is not null drop table #db_roles;

    create table #db_roles

    (

    primary key ( login_name, db_name, db_role) with (ignore_dup_key = on)

    , login_name varchar(180) not null

    , db_name varchar(180) not null

    , db_role varchar(8000) not null

    );

    insert into #db_roles

    exec sp_msforeachdb

    '

    use ?;

    SELECT DISTINCT m.NAME login_name, db_name() db_name, upper(p.NAME)db_role

    FROM sys.database_role_members rm

    JOIN sys.database_principals p

    ON rm.role_principal_id = p.principal_id

    JOIN sys.database_principals m

    ON rm.member_principal_id = m.principal_id

    ';

    select * from #db_roles;

    Also, you might be surprised by who all or what all appears in the SYSADMIN role as well.

    if object_id('tempdb..#server_roles') is not null drop table #server_roles;

    create table #server_roles

    (

    primary key ( login_name, server_role) with (ignore_dup_key = on)

    , login_name varchar(180) not null

    , server_role varchar(8000) not null

    );

    insert into #server_roles

    SELECT member.name AS login_name, upper(role.name) AS server_role

    FROM sys.server_principals AS member

    LEFT JOIN sys.server_role_members

    ON sys.server_role_members.member_principal_id = member.principal_id

    LEFT JOIN sys.server_principals AS role

    ON sys.server_role_members.role_principal_id = role.principal_id

    WHERE role.name is not null

    ORDER BY member.name;

    insert into #server_roles

    select name as login_name, 'SYSADMIN' as server_role

    from sys.server_principals

    where IS_SRVROLEMEMBER ('sysadmin',name) > 0;

    select * from #server_roles;

    However, the big reveal may be when you use the following extended procedure call to drill down and take a look at what individual member accounts are in a domain or windows group mapped to a SYSADMIN or database role.

    xp_logininfo '[ntgroup_name]', 'members';

    "Do not seek to follow in the footsteps of the wise. Instead, seek what they sought." - Matsuo Basho

  • You folks should write and article each on these. Throw in something about sp_ValidateLogins and both would be to kill for.

    --Jeff Moden


    RBAR is pronounced "ree-bar" and is a "Modenism" for Row-By-Agonizing-Row.
    First step towards the paradigm shift of writing Set Based code:
    ________Stop thinking about what you want to do to a ROW... think, instead, of what you want to do to a COLUMN.

    Change is inevitable... Change for the better is not.


    Helpful Links:
    How to post code problems
    How to Post Performance Problems
    Create a Tally Function (fnTally)

Viewing 8 posts - 1 through 7 (of 7 total)

You must be logged in to reply to this topic. Login to reply