【发布时间】:2020-09-17 02:24:54
【问题描述】:
我创建了一个执行以下操作的 PowerShell 脚本:
- 将模板 Excel 文件复制到另一个目录
- 使用 Doug Finke (https://www.powershellgallery.com/packages/ImportExcel/7.1.0) 创建的 ImportExcel 模块将数据导入此模板文件
- 运行包含在模板文件中的宏
- 将文件重命名为 .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