【问题标题】:PowerShell script failing when run from SQL Agent从 SQL 代理运行时 PowerShell 脚本失败
【发布时间】:2020-09-17 02:24:54
【问题描述】:

我创建了一个执行以下操作的 PowerShell 脚本:

  1. 将模板 Excel 文件复制到另一个目录
  2. 使用 Doug Finke (https://www.powershellgallery.com/packages/ImportExcel/7.1.0) 创建的 ImportExcel 模块将数据导入此模板文件
  3. 运行包含在模板文件中的宏
  4. 将文件重命名为 .xlsx 文件类型

当我从服务器运行这个脚本时,它可以完美地执行并执行预期的操作。但是,当我尝试设置 SQL 代理作业来运行相同的 PS 脚本时,它失败了,我找不到这样做的原因。

这是我的 PS 脚本:

# Directory Information
$RootDirectory = "D:\MSSQL\SSIS\BIN Commission Report\"
$ArchiveFolder = "Archive\"
$SourceFolder = "Source\"
$TemplateFolder = "Template\"

# File Information
$TemplateFile = "Commission_Invoices_Template.xlsm" #Template file with macro
$MacroFile = "Commission_Invoices.xlsm" #Macro-enabled file with vendor data
$VendorFile = "Commission_Invoices.xlsx"  #File provided by the vendor
$DataImportFile = "Commission_Invoices_Import.xlsx" #File used to import data into SQL
$AppliedMacroFile = "Commission_Invoices_Import.xlsm"

#Full paths for each file
$TemplatePath = $RootDirectory, $TemplateFolder, $TemplateFile -Join ""
$MacroPath = $RootDirectory, $SourceFolder, $MacroFile -Join ""
$VendorPath = $RootDirectory, $SourceFolder, $VendorFile -Join ""
$DataImportPath = $RootDirectory, $SourceFolder, $DataImportFile -Join ""
$AppliedMacroPath = $RootDirectory, $SourceFolder, $AppliedMacroFile -Join ""

If ( Test-Path $MacroPath ) { Remove-Item $MacroPath }
If ( Test-Path $AppliedMacroPath ) { Remove-Item $AppliedMacroPath }

#Copy template file to use for date insertion and macro
Copy-Item $TemplatePath -Destination $MacroPath

# Copy data from vendor spreadsheet into macro-enabled workbook
Import-Excel -Path $VendorPath -WorksheetName Sheet1 | Export-Excel $MacroPath -WorksheetName Commission_Invoice

# Run the macro in Excel
$MacroName = "CommissionPrep"

$Excel = New-Object -ComObject Excel.Application
$Excel.Visible = $false
$WB = $Excel.Workbooks.Add($MacroPath)
$Excel.Run($MacroName)

#Close Excel
$WB.Close($false)
$Excel.Quit()

[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()

[System.Runtime.Interopservices.Marshal]::ReleaseComObject($WB)
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($Excel)

Remove-Variable -Name Excel

# Copy data to xlsx file from xlsm for data import into SQL
Import-Excel -Path $AppliedMacroPath -WorksheetName Commission_Invoice | Export-Excel $DataImportPath -WorksheetName Commission_Invoice -AutoSize

If ( Test-Path $MacroPath ) { Remove-Item $MacroPath }
If ( Test-Path $VendorPath ) { Remove-Item $VendorPath }
If ( Test-Path $AppliedMacroPath ) { Remove-Item $AppliedMacroPath }

这就是我的 SQL 代理工作的样子:

C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -File "D:\MSSQL\SSIS\BIN Commission Report\Scripts\CommissionInvoices_PS.ps1"

以下是作为 SQL 代理作业运行时的错误消息:

Message
Executed as user: CompanyX\CompanyXSQLADMIN. 
Microsoft Excel cannot access the file 'D:\MSSQL\SSIS\BIN Commission Report\Source\Commission_Invoices.xlsm'. 
There are several possible reasons:  
 The file name or path does not exist.  
 The file is being used by another program.  
 The workbook you are trying to save has the same name as a currently open workbook.  

At D:\MSSQL\SSIS\BIN Commission Report\Scripts\CommissionInvoices_PS.ps1:35 char:1  + $WB = $Excel.Workbooks.Add($MacroPath)  + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : OperationStopped: (:) [], COMException + FullyQualifiedErrorId : System.Runtime.InteropServices.COMExceptionException calling "Run" with "1" argument(s): "Cannot run the macro 'CommissionPrep'. The macro may not be available in this workbook or all macros may be disabled."  

At D:\MSSQL\SSIS\BIN Commission Report\Scripts\CommissionInvoices_PS.ps1:36 char:1 + $Excel.Run($MacroName) + ~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : COMException

You cannot call a method on a null-valued expression.

At D:\MSSQL\SSIS\BIN Commission Report\Scripts\CommissionInvoices_PS.ps1:39 char:1 + $WB.Close($false)  + ~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (:) [], RuntimeException + FullyQualifiedErrorId : InvokeMethodOnNullException calling "ReleaseComObject" with "1" argument(s): "Object reference not set to an instance of an object."

At D:\MSSQL\SSIS\BIN Commission Report\Scripts\CommissionInvoices_PS.ps1:45 char:1 + [System.Runtime.Interopservices.Marshal]::ReleaseComObject($WB) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : NullReferenceException 0 'D:\MSSQL\SSIS\BIN Commission Report\Source\Commission_Invoices_Import.xlsm' file not found  

At C:\Program Files\WindowsPowerShell\Modules\ImportExcel\7.0.1\Public\Import-Excel.ps1:105 char:17 + throw "'$($Path)' file not found" + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : OperationStopped: ('D:\MSSQL\SSIS\... file not found:String) [], RuntimeException + FullyQualifiedErrorId : 'D:\MSSQL\SSIS\BIN Commission Report\Source\Commission_Invoices_Import.xlsm' file not found. Process Exit Code 1.  The step failed.

我不清楚当在服务器上本地运行时从 PowerShell ISE shell 运行时此脚本如何完美执行,但通过 SQL 代理作业运行失败。有关如何解决此问题的任何建议?

【问题讨论】:

  • SQL Server 代理服务帐户是否有权访问这些目录?错误提示不是。
  • 是的,我让服务帐户完全控制父目录并应用到所有子目录,但我仍然收到此错误消息。
  • 以代理的用户帐户启动一个 shell 并尝试手动运行脚本。

标签: sql powershell sql-server-2016


【解决方案1】:

您是否尝试为您的 SQL 代理作业设置执行策略:

C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -executionpolicy bypass -File "D:\MSSQL\SSIS\BIN Commission Report\Scripts\CommissionInvoices_PS.ps1"

【讨论】:

  • 我刚刚添加了带有绕过执行策略的额外代码,但不幸的是它仍然失败并显示相同的错误消息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-06-05
  • 1970-01-01
  • 2020-03-22
  • 1970-01-01
  • 2020-07-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多