Invoke-Expression参数使用SqlCmd进行splatting

时间:2015-07-27 20:59:32

标签: powershell powershell-v3.0 sqlcmd

假设:

$args = @()
$args += '-E'
$args += "-S 'SERVER'"
$args += "-d 'DATABASE'"
$args += "-Q 'SELECT GetDate() NOW'"

Invoke-Expression "sqlcmd $($args -join ' ')"产生:

NOW
-----------------------
2015-07-27 16:48:26.387

(1 rows affected)

我的尝试' splatting'失败。

  

Invoke-Expression "sqlcmd" @argsInvoke-Expression 'sqlcmd' @args以及Invoke-Expression sqlcmd @args生成:

`Error: 7/27/2015 4:53:00 PM:
At C:\Users\...\default.ps1:34 char:3 +   Invoke-Expression "sqlcmd" @args +   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~ [<<==>>]
     

异常:找不到接受的位置参数   争论&#39; -E&#39;。

& sqlcmd @args& 'sqlcmd' @args生成:

Sqlcmd: '-S 'SERVER'': Unexpected argument. Enter '-?' for help.

正确的splatting语法是什么?

**编辑**

类似模式(来源 - Differential backups using 7-zip and PowerShell):

$args = @()
$args += 'a'
$args += "-tZIP"
$args += 'C:\Users\x\Desktop\archive.zip'
$args += 'C:\Users\x\Desktop\a.txt'

& '7z' @args

结果:

7-Zip [64] 9.38 beta  Copyright (c) 1999-2014 Igor Pavlov  2015-01-03

Scanning

Updating archive C:\Users\x\Desktop\archive.zip

Compressing  a.txt

Everything is Ok

Kernel  Time =     0.031 =   63%
User    Time =     0.000 =    0%
Process Time =     0.031 =   63%    Virtual  Memory =      9 MB
Global  Time =     0.049 =  100%    Physical Memory =      6 MB

有什么区别?

2 个答案:

答案 0 :(得分:1)

Splatting适用于powershell函数和CmdLets。 SqlCmd不支持。 您可以为SqlCmd编写一个包装器并让它以这种方式工作。请参阅以下示例。

function SqlCmdWithSplatting
{
param
(
    [string]$server,
    [string]$database,
    [string]$query
)
sqlcmd -E -S $server -d $database -Q $query
}

# Now call that with splatting

$myargs = @{Server="(localdb)\ProjectsV12";database="John";Query="select * from Table1"}

SqlCmdWithSplatting @myargs

    Id         
-----------
          1
          2
          3

答案 1 :(得分:0)

首先:我会避免为$args提供值,这是为脚本参数保留的Powershell automatic variable

第二次:这是我用来做的方式:

$scriptblock = {fullpath\sqlcmd -S `"(local)\instance1`" <# comment option -S #>`
                                -U a `
                                -P a `
                                -i `"c:\temp\sql.sql`" }
Invoke-Command -ScriptBlock $scriptBlock

然后,您可以在脚本块中使用$args变量,甚至可以远程启动它。

$scriptblock = {fullpath\sqlcmd -S `"(local)\instance1`" <# comment option -S #>`
                                -U a `
                                -P a `
                                -i `"$($args[0])`" }
Invoke-Command -ScriptBlock $scriptBlock -argumentList "c:\temp\sql.sql" -computer "remote1"

备注:每个选项一行允许对每个参数进行注释,但是当它们位于行尾时,请注意不要忘记“`”并且不要忘记它们。