我的脚本运行外部命令没有任何问题:
$Target= "X:\Backup 2017-12-27.7z"
Write-Host "Compressing as $Target..."
& "C:\Program Files\7-Zip\7z.exe" a "$Target" @C:\Webs\Scripts\include.txt -w
但是当我添加更多开关时它完全打破了:
$Target= "X:\Backup 2017-12-27.7z"
Write-Host "Compressing as $Target..."
& "C:\Program Files\7-Zip\7z.exe" a "$Target" -spf -i@C:\Webs\Scripts\include.txt -x@C:\Webs\Scripts\exclude.txt -w
7z.exe : ERROR: X:\Backup 2017-12-27.7z At C:\Webs\Scripts\backup.ps1:50 char:1 + & "C:\Program Files\7-Zip\7z.exe" a "$Target" -spf -i@C:\Webs\Scripts\include.t ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (ERROR: X:\Backup 2017-12-27.7z:String) [], RemoteException + FullyQualifiedErrorId : NativeCommandError X:\Backup 2017-12-27.7z Open ERROR: Can not open the file as [7z] archive ERRORS: Headers Error System ERROR: Incorrect function.
该命令从cmd
运行良好。我打破了什么PowerShell语法以及如何解决它?
有时,PowerShell的参数解析会干扰您要传递给外部程序的参数。这就是为什么你要确保PowerShell将这些参数视为字符串而不是它应该自己处理的参数。你可以通过在整个参数周围加上引号来做到这一点:
$program = 'C:\path\to\your.exe'
& $program '-a' '-b:foo'
和/或将参数放在变量中:
$program = 'C:\path\to\your.exe'
$param1 = '-a'
$param2 = '-b:foo'
& $program $param1 $param2
更好的方法是收集数组中的所有参数,并将splat数组收集到程序中:
$program = 'C:\path\to\your.exe'
$params = '-a', '-b:foo'
& $program @params
从PowerShell v3开始,您还可以使用“魔术参数”(--%
)来阻止PowerShell解析参数:
$program = 'C:\path\to\your.exe'
& $program --% -a -b:foo
但请注意,PowerShell不会评估--%
的任何内容,这意味着所有内容(包括变量)都将作为文字传递。
$program = 'C:\path\to\your.exe'
& $program --% $foo
在上面的代码片段中,程序将使用文字字符串'$foo'
而不是变量$foo
的值来调用。
有关从PowerShell see here运行外部命令的更多信息。
问题是由$Target
的空间引起的。根据其他开关的存在,我不知道为什么这是一个问题。正如@TimTharratt指出的那样,将文本移动到变量的解决方法对我来说很有用。注入的变量甚至不需要引用:
$Target= "X:\Backup 2017-12-27.7z"
Write-Host "Compressing as $Target..."
$Include = "-i@C:\Webs\Scripts\include.txt"
$Exclude = "-x@C:\Webs\Scripts\exclude.txt"
& "C:\Program Files\7-Zip\7z.exe" a $Target -spf $Include $Exclude -w
我很乐意接受提供正确修复的任何答案或(如果没有完整的CS专业甚至可能)解释PowerShell关于空格的语法。与此同时,这是一个完成任务的黑客。