引号/string如何在Powershell中工作?

我有一个命令行工作在常规的Windows命令行,但不知何故在Powershell(我是相当新的Powershell)误解。

sqlcmd -S .\SQLEXPRESS -i "f:\SQLBackups\ExpressMaint.sql" -v DB="ksuite" -v OPTYPE="DB" -v BACKUPFOLDER="f:\SQLBackups" -v REPORTFOLDER="f:\SQLBackups\Reports" -v DBRETAINUNIT="days" -v DBRETAINVAL="7" 

Powershell似乎是从需要path的参数中剥离驱动器号。 例如,当我尝试在Powershell中运行上述命令时,我得到以下内容:

 Sqlcmd: ':\SQLBackups': Invalid argument. Enter '-?' for help. 

那么确定它没有驱动器号是无效的。 我已经尝试过双引号,转义等等的变体,但不能得到它的工作。 我错过了什么Powershell做不同?

Jaykul的启动过程也是我如何做的。 SQLCMD在devise时考虑到了cmd.exe,因此在想要查看引号字符和Powershell使用它们的方式(或者不会更多地使用它们)之间存在一些冲突。

下面是你可以用来打电话,应该工作:

 sqlcmd -S .\SQLEXPRESS -i "`""f:\SQLBackups\ExpressMaint.sql`"" -v 'DB="ksuite"' -v 'OPTYPE="DB"' -v 'BACKUPFOLDER="`"'f:\SQLBackups'`"" -v 'REPORTFOLDER="`"'f:\SQLBackups\Reports'`"" -v 'DBRETAINUNIT="days"' -v 'DBRETAINVAL="7"' 

对于初学者来说,PowerShell假定所有参数都只是一个值或一个名称-name value对。 当你在价值的中间引号时,奇怪的事情发生…

在这种情况下,您可能只需要引用整个参数:

 sqlcmd -S .\SQLEXPRESS -i "f:\SQLBackups\ExpressMaint.sql" -v 'DB="ksuite"' -v 'OPTYPE="DB"' -v 'BACKUPFOLDER="f:\SQLBackups"' -v 'REPORTFOLDER="f:\SQLBackups\Reports"' -v 'DBRETAINUNIT="days"' -v 'DBRETAINVAL="7"' 

但是,我通常的build议是使用Start-Process,它将所有的参数都放在一个单独的string中,所以你可以这样做:

 Start-Process sqlcmd @" -S .\SQLEXPRESS -i "f:\SQLBackups\ExpressMaint.sql" -v DB="ksuite" -v OPTYPE="DB" -v BACKUPFOLDER="f:\SQLBackups" -v REPORTFOLDER="f:\SQLBackups\Reports" -v DBRETAINUNIT="days" -v DBRETAINVAL="7" "@ -RedirectStandardOutput f:\SQLBackups\CapturedOutput.log 

在最后一行的-RedirectStandardOutput f:\SQLBackups\CapturedOutput.log将只捕获标准输出到一个文件,以防万一你需要它…如果你需要logging错误输出,或需要提供input,你可以redirect也可以从/从文件。

我没有sqlcmd,所以我不能评论它是如何解释正在传递的参数,但是如果我使用的结构将parameter passing到一个batch file,只是回应调用cmd shell的命令( echo %cmdcmdline% )显示正在传递的参数如下所示:

 cmd /c ""C:\Users\Joe\sqlcmd.cmd" -S .\SQLEXPRESS -if:\SQLBackups\ExpressMaint.sql -v DB=ksuite -v OPTYPE=DB -v BACKUPFOLDER=f:\SQLBackups -v REPORTFOLDER=f:\SQLBackups\Reports -v DBRETAINUNIT=days -v DBRETAINVAL=7" 

Sqlcmd的parsing器可能不会像Powershell那样剥离引用一些参数,比如查询位置和DB =“ksuite”参数被严重改变的方式。

一种可能的方法是将整个文件用单引号括起来,以保留内部的双引号string,并希望sqlcmdparsing器能够处理这个问题:

 sqlcmd '-S .\SQLEXPRESS -i "f:\SQLBackups\ExpressMaint.sql" -v DB="ksuite" -v OPTYPE="DB" -v BACKUPFOLDER="f:\SQLBackups" -v REPORTFOLDER="f:\SQLBackups\Reports" -v DBRETAINUNIT="days" -v DBRETAINVAL="7"' 

这将提供未经修改的参数列表到sqlcmd,但它作为一个单一的参数,只要壳有关,我会感到惊讶,如果它的工作。 如果您有select地引用所有正在使用单引号修改的参数块,则更有可能获得成功,如下所示:

 sqlcmd.cmd -S .\SQLEXPRESS -i '"f:\SQLBackups\ExpressMaint.sql"' -v 'DB="ksuite"' -v 'OPTYPE="DB"' -v 'BACKUPFOLDER="f:\SQLBackups"' -v 'REPORTFOLDER="f:\SQLBackups\Reports"' -v 'DBRETAINUNIT="days"' -v 'DBRETAINVAL="7"' 

如果这仍然不起作用,则可能有其他项需要明确地转义,而不是通过在Powershellstring分析中使用用作转义字符的反引号字符在单引号和双引号之间切换来避免。

你可以从PowerShell中通过help about_quoting来获得关于引用和转义的所有方面的更多信息。