ค้นหาผู้ใช้กำพร้า


12

ใน SQL Server 2005 มีวิธีการค้นหาผู้ใช้ที่ไม่มีอยู่ในระดับเซิร์ฟเวอร์ (บัญชีที่ถูกลบในระดับเซิร์ฟเวอร์ แต่ไม่ได้ถูกแยกจากฐานข้อมูลก่อนที่จะถูกลบ) หรือบัญชีที่ไม่ได้เชื่อมโยง (บัญชีอาจถูกลบที่ระดับเซิร์ฟเวอร์ แต่ไม่ใช่ระดับ db จากนั้นอ่านอีกครั้ง แต่ระดับ db ไม่เคยล้างข้อมูล)

ฉันมีเซิร์ฟเวอร์ที่ยุ่งมากและมันก็ยอดเยี่ยมมากถ้ามีคำถามให้เรียกใช้เพื่อค้นหาสิ่งเหล่านี้


คำตอบ:


15

สคริปต์ต่อไปนี้จากเว็บไซต์ Brent Ozar ไม่ จำกัด iterates ผ่านฐานข้อมูลและรายชื่อผู้ใช้กำพร้าทั้งหมดด้วยฐานข้อมูลพร้อมกับคำสั่งลดลงจะลบออก อาจมีวิธีการจัดการที่ใหม่กว่า / ใหม่กว่า แต่สิ่งนี้ดูเหมือนว่าจะทำงานได้อย่างถูกต้องใน 2005-2012

DECLARE @SQL nvarchar(2000)
DECLARE @name nvarchar(128)
DECLARE @database_id int

SET NOCOUNT ON;

IF NOT EXISTS 
    (SELECT name FROM tempdb.sys.tables WHERE name like '%#orphan_users%')
BEGIN
    CREATE TABLE #orphan_users
        (
        database_name nvarchar(128) NOT NULL,
        [user_name] nvarchar(128) NOT NULL,
        drop_command_text nvarchar(200) NOT NULL
        )
END

CREATE TABLE #databases 
(
    database_id int NOT NULL
    , database_name nvarchar(128) NOT NULL
    , processed bit NOT NULL
)

INSERT
    #databases 
    ( database_id
    , database_name
    , processed )
SELECT 
    database_id
    , name
    , 0 
FROM 
    master.sys.databases 
WHERE 
    name NOT IN 
    ('master'
    , 'tempdb'
    , 'msdb'
    , 'distribution'
    , 'model')

WHILE (SELECT COUNT(processed) FROM #databases WHERE processed = 0) > 0
BEGIN
    SELECT TOP 1
        @name = database_name,
        @database_id = database_id
    FROM #databases
    WHERE processed = 0
    ORDER BY database_id

    SELECT @SQL =

'USE [' + @name + '];
INSERT INTO #orphan_users (database_name, user_name, drop_command_text)
SELECT 
    DB_NAME()
    , u.name
    , ' + '''' 
    + 'USE [' + @name + ']; ' 
    + 'DROP USER [' 
    + '''' + ' + u.name 
    + ' + '''' + '] ' 
    + '''' + '
FROM
    master..syslogins l
RIGHT JOIN 
    sysusers u 
ON l.sid = u.sid
WHERE   
    l.sid IS NULL
AND issqlrole <> 1
AND isapprole <> 1
AND ( u.name <> ' + '''' + 'INFORMATION_SCHEMA' + ''''
        + ' AND u.name <> ' + '''' + 'guest' + ''''
        + ' AND u.name <> ' + '''' + 'dbo' + ''''
        + ' AND u.name <> ' + '''' + 'sys' + ''''
        + ' AND u.name <> ' + '''' + 'system_function_schema' + '''' + ')'

    PRINT @SQL;

    EXEC sys.sp_executesql @SQL

    UPDATE 
        #databases 
    SET 
        processed = 1 
    WHERE 
        database_id = @database_id;
END

SELECT 
    database_name
    , [user_name]
    , drop_command_text 
FROM 
    #orphan_users 
ORDER BY 
    [database_name]
    , [user_name];

DROP TABLE #databases;
DROP TABLE #orphan_users;

SET NOCOUNT OFF;

4

ฉันต้องการ THANK Mark ก่อนเพื่อโพสต์สคริปต์ มันช่วยให้ฉันประหยัดเวลาเขียนตั้งแต่เริ่มต้น ฉันแก้ไขมันเล็กน้อยตั้งแต่พบปัญหาที่ฉันได้รับข้อผิดพลาดที่ระบุว่า "ฐานข้อมูลหลักเป็นเจ้าของสคีมาในฐานข้อมูลและไม่สามารถหลุด" ข้อผิดพลาด ฉันแก้ไขสคริปต์เพื่อสร้างคำสั่งสำหรับข้อผิดพลาดของ SCHEMA และสำหรับข้อผิดพลาดของบทบาทหากคุณควรได้รับเช่นกัน

หวังว่านี่จะช่วยให้ใครบางคนที่นั่น ..

DECLARE @SQL nvarchar(2000)
DECLARE @name nvarchar(128)
DECLARE @database_id int

SET NOCOUNT ON;

IF NOT EXISTS 
    (SELECT name FROM tempdb.sys.tables WHERE name like '%#orphan_users%')
BEGIN
    CREATE TABLE #orphan_users
        (
        database_name nvarchar(128) NOT NULL,
        [user_name] nvarchar(128) NOT NULL,
        drop_command_text nvarchar(200) NOT NULL,
        drop_schema_text nvarchar(200) not null,
        drop_role_text nvarchar(200) not null
        )
END

CREATE TABLE #databases 
(
    database_id int NOT NULL
    , database_name nvarchar(128) NOT NULL
    , processed bit NOT NULL
)

INSERT
    #databases 
    ( database_id
    , database_name
    , processed )
SELECT 
    database_id
    , name
    , 0 
FROM 
    master.sys.databases 
WHERE 
    name NOT IN 
    ('master'
    , 'tempdb'
    , 'msdb'
    , 'distribution'
    , 'model')

WHILE (SELECT COUNT(processed) FROM #databases WHERE processed = 0) > 0
BEGIN
    SELECT TOP 1
        @name = database_name,
        @database_id = database_id
    FROM #databases
    WHERE processed = 0
    ORDER BY database_id

    SELECT @SQL =

'USE [' + @name + '];
INSERT INTO #orphan_users (database_name, user_name, drop_command_text, Drop_schema_text, drop_role_text)
SELECT 
    DB_NAME()
    , u.name
    , 
        ' + '''' 
        + 'USE [' + @name + ']; ' 
        + 'DROP USER [' 
        + '''' + ' + u.name 
        + ' + '''' + '] ' 
        + '''' + '
    , 
        ' + '''' + 'USE [' + @name + ']; ' +
        'ALTER AUTHORIZATION ON SCHEMA::[' 
        + '''' + ' + u.name 
        + ' + '''' + ']  TO [dbo]' + '''' + '
    , 
        ' + '''' + 'USE [' + @name + ']; ' +
        'ALTER AUTHORIZATION ON Role::[' 
        + '''' + ' + u.name 
        + ' + '''' + ']  TO [dbo]' + '''' + '
FROM
    master..syslogins l
RIGHT JOIN 
    sysusers u 
ON l.sid = u.sid
WHERE   
    l.sid IS NULL
AND issqlrole <> 1
AND isapprole <> 1
AND ( u.name <> ' + '''' + 'INFORMATION_SCHEMA' + ''''
        + ' AND u.name <> ' + '''' + 'guest' + ''''
        + ' AND u.name <> ' + '''' + 'dbo' + ''''
        + ' AND u.name <> ' + '''' + 'sys' + ''''
        + ' AND u.name <> ' + '''' + 'system_function_schema' + '''' + ')'

    PRINT @SQL;

    EXEC sys.sp_executesql @SQL

    UPDATE 
        #databases 
    SET 
        processed = 1 
    WHERE 
        database_id = @database_id;
END

SELECT 
    database_name
    , [user_name]
    , drop_command_text 
    , Drop_schema_text
    , drop_role_text
FROM 
    #orphan_users 
ORDER BY 
    [database_name]
    , [user_name];

DROP TABLE #databases;
DROP TABLE #orphan_users;

SET NOCOUNT OFF;

3

sp_change_users_login นี้ถูกคิดค่าเสื่อมราคาตั้งแต่ SQL 2008 แต่ยังใช้งานได้ดี หากคุณผ่านตัวเลือก 'รายงาน' ระบบจะแสดงรายการผู้ใช้ทั้งหมดที่ไม่มีการเข้าสู่ระบบที่เกี่ยวข้อง

EXEC sp_change_users_login 'report'

หากคุณต้องการเรียกใช้สำหรับฐานข้อมูลทั้งหมดของคุณคุณสามารถทำได้เช่นนี้

EXEC sp_msforeachdb 'use [?]; PRINT ''?''; EXEC sp_change_users_login ''report'';'

หากคุณค้นหาใน BOL คุณจะพบตัวเลือกสำหรับการแก้ไขผู้ใช้ "orphaned"

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.