在Jenkins powershell脚本中转​​义空间并解析变量不起作用

时间:2018-07-31 12:16:00

标签: powershell jenkins jenkins-pipeline

我尝试了不同的方法来转义“程序文件”中的空间,但这不起作用。执行此部分后,我在Jenkins中收到以下错误:

  

powershell.exe:要求FileStream打开不是文件的设备。要支持“ com1:”或“ lpt1:”等设备,请致电   C:\ web \ JenkinsMaster \ workspace \ XXX @ tmp \ durable-d3011838 \ powershellWrapper.ps1:5   字符数:3   +&powershell -NoProfile -NonInteractive -ExecutionPolicy Bypass -Fi ...   + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~   + CategoryInfo:未指定:(FileStream是...'lpt1:',调用:String)[],RemoteException   + FullyQualifiedErrorId:NativeCommandError CreateFile,然后使用将OS句柄作为IntPtr的FileStream构造函数。

     
      
  • CategoryInfo:OpenError:(:) [Out-File],NotSupportedException

  •   
  • FullyQualifiedErrorId:FileOpenFailure,Microsoft.PowerShell.Commands.OutFileCommand

  •   
  • PSComputerName:XXXXX

  •   
powershell script: '''
$pass = ConvertTo-SecureString -AsPlainText "XXXX" -Force
$cred = New-Object System.Management.Automation.PSCredential -ArgumentList "XXXX",$pass
$sessionOption = New-PSSessionOption -SkipCACheck -SkipCNCheck -SkipRevocationCheck
$session = New-PSSession -ComputerName XXXXXXXX -UseSSL -Credential $cred -SessionOption $sessionOption
Copy-Item $env:WORKSPACE\\* -Destination "C:\\data\\install\\" -Filter *TEST* -Recurse -Force -Verbose -ToSession $session
$filename = $env:JOB_NAME + "_" + $env:BUILD_DISPLAY_NAME + "_wwwroot.7z"
Invoke-Command -Session $session -ScriptBlock {cmd /c "C:\\Program Files\\7-Zip\\7z.exe\\" x C:\\Data\\Install\\$filename -oC:\\data\\install\\test -aoa >NUL}
Remove-PSSession $session
Exit-PSSession
'''

如果我将Invoke-Command更改为以下内容,则Program Files目录似乎可以正确解析,但是变量$ filename不再解析。

Invoke-Command -Session $session -ScriptBlock {cmd /c \'"C:\\Program Files\\7-Zip\\7z.exe" x C:\\Data\\Install\\$filename -oC:\\data\\install\\test -aoa >NUL'}
  

powershell.exe:未指定:(:String)[],RemoteException在   C:\ web \ Jenkins \ workspace \ XXX @ tmp \ durable-53dbead2 \ powershellWrapper.ps1:5   字符数:3   +&powershell -NoProfile -NonInteractive -ExecutionPolicy Bypass -Fi ...   + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~   + CategoryInfo:未指定:(未指定:(... RemoteException:String)[],RemoteException   + FullyQualifiedErrorId:NativeCommandError

     
      
  • CategoryInfo:未指定:(:String)[],RemoteException
  •   
  • FullyQualifiedErrorId:NativeCommandError
  •   
  • PSComputerName:XXXXX
  •   
     

错误:系统找不到指定的文件。

     

C:\ Data \ Install \ $ filename

     

系统错误:

     

系统找不到指定的文件。

希望您能在这种情况下为我提供帮助!其余命令运行正常。

谢谢!

2 个答案:

答案 0 :(得分:2)

第一个命令中的7z.exe路径具有多余的结尾\ ,这会引起问题:

cmd /c "C:\\Program Files\\7-Zip\\7z.exe\\"  # <- trailing \\ shouldn't be there

在第二个命令中,您在传递给cmd /c'...')的命令周围使用单引号 PowerShell中的'...'字符串被视为 literals ,这说明了为什么$fileName未展开(内插);
在PowerShell中仅扩展双引号("...")字符串,并在限制范围内扩展无引号的命令参数;例如,将Write-Output '$HOME'的输出与Write-Output "$HOME" / Write-Output $HOME的输出进行比较。

正如iRon所提到的,根本不需要参与cmd -PowerShell完全能够直接执行命令行程序,因此应该可以:

Invoke-Command -Session $session -ScriptBlock { & "C:\\Program Files\\7-Zip\\7z.exe" x C:\\Data\\Install\\$using:filename -oC:\\data\\install\\test -aoa >$null }
  • 由于直接调用7z.exe,现在不再需要外部引号,因此$fileName应该扩展。

    • 但是请注意,$fileName被替换为 $using:fileName ,这对于使目标会话了解 local 是必需的$fileName变量-请参见Get-Help about_Remote_Variables
  • 由于7z.exe文件路径已被引用(由于包含空格,因此必不可少),因此您必须使用呼叫运营商& < / strong>,以调用它。

  • 由于>重定向现在由PowerShell本身执行,因此cmd样式的>NUL输出抑制已替换为其PowerShell类似物 {{1} }

答案 1 :(得分:0)

我想知道是否为此必须调用CMD shell。 我想直接调用带有其参数的7z.exe会更简单。

不过,您可以像这样构建自己的脚本块:

[ScriptBlock]::Create('cmd /c "C:\\Program Files\\7-Zip\\7z.exe" x C:\\Data\\Install\\' + $filename + ' -oC:\\data\\install\\test -aoa >NUL')