如何在工作组环境中为 MS SQL Server 创建 Windows 服务帐户?

Posted

技术标签:

【中文标题】如何在工作组环境中为 MS SQL Server 创建 Windows 服务帐户?【英文标题】:How to create a Windows service account for MS SQL Server in a workgroup environment? 【发布时间】:2016-11-28 06:51:43 【问题描述】:

我在一个工作组中有两台 Windows Server 2012 R2 服务器,第一台我有 MS SQL Server,另一台(除其他外)用作备份存储。在数据库服务器上,SQL Server 数据库引擎和 SQL Server 代理都使用默认虚拟帐户运行 - NT Service\MSSQLSERVER 和 NT Service\SQLSERVERAGENT。

现在,我想使用 Ola Hallengren 维护作业来备份我的 MS SQL Server 数据库。这些脚本被包装到 SQL Server 代理作业中,但备份是一个 t-sql 过程,因此由 SQL Server 数据库引擎使用 NT Service\MSSQLSERVER 执行。

我在存储服务器上创建了一个帐户,并为此帐户创建了一个具有访问权限的共享文件夹。我可以使用为创建的帐户提供凭据的 net use 命令连接数据库服务器上的共享。 有一个问题:共享是为运行 net use 命令的帐户连接的。

如果我将共享与本地系统帐户(应该适用于所有用户)连接,那么 NT Service\MSSQLSERVER 仍然无法访问它,任何其他帐户都不能。似乎hack previously proposed on *** 在 Windows Server 2012 R2 中已修复。

如果我在 SQL Server 代理作业中将 net use 命令作为一个步骤运行,那么它会使用另一个虚拟帐户 - NT Service\SQLSERVERAGENT - 并且备份步骤失败并出现“找不到文件夹”错误。

所以我想知道一种使用all the necessary permissions 创建 Windows 服务帐户的方法,以便在工作组环境中使用 SQL Server 数据库引擎服务。或者解释为什么它不能完成。 理想情况下,它应该是一个脚本 - Powershell 或 VBScript。

我尝试将 SQL Server Dabase Engine 和 SQL Server Agent 作为本地系统运行,并且备份的效果非常好。但我不认为这是一种解决方案,因为从安全角度来看不建议这样做。

由于同样的安全原因,我也不会考虑使用xp_cmdshell 运行 net use 命令的解决方案。

【问题讨论】:

您如何访问共享,您使用的路径是什么?您映射了驱动器还是使用了 UNC 路径? @DavidG,我使用 UNC 路径,像这样:net use \\remotehost\folder password /user:remotehost\username 问题是这仅对当前登录的用户有效,您需要以运行 SQL 的同一用户身份登录。 是的,这就是目标。我需要一个脚本来在工作组中创建这样的帐户,以便该帐户能够运行 MS SQL Server 并连接网络共享文件夹。或者某种手册,如果不是脚本的话。 【参考方案1】:

好的,完成它的正确方法是执行以下操作:

在两台服务器上创建一个名称完全相同的用户帐户。如果用户名为.\UserName 而不是ServerName\UserName,则可以这样做。 完成后,您需要嗅探虚拟服务帐户NT Service\MSSQLSERVER 的权限。这可以通过使用 SubInACL 实用程序来完成。此工具由 Microsoft 专门为此目的创建,可从官方 Microsoft 下载中心下载。或者,您可以跳过嗅探实际权限并继续下一点。 知识库文章https://msdn.microsoft.com/en-us/library/ms143504.aspx 中描述的所有权限都可以使用相同的SubInACL 工具为新创建的帐户设置到位。网上有几篇关于如何使用该工具的文章,我用过这一篇-https://redmondmag.com/articles/2008/03/01/dive-deep-with-subinacl.aspx 最后一步是:在新创建的用户帐户下启动 SQL Server 服务,并提供对另一台服务器上共享文件夹的访问权限。

这应该去superuser.com

【讨论】:

【参考方案2】:

是否可以使用 SSIS 包来执行以下操作:

    使用登录详细信息等通过 tsql 创建和编写脚本。并将其导出到磁盘上的脚本文件。 运行运行脚本。 再次删除脚本文件。

示例: https://www.simple-talk.com/sql/ssis/adding-the-script-task-to-your-ssis-packages/

使用 T-sql 创建批处理文件:

--Set first day of Week to Monday
--Value First day of the week is 
--1 Monday 
--2 Tuesday 
--3 Wednesday 
--4 Thursday 
--5 Friday 
--6 Saturday 
--7 (default, U.S. English) Sunday 
SET DATEFIRST 1

Declare @CmdSource varchar(100),
    @CmdDestination varchar(100),
    @Year varchar(4),
    @Week varchar (2),
    @Difference int

Set @Difference = 0
Set @Year = Convert(varchar(4), DatePart(Year, GetDate()-@Difference))
Set @Week = Convert(varchar(2), DatePart(week, GetDate()-@Difference))
If @Year = '2010'
BEGIN
    Set @Week = @Week - 1
END

SELECT @Week = 
        CASE Len(@Week)
            WHEN 1
            THEN '0' + @Week
            else @Week
        END

Set @CmdSource = 'XCopy "<sourcepath>' + @Year + '\extras text' + @Year + @Week + '.bak" '
Set @CmdDestination = '"<Destination path>" /Y'

SELECT @CmdSource + @CmdDestination as Batchfile

我们选择在设定的时间创建文件。然后,我们设置一个单独的 windows 计划任务,在创建后的设定时间独立于 SQL 运行。在 2010 年与 SSIS 一起运行是不可预测的。只有一个很长的目标列(长度为 200,由您决定。)

【讨论】:

您能否详细说明“使用登录详细信息通过 tsql 创建和编写脚本”。我可以使用 C#/VB.net 脚本创建一个 SSIS 包。这里没问题。但我不确定我是否理解其中的代码应该是什么。你的回答似乎更像是一个问题而不是一个答案。 我们过去做过类似的事情。我还在寻找它。将通过示例和步骤回复您 更新了答案以包含更详细的步骤和图像。希望有帮助 什么?!这如何回答我的问题?这完全是题外话。 这是一个建议。使用 if 作为解决方案的一部分。将其备份到它所在的一个副本上。下一步做什么。这是解决方案中的一些步骤,而不是解决方案。我不需要解释。【参考方案3】:

恕我直言,您最好的选择仍然是在 xp_cmdshell 中运行 net use \\remotehost\folder password /user:remotehost\username

只需要运行一次,如果不喜欢可以再次关闭xp_cmdshell;这不像更改该选项需要重新启动 =)

为此,我建议将其放入“启动”程序中。如果您担心有人会 sp_helptext 它来查找该登录名的密码,您甚至可以添加 WITH RECOMPILE。再说一次,人们在找到加密的启动过程时可能会吓坏=)

USE master
GO
CREATE PROCEDURE sp_net_use_that_other_server
AS

-- To allow advanced options to be changed.  
EXEC sp_configure 'show advanced options', 1;  

-- To update the currently configured value for advanced options.  
RECONFIGURE;  

-- To enable the feature.  
EXEC sp_configure 'xp_cmdshell', 1;  

-- To update the currently configured value for this feature.  
RECONFIGURE;  

-- you might want to fetch this dynamically from the database somewhere, or simply leave it hardcoded here...

EXEC master..xp_cmdshell 'net use \\remotehost\folder password /user:remotehost\username'

-- To disable the feature.  
EXEC sp_configure 'xp_cmdshell', 0;  

-- To update the currently configured value for this feature.  
RECONFIGURE;  


Return
GO

-- set this up as a startup procedure
EXEC sp_procoption @ProcName = 'sp_net_use_that_other_server'   
                 , @OptionName =  'startup'   
                 , @OptionValue = 'on';  

GO

之后,数据库引擎应该能够BACKUP DATABASE... 到该共享。

【讨论】:

使用 xp_cmdshell 存在安全风险,一般不推荐。请查看此链接blogs.msdn.microsoft.com/sqlsecurity/2008/01/10/xp_cmdshell 因此我建议在您不再需要它之后再次“关闭那个洞”;您只需要它在启动服务时创建共享。

以上是关于如何在工作组环境中为 MS SQL Server 创建 Windows 服务帐户?的主要内容,如果未能解决你的问题,请参考以下文章

[MS SQL Server]SQL Server如何开启远程访问

如何在 Sql Alchemy Python 中为 MS SQL 后端指定事务隔离级别

如何在 php 中为 tsql 字符串转义单引号(ms sql)

在 SQL Server 中为关键数据库还原数据库的最佳方法

带有管理工作室的 MS SQL Server - 如何使用其数据(作为插入语句)编写表的脚本? [复制]

如何使 MS Access 直通查询在 SQL Server 中正确运行