7

I was trying to execute a powershell command from ruby code. Get-WmiObject -Class Win32_Product -ComputerName . -Filter "Name='Qlik Sense Client'" |Select-Object -Property version

It gives me the version of the product perefectly. But the same thing when i try to execute from ruby like(entire command in backticks) : find = powershell.exe Get-WmiObject -Class Win32_Product -ComputerName . -Filter "Name=''"|Select-Object -Property version

The command breaks, it cant interpret the quotes, pipes etc in ruby. I tried to escape those quotes but it still it breaks. I dont know how to escape that pipe as well. Kindly help me here or refer me to something relevant. Many thanks.

2 Answers 2

8

I have tested this now:

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 expects UTF-16LE-encoded strings, so you have to convert from Ruby's encoding (UTF-8) before the base64 conversion.


Alternatively you could try using shellescape from shellwords to escape the command so the shell interprets it as a single string.

Another alternative is to use powershell.exe -Command - with popen3. That will let you write your commands and read their results using a file stream.

Sign up to request clarification or add additional context in comments.

12 Comments

Thanks Max for the reply. But the last line where i execute the ps command is not able to read that binary as it it. Its giving like : "??????4??????????????????????????????????????????4????????? : The term \n'??????4?????????????????????? ????4?????????' is not recognized as the name of a cmdlet, function, \nscript file, or operable program. i tried removing newline chars etc, but still same output. Again, can you please give me an e.g of popen.My command has a pipe, so thinking how to pass it.Thanks again.
popen is definitely the most complicated way to go. The documentation I linked to has some examples. Did you try the base64 encoded approach?
hi Max,yes i did try that base64.The first line coverts it into some binary, but when i run the powershell -exe command, it gives the error as i mentioned above.Kindly advice if smthng needs to be modified.Many thanks!
@padmaksharoy I found the error and corrected my answer
HI Max, Many thanks, it works fine. Please do me one more favor. Can you tell me the reference so that I can get those basic information like the encoding standard you have mentioned. This approach will help me debug probs with a new approach unlike just google search. Many thanks again!
|
0

Here an example of how I shell to external apps, should also work with Powershell. Copy the working command from your console between the {} without extra delimiters. The %Q also makes it possible to do interpolation of variables in case your command is not always the same, it works the same way as between the " delimiter.

All the output is captured by the " 2>&1" and enumerated line by line in the block after while.

In case more than one line is captured you need to check which line the result you are after is displayed and return the result.

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

Use the %q{} alternative if you don't need the interpolation since that also could give problems. Use the Ruby comamnd in the same console as where you get your powershell results. Ensure you can run powershell from there (must be in the path).

But as I understand this will get you the name and version of the installed products on your pc.

Why not use just Ruby ? It's way more faster than the VERY slow Wmi queries.

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

10 Comments

Hi Peter, many thanks for the reply. I tried running the powershell command as it as without any delimeter, like command = %Q{Get-WmiObject -Class Win32_Product -ComputerName . -Filter "Name='Java Auto Updater'"|Select-Object -Property version} But its not able to execute the powershell command. PS C:\Users\padmaksha.roy\Documents> ruby cmd_test.rb 'Get-WmiObject' is not recognized as an internal or external command, Command works fine. Prints below. version ------- 2.8.121.13 kindly suggest.
try with %q{} and also see my suggestion I added, I can't run the powershell command you use, I allready get error in the console
hi Peter, many thanks again. %q{} gives the same error, cant interpret the powershell commands. The 2nd thing you advised does work but it is not giving all the list of products. Shall i have to change the directory to get the list of all products installed. I will then put some checks for the product i want. Will be grateful if you advice a little here.Thanks again.
just use the basic "powershell.exe Get-WmiObject -Class Win32_Product -ComputerName ." and do the filtering and selecting of properties in the while block but it will be slow otherwise use the ruby method but search in the registry first in which key the required info is using regedit.exe
Hi Peter, I could get the exact details using the rub win32 Reg doing some iterations. Many thanks for your help.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.