AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 271387
Accepted
Saravana Kumar
Saravana Kumar
Asked: 2020-07-22 14:26:42 +0800 CST2020-07-22 14:26:42 +0800 CST 2020-07-22 14:26:42 +0800 CST

生成脚本以删除或映射 SQL Server 实例中的孤立用户

  • 772

我对 SQL Server 很陌生。我有一个脚本可以在所有数据库中找到孤立用户并生成脚本以删除或映射用户以正确登录(如果可用)。

由于我想在大量服务器上运行脚本,我想到了使用 PowerShell 来帮助我。但我现在有两个问题:

  1. 脚本错误
  2. Power-shell 执行错误

问题 1:以下脚本本身返回输出,但仍然显示一些错误。我试图调试,但我无法这样做。

DECLARE @orphan_users TABLE (
    Server NVARCHAR(MAX),
    DBName sysname,
    [user_name] sysname,
    type_desc nvarchar(60),
    default_schema_name sysname NULL,
    create_date datetime,
    modify_date DATETIME,
    [sid] VARBINARY(85),
    cr_type int
); 

INSERT INTO @orphan_users (Server,
    DBname,
    [user_name],
    type_desc,
    default_schema_name,
    create_date,
    modify_date,
    [sid],
    cr_type
) 
EXEC sp_msforeachdb 
'use [?] 
SELECT 
    @@SERVERNAME 
    ,DB_NAME() DBname 
    ,name 
    ,type_desc 
    ,default_schema_name 
    ,create_date 
    ,modify_date 
    ,[sid] 
    ,Datalength(sid) AA 
from sys.database_principals 
where type in (''S'') 
and [sid] not in ( select [sid] from sys.server_principals where type in (''G'',''S'',''U'') ) 
and name not in (''dbo'',''guest'',''INFORMATION_SCHEMA'',''sys'' ,''MS_DataCollectorInternalUser'')'; 

DECLARE @db_users TABLE (
    [LogInAtServerLevel] NVARCHAR(MAX),
    [UserAtDBLevel] NVARCHAR(MAX), 
    DBname sysname
); 

INSERT INTO @db_users ([LogInAtServerLevel], [UserAtDBLevel],DBname) 
EXEC sp_msforeachdb 
'use [?] 
SELECT 
    susers.[name],
    users.[name],
    DB_NAME() DBname               
from sys.database_principals users 
inner join sys.database_role_members link 
   on link.member_principal_id = users.principal_id 
inner join sys.database_principals roles 
   on roles.principal_id = link.role_principal_id 
inner join sys.server_principals susers 
   on susers.sid = users.sid'; 

SELECT 
    a.Server,
    a.DBName,
    a.user_name,
    b.name,cr_type,
    c.UserAtDBLevel, 
    CASE 
        WHEN (b.name IS NULL) and (cr_type > 17) 
            THEN 'USE ' + QUOTENAME(a.DBname) + '; DROP USER ' + QUOTENAME(a.user_name) + ';' 
        WHEN (b.name IS not NULL) and (cr_type < 17) and (c.UserAtDBLevel is null) 
            THEN 'USE ' + QUOTENAME(a.DBname) + '; ALTER USER ' + QUOTENAME(a.user_name) + ' WITH LOGIN = ' + QUOTENAME(b.name)+';' 
        WHEN (b.name IS not NULL) and (cr_type < 17) and (c.UserAtDBLevel is not null) 
            THEN 'USE ' + QUOTENAME(a.DBname) + '; DROP USER ' + QUOTENAME(a.user_name) + ';' 
        WHEN (b.name IS NULL) 
            THEN 'USE ' + QUOTENAME(a.DBname) + '; DROP USER ' + QUOTENAME(a.user_name) + ';' 
        WHEN (b.name IS not NULL) and (cr_type > 17) 
            THEN 'USE ' + QUOTENAME(a.DBname) + '; DROP USER ' + QUOTENAME(a.user_name) + ';' 
    END as [remediation] 
FROM ((@orphan_users a 
    left join sys.server_principals b on a.user_name = b.name)  
    left join @db_users c on c.DBname=a.DBName and c.LogInAtServerLevel=b.name) 
ORDER BY a.user_name; 

结果是

在此处输入图像描述

但是由于该错误,实例中的所有数据库都会出现类似的错误

“tempdbfrom”附近的语法不正确。消息 102,级别 15,状态 1,第 3 行
“modelfrom”附近的语法不正确。消息 102,级别 15,状态 1,第 3 行
“msdbfrom”附近的语法不正确。消息 102,级别 15,状态 1,第 3 行
'dbamonfrom' 附近的语法不正确。消息 102,第 15 级,状态 1,第 3 行

问题 2:由于脚本是准确的(至少在我的环境中),所以我尝试使用 power-shell 运行它,如下所示。它只返回错误,没有输出

Invoke-SqlCmd `
    -InputFile "D:\temp\up.sql" `
    -ServerInstance 'abc\sql2012' `
    -IncludeSqlUserErrors

我已经尝试了使用 > 重定向输出的所有方法来启动和停止转录。他们似乎都没有捕捉到查询给出的结果,但是错误被准确捕捉到了..

如果任何一个问题得到解决,这对我来说将是一个很大的帮助。

sql-server powershell
  • 3 3 个回答
  • 358 Views

3 个回答

  • Voted
  1. alroc
    2020-07-22T19:13:35+08:002020-07-22T19:13:35+08:00

    该dbatools模块已经为您解决了这个问题。

    • Get-DbaDbOrphanUser- 报告一个或多个数据库中没有相应登录的所有用户
    • Repair-DbaDbOrphanUser- 查找孤儿用户,如果有同名登录,它将重新映射他们。
    • Remove-DbaDbOrphanUser- 定位孤立用户并将其从数据库中删除(您也可以这样做Repair-DbaDbOrphanUser -RemoveNotExisting)。
    • 6
  2. Best Answer
    Yunus UYANIK
    2020-07-22T15:23:06+08:002020-07-22T15:23:06+08:00

    可能你的编辑有问题,或者我不知道到底是什么问题。但是我清除了所有空白msforeachdb并运行它,因此错误消失了。

    DECLARE @orphan_users TABLE (
      Server nvarchar(max),
      DBName sysname,
      [user_name] sysname,
      type_desc nvarchar(60),
      default_schema_name sysname NULL,
      create_date datetime,
      modify_date datetime,
      [sid] varbinary(85),
      cr_type int
    );
    
    INSERT INTO @orphan_users (Server, DBname, [user_name], type_desc, default_schema_name, create_date, modify_date, [sid], cr_type)
    
    EXEC sp_MSforeachdb '
    USE [?]
    SELECT 
    @@SERVERNAME 
    ,DB_NAME() DBname 
    ,name 
    ,type_desc 
    ,default_schema_name 
    ,create_date 
    ,modify_date 
    ,[sid] 
    ,Datalength(sid) AA 
    from sys.database_principals where type in (''S'') 
    and [sid] not in ( select [sid] from sys.server_principals where type in (''G'',''S'',''U'') ) 
    and name not in (''dbo'',''guest'',''INFORMATION_SCHEMA'',''sys'' ,''MS_DataCollectorInternalUser'')';
    
    DECLARE @db_users TABLE (
      [LogInAtServerLevel] nvarchar(max),
      [UserAtDBLevel] nvarchar(max),
      DBname sysname
    );
    
    INSERT INTO @db_users ([LogInAtServerLevel], [UserAtDBLevel], DBname)
    
    EXEC sp_MSforeachdb '
    USE [?]
    SELECT susers.[name],users.[name],DB_NAME() AS DBNAME
    from sys.database_principals users 
    inner join sys.database_role_members link 
    on link.member_principal_id = users.principal_id 
    inner join sys.database_principals roles 
    on roles.principal_id = link.role_principal_id 
    inner join sys.server_principals susers 
    on susers.sid = users.sid';
    
    SELECT
      a.Server,
      a.DBName,
      a.user_name,
      b.name,
      cr_type,
      c.UserAtDBLevel,
    
      CASE
        WHEN (b.name IS NULL) AND
          (cr_type > 17) THEN 'USE ' + QUOTENAME(a.DBname) + '; DROP USER ' + QUOTENAME(a.user_name) + ';'
    
        WHEN (b.name IS NOT NULL) AND
          (cr_type < 17) AND
          (c.UserAtDBLevel IS NULL) THEN 'USE ' + QUOTENAME(a.DBname) + '; ALTER USER ' + QUOTENAME(a.user_name) + ' WITH LOGIN = ' + QUOTENAME(b.name) + ';'
    
        WHEN (b.name IS NOT NULL) AND
          (cr_type < 17) AND
          (c.UserAtDBLevel IS NOT NULL) THEN 'USE ' + QUOTENAME(a.DBname) + '; DROP USER ' + QUOTENAME(a.user_name) + ';'
    
        WHEN (b.name IS NULL) THEN 'USE ' + QUOTENAME(a.DBname) + '; DROP USER ' + QUOTENAME(a.user_name) + ';'
    
        WHEN (b.name IS NOT NULL) AND
          (cr_type > 17) THEN 'USE ' + QUOTENAME(a.DBname) + '; DROP USER ' + QUOTENAME(a.user_name) + ';'
      END AS [remediation]
    
    FROM ((@orphan_users a
    
    LEFT JOIN sys.server_principals b
      ON a.user_name = b.name)
    
    LEFT JOIN @db_users c
      ON c.DBname = a.DBName
      AND c.LogInAtServerLevel = b.name)
    
    ORDER BY a.user_name;
    
    • 1
  3. Ronaldo
    2020-07-22T15:38:07+08:002020-07-22T15:38:07+08:00

    您是否考虑过 SQL Server 接受使用没有登录的用户,虽然它看起来像一个孤立的用户,但它可以被设计成这样?

    创建用户文档说:

    WITHOUT LOGIN 子句创建未映射到 SQL Server 登录的用户。它可以以访客身份连接到其他数据库。可以将权限分配给该未登录用户,并且当安全上下文更改为未登录用户时,原始用户将获得未登录用户的权限。参见示例D。创建和使用没有登录的用户。

    因此,在自动化该任务时要小心,因为如果您不熟悉正在使用的数据库,您可能会破坏某些东西。

    • 0

相关问题

  • SQL Server - 使用聚集索引时如何存储数据页

  • 我需要为每种类型的查询使用单独的索引,还是一个多列索引可以工作?

  • 什么时候应该使用唯一约束而不是唯一索引?

  • 死锁的主要原因是什么,可以预防吗?

  • 如何确定是否需要或需要索引

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve