我有一个 SQL Server 作业,其中包含一个运行 Windows 批处理脚本 (.bat) 的步骤。在批处理代码中有一行调用命令行指令使用 GnuPG 解密文件。
手动运行批处理文件(从 Windows GUI 双击)所有命令运行良好,包括解密指令。当批处理文件通过 Windows 任务计划程序使用编程任务运行时,我得到相同的结果。
通过SQL Server和SQL Server Agent运行批处理文件时,当遇到调用解密指令的行时会抛出错误。
该特定 SQL 作业步骤的日志文件包含以下输出:
Searching for host...
Connecting to host...
Authenticating...
Using username "[myusername]".
Authenticating with public key "[configured public key]".
Authenticated.
Starting the session...
Session started.
Active session: [1] [myusername]f@[sftpServerIP]
extract_CES_SAE_v3_[myusername]_[datestring].txt.pgp | 1 KB | 0.0 KB/s | binary | 100%
gpg: encrypted with RSA key, ID [RSAKeyIDNumber]
gpg: public key decryption failed: No secret key
gpg: decryption failed: No secret key
为安全起见对某些字段进行了编辑
在从 SQL Server 作业运行它时,我已经想不出如何让它工作了。
有没有其他人遇到过这样的事情并能够解决它?我在网上查看过这个问题,但似乎找不到任何从 SQL Server 中运行解密指令的实例,并且大多数记录有类似错误的案例都来自 Linux 环境而不是 Windows。
批处理脚本负责以下步骤:
就像我提到的,当批处理文件从 Windows GUI 或通过任务计划程序运行时,解密没有错误,但从 SQL Server 作业运行时抛出“无密钥”错误。
解密文件的脚本中有问题的行如下:
gpg --batch --yes --output C:\[AppDirectory]\automation\decrypted\extract_CES_SAE_v3_[myusername].txt --decrypt %LAST%
%LAST% 变量包含要解密的文件名,输出指示它存储解密文件的位置。通过命令提示符运行此特定行,指定文件名而不是变量,没有任何问题。使用存储在变量中的文件名从 Windows GUI 运行批处理文件没有问题,就像从任务计划程序运行它一样。
*** 编辑以包含 .BAT 代码 ***
@echo off
cd C:\[AppPath]\in\
if exist C:\[AppPath]\in\extract_CES_SAE_v3_[sftpUserName].txt (
cd C:\[AppPath]\automation\
echo -1 > C:\[AppPath]\automation\output.txt
powershell "C:\[AppPath]\automation\EmailProcessingError.ps1"
exit /b -1
)
cd C:\[AppPath]\automation\downloaded\
for /f %%i in ('dir "C:\[AppPath]\automation\downloaded\" /b/a-d/od/t:c') do set PGPFILE=%%i
echo ULTIMO ARCHIVO ANTES DE DESCARGA = %PGPFILE% > C:\[AppPath]\automation\log\automation_log.txt
"C:\Program Files (x86)\WinSCP\WinSCP.com" ^
/log="C:\[AppPath]\automation\log\WinSCP_.log" /ini=nul ^
/command ^
"open sftp://[sftpUserName]@[sftpIpAddress]/ -hostkey=""[hostKeyInfo]"" -privatekey=""C:\[KeyDirectory]\FTP\[PrivateKeyName].ppk"" -rawsettings AgentFwd=1" ^
"get -latest -filemask=*>1K /out/extract_CES* C:\[AppPath]\automation\downloaded\" ^
"exit"
set WINSCP_RESULT=%ERRORLEVEL%
for /f %%i in ('dir "C:\[AppPath]\automation\downloaded\" /b/a-d/od/t:c') do set LAST=%%i
echo ULTIMO ARCHIVO DESPUES DE DESCARGA = %LAST% >> C:\[AppPath]\automation\log\automation_log.txt
if %LAST%==%PGPFILE% (
cd C:\[AppPath]\automation\
echo 1 > C:\[AppPath]\automation\output.txt
powershell "C:\[AppPath]\automation\EmailNoNewFile.ps1"
exit /b 1
) else (
gpg --batch --yes --output C:\[AppPath]\automation\decrypted\extract_CES_SAE_v3_[sftpUserName].txt --decrypt %LAST%
)
cd C:\[AppPath]\automation\decrypted
if exist C:\[AppPath]\automation\decrypted\extract_CES_SAE_v3_[sftpUserName].txt (
copy /y C:\[AppPath]\automation\decrypted\extract_CES_SAE_v3_[sftpUserName].txt C:\[AppPath]\automation\decrypted\extract_CES_SAE_v3_[sftpUserName]_1.txt
) else (
echo ERROR EN DESENCRIPTACION DEL ARCHIVO >> C:\[AppPath]\automation\log\automation_log.txt
exit /b -1
)
rem copy /y C:\[AppPath]\automation\decrypted\extract_CES_SAE_v3_[sftpUserName].txt C:\[AppPath]\automation\decrypted\extract_CES_SAE_v3_[sftpUserName]_1.txt
set CUR_YYYY=%date:~10,4%
set CUR_MM=%date:~4,2%
set CUR_DD=%date:~7,2%
set CUR_HH=%time:~0,2%
if %CUR_HH% lss 10 (set CUR_HH=0%time:~1,1%)
set CUR_NN=%time:~3,2%
rename extract_CES_SAE_v3_[sftpUserName]_1.txt extract_CES_SAE_v3_[sftpUserName]_%CUR_YYYY%%CUR_MM%%CUR_DD%%CUR_HH%%CUR_NN%.txt
robocopy C:\[AppPath]\automation\decrypted\ C:\[AppPath]\in extract_CES_SAE_v3_[sftpUserName].txt
del C:\[AppPath]\automation\decrypted\extract_CES_SAE_v3_[sftpUserName].txt
powershell "C:\[AppPath]\automation\EmailNewFile.ps1"
echo 0 > C:\[AppPath]\automation\output.txt