Get List of Users with 'sa' Priveleges
Applicability:
SQL Server 2000: N/A
SQL Server 2005: Tested
SQL Server 2008: Tested
SQL Server 2008R2: Tested
SQL Server 2012: Tested
SQL Server 2014: Tested
SQL Server 2016: Tested
SQL Server 2017: Tested
Credits:
Author: Unknown
Date: 9 Jun 2020
Description
Get a list of users with 'sa' priveleges.
Code
set xact_abort off;
set nocount on;
declare @principals table
(
primary key ( principal_type, principal_name, member_name ),
principal_type varchar(180) not null,
principal_name varchar(180) not null,
member_name varchar(180) not null,
create_date datetime null,
modify_date datetime null,
admin_role_desc varchar(180) null,
logininfo_note varchar(8000) null
);
-- insert all accounts and groups into result:
insert into @principals
select
type_desc,
name,
'-' as member_name,
create_date,
modify_date,
(
case is_srvrolemember('sysadmin',name) when 1 then 'sysadmin|' else null end
+ case is_srvrolemember('securityadmin',name) when 1 then 'securityadmin|' else null end
+ case is_srvrolemember('serveradmin',name) when 1 then 'serveradmin|' else null end
+ case is_srvrolemember('setupadmin',name) when 1 then 'setupadmin|' else null end
+ case is_srvrolemember('processadmin',name) when 1 then 'processadmin|' else null end
+ case is_srvrolemember('diskadmin',name) when 1 then 'diskadmin|' else null end
+ case is_srvrolemember('dbcreator',name) when 1 then 'dbcreator|' else null end
+ case is_srvrolemember('bulkadmin',name) when 1 then 'bulkadmin|' else null end
) as admin_role_desc,
null as logininfo_note
from sys.server_principals
;
declare @admin_groups table
(
primary key ( group_type, group_name ),
group_type varchar(180) not null,
group_name varchar(180) not null
);
declare @logininfo table
(
primary key ( account_name, permission_path ),
account_name varchar(180) not null,
type varchar(180) null,
privilege varchar(180) null,
mapped_login_name varchar(180) null,
permission_path varchar(180) not null
);
-- For each domain group with admin privilages,
-- insert one record for each of it's member accounts into the result:
declare @group_type varchar(180), @group_name varchar(180);
select @group_type = '*', @group_name = '*';
while @group_name is not null
begin
select @group_type = null, @group_name = null;
select top 1 @group_type = principal_type, @group_name = principal_name
from @principals
where principal_type in ('windows_group')
and member_name = '-'
and admin_role_desc is not null
and principal_name not in (select group_name from @admin_groups);
if @group_name is not null
begin
-- Call xp_logininfo to return all domain accounts belonging to group:
insert @admin_groups values (@group_type, @group_name);
begin try
delete from @logininfo;
insert into @logininfo
exec master..xp_logininfo @group_name,'members';
-- Update number of members for group to logininfo_note:
update @principals
set logininfo_note = 'xp_logininfo returned '+cast(@@rowcount as varchar(9))+' members.'
where principal_type in ('windows_group')
and principal_name = @group_name
and member_name = '-';
end try
begin catch
-- If an error occurred, then update it to logininfo_note, and then continue:
update @principals
set logininfo_note = 'xp_logininfo returned error '+cast(error_number() as varchar(9))
where principal_type in ('windows_group')
and principal_name = @group_name
and member_name = '-';
end catch
-- For each group member, insert a record into the result:
insert into @principals
select
@group_type as principal_type,
@group_name as principal_name,
account_name as member_name,
null as create_date,
null as modify_date,
(select admin_role_desc
from @principals
where principal_type = @group_type
and principal_name = @group_name
and member_name = '-') as admin_role_desc,
null as logininfo_note
from @logininfo;
-- For each group member that is a group,
-- insert a record of type 'WINDOWS_GROUP' into the result:
insert into @principals
select
'WINDOWS_GROUP' as principal_type,
account_name as principal_name,
'-' as member_name,
null as create_date,
null as modify_date,
(select admin_role_desc
from @principals
where principal_type = @group_type
and principal_name = @group_name
and member_name = '-') as admin_role_desc,
null as logininfo_note
from @logininfo
where type = 'group'
and not exists
(select 1
from @principals
where principal_type = 'WINDOWS_GROUP' and principal_name = account_name and member_name = '-'
);
end;
end;
-- Return result of only those accounts, groups, and members who have an admin role:
select principal_type, principal_name, logininfo_note, member_name, create_date, modify_date, admin_role_desc
from @principals
where admin_role_desc is not null -- only get users with admin role granted
order by principal_type, principal_name, member_name;