由于扩展了旧系统,我需要从旧 SSIS(另一台服务器)运行 SSIS2016 包。该包从 SQL 代理运行良好,但我无法使用 tsql 或 DTEXEC 运行它。问题是即使在提升的 cmd 中运行(在 sysadmin 下),包也无法访问网络
- 我能够从我正在运行包的帐户访问网络驱动器(管理员)
- 我知道该包在同一帐户下从 Sql 代理运行时运行良好。
- 当文件保存到本地临时文件夹(DTEXEC 和 TSQL)时,包运行良好
使用 SSMS、TSQL 或 DTEXEC 运行时,包无法将文件保存到网络。
DTEXEC /ISSERVER "\SSISDB\XXXX\Exports\package.dtsx" /SERVER "." /Par "$Package::FilePath(String)";"C:\TEMP"
从我在互联网上阅读的所有内容来看,似乎运行 SSIS2016 包的唯一方法是使用 SQL 代理和作业。
我对 DTEXEC 忽略执行命令行的帐户的安全上下文这一事实感到惊讶。有没有办法强制它使用代理帐户?
我很难相信,运行具有网络权限的包的唯一方法是使用 Sql 代理和作业。
谢谢你。ps 这是关于运行包的好文章,但它完全忽略了网络访问问题。
编辑 2019-06-10
我应用了 MSSQL2016 CU7 并重新启动了服务器。在这之后,
- 我能够使用在本地服务器上运行的 DTEXEC 命令将文件保存到网络(以系统管理员身份登录)
- 我能够使用从本地服务器运行的 sp 将文件保存到网络(以系统管理员身份登录)
- 在不同机器上以系统管理员身份登录时,我无法将文件保存到网络驱动器。错误是
平面文件目标未通过预执行阶段并返回错误代码 0xC020200E。
无法打开数据文件..
在应该保存文件的数据流中还有警告“访问被拒绝”。
存储过程源代码
DECLARE @execution_id BIGINT;
EXEC [SSISDB].[catalog].[create_execution]
@package_name = N'package.dtsx',
@execution_id = @execution_id OUTPUT,
@folder_name = N'XXXX',
@project_name = N'Exports',
@use32bitruntime = False,
@reference_id = NULL;
SELECT @execution_id;
DECLARE @var0 SQL_VARIANT = N'\\NETWORK\PATH\Export\test_files';
EXEC [SSISDB].[catalog].[set_execution_parameter_value]
@execution_id,
@object_type = 30,
@parameter_name = N'FilePath',
@parameter_value = @var0;
DECLARE @var1 SMALLINT = 1;
EXEC [SSISDB].[catalog].[set_execution_parameter_value]
@execution_id,
@object_type = 50,
@parameter_name = N'LOGGING_LEVEL',
@parameter_value = @var1;
EXEC [SSISDB].[catalog].[start_execution]
@execution_id;
我还添加了 System::UserName 以登录包的开始,我看到了正确的帐户。我认为,正如@Piotr 提到的那样,这个问题可能是双跳。我正在挖掘文件服务器日志以查看。
EDIT2 2019-06-10
好的。经过多次讨论,我可以将问题缩小到对 CIFS 执行用户权限的委派。
我做了什么
- 在开发计算机上设置共享
- 使用 scriptask 创建包,它尝试创建测试文件并获取调用用户 WindowsIdentity.GetCurrent().Name 的安全上下文
- 然后我在总是以拒绝访问结束的情况下使用上面的代码运行存储过程。
在我启用匿名访问(使用本文)之前,该包无法保存文件。
AFAIK 我们只启用了 MSSQLSvc kerberos 委派。
关闭:
问题是由 SSIS 目录的行为引起的,当从 TSQL 调用时,它会获取用户安全上下文,但为了正常工作,在访问网络共享时,您还需要为 CIFS 设置 Kerberos 委派。
我无法在我们的环境中执行此操作,因此我恢复为 xp_cmdshell。
感谢大家的支持。