我在 SQL Server Agent 作业步骤中使用 PowerShell 自动将 .ZIP 文件内容提取到目录中。
根据该问题得票最高的答案:如何在 Powershell 中压缩/解压缩文件?
我正在使用这个代码:
$dir_source = "\\myserver\myshare\"
$dir_destination = "\\myserver2\myshare2\"
$file_source = Get-ChildItem -Path (Join-Path -Path $dir_source -ChildPath "test.zip")
$shell_app = New-Object -com shell.application
$zip_file = $shell_app.namespace($file_source.FullName)
$destination = $shell_app.namespace($dir_destination)
$destination.Copyhere($zip_file.items(),20)
CopyHere 方法的 vOptions 可选参数为 20,指定“不显示进度对话框。”(4)和“对显示的任何对话框都回答‘全部是’。”(16)。
此参数在 PowerShell 脚本编辑器中按预期工作(我使用的是 PowerGUI 脚本编辑器)。我可以运行该脚本,然后再次运行它(覆盖方案),并且脚本完成时没有错误,也没有对话框。但是,在 SQL Server Agent PowerShell 作业步骤中执行相同的代码会导致作业挂起,因为文件已存在于目标数据库中。
重现步骤:
- Instantiate code in a SQL Server 2008 SQL Server Agent Job step
- Start the SQL job
- Result: SQL job completes, unzipped file "test.csv" appears in the $dir_destination folder
- Start the SQL job
- Result: Job executes indefinitely.
- Stop the SQL job
- Delete the "test.csv" from the $dir_destination folder
- Start the SQL job
- Result: SQL job completes, unzipped file "test.csv" appears in the $dir_destination folder
为什么 vOption 参数对 SQL Job 不起作用?
...请注意,每个 shell 文件夹都由 shell 命名空间扩展(简称 NSE)支持。每个 NSE 都会选择自己的机制来复制/移动/删除数据项(对于普通文件系统路径,为文件/文件夹)。
您引用的有关 CopyHere 方法的文档仅适用于普通文件系统路径。这就是为什么您使用选项 4 禁用进度对话框对 zip 文件夹不起作用的原因。
另一方面,上次我与 shell 团队核实时,目前 zip 文件 NSE 的功能仅用于用户交互。
换句话说,以编程方式访问 zip 文件 NSE 不受官方支持。”
答案1
我想知道这是否与 SQL Agent 中 Powershell 作业步骤的内部有关。例如,您无法在 SQL Agent 中的 powershell 作业步骤中执行 write-host,如本博客文章中所述:http://blogs.msdn.com/b/mwories/archive/2009/09/30/the-use-of-write-host-and-sql-server-agent-powershell-job-steps.aspx
一个建议——尝试设置 CmdExec 作业步骤并使用 -file 参数调用 C:\windows\System32\WindowsPowerShell\v1.0\powershell.exe,而不是使用 powershell 作业步骤。这样它将使用 cmdexec 而不是 sqlps。
答案2
您需要传递标志
(16)
Respond with "Yes to All" for any dialog box that is displayed.
就像这样:
$destination.Copyhere($zip_file.items(), 16)
您可能希望将其与此标志结合起来:
(4)
Do not display a progress dialog box.
因此你会这样做:
$destination.Copyhere($zip_file.items(), 20)