从ruby执行powershell命令

时间:2017-12-04 14:05:46

标签: ruby powershell

我试图从ruby代码执行powershell命令。 Get-WmiObject -Class Win32_Product -ComputerName。 -Filter“Name ='Qlik Sense Client'”| Select-Object -Property version

它完美地给了我产品的版本。但是当我尝试从ruby执行时(在反引号中的整个命令)同样的事情: find = powershell.exe Get-WmiObject -Class Win32_Product -ComputerName . -Filter "Name=''"|Select-Object -Property version

命令中断,它无法解释红宝石中的引号,管道等。我试图逃避这些引用,但它仍然打破了。我也不知道如何逃脱这条管道。 请在这里帮助我或推荐我相关的东西。非常感谢。

2 个答案:

答案 0 :(得分:4)

我现在已经测试了这个:

require 'base64'
cmd = %{Get-WmiObject -Class Win32_Product -ComputerName . -Filter "Name='Qlik Sense Client'"|Select-Object -Property version}
encoded_cmd = Base64.strict_encode64(cmd.encode('utf-16le'))
find = `powershell.exe -encodedCommand #{encoded_cmd}`

Powershell期望使用UTF-16LE编码的字符串,因此您必须在base64转换之前从Ruby的编码(UTF-8)进行转换。

或者,您可以尝试使用shellwords中的shellescape来转义命令,以便shell将其解释为单个字符串。

另一种方法是将powershell.exe -Command -popen3一起使用。这将允许您编写命令并使用文件流读取其结果。

答案 1 :(得分:0)

这里有一个关于我如何对外部应用程序进行shell的示例,也应该与Powershell一起使用。在没有额外分隔符的{}之间从控制台复制工作命令。 %Q还可以在您的命令不总是相同的情况下进行变量插值,它的工作方式与“分隔符”之间的工作方式相同。

所有输出都由" 2>&1"捕获,并在while之后逐行枚举。

如果捕获了多行,您需要检查显示的结果是哪一行并返回结果。

def powershell 
  command = %Q{your command just like you execute it in a console}
  IO.popen(command+" 2>&1") do |pipe|
    pipe.sync = true
    while lijn = pipe.gets
      # do whatever you need with the output of the command
      # return the result
    end
  end
end

如果您不需要插值,请使用%q {}替代方法,因为这也会产生问题。在获得PowerShell结果的同一控制台中使用Ruby comamnd。确保您可以从那里运行powershell(必须在路径中)。

但据我所知,这将为您提供电脑上已安装产品的名称和版本。

为什么不只使用Ruby?它比非常慢的Wmi查询更快。

require 'win32/registry'

Win32::Registry::HKEY_LOCAL_MACHINE.open(
  'Software\Microsoft\Windows\CurrentVersion\Uninstall'
) do |reg|
  reg.each_key do |key|
    k = reg.open(key)
    puts key
    puts k["DisplayName"]    rescue "?"
    puts k["DisplayVersion"] rescue "?"
    puts
  end
end