Two Ruby equivalents to Powershell commands

Hi,

I’m in the process of transferring a bunch of script from powershell to
ruby to aid interoperability with an existing application and I’m
looking for two ruby equivalents to powershell commands:

PSBASE is a view which returns the raw view of an object.
getText returns the text between the current location and the specified
location in the buffer.

I use these a lot with WMI code in powershell, an example:

$Var1 = path to WMI class or object
$Var1.psbase.gettext(1) > wmi.xml

This would give me pure XML of a WMI object.

Any help greatly appreciated.

On Thu, Jun 19, 2008 at 10:38 AM, Nicholas C.
[email protected] wrote:

I use these a lot with WMI code in powershell, an example:

$Var1 = path to WMI class or object
$Var1.psbase.gettext(1) > wmi.xml

This would give me pure XML of a WMI object.

I’m not sure that you need PSBASE outside of powershell, I could be
wrong, though. GetText in OLE land is called GetText_.

Win32OLE example:

require ‘win32ole’
=> true

?> wmi = WIN32OLE.connect(“winmgmts://”)
=> #WIN32OLE:0x2c50740

?> processes = wmi.ExecQuery(“select * from win32_process”)
=> #WIN32OLE:0x2c280c0

?>
?> for process in processes do
?> p process.gettext_(1)

break
end
"<INSTANCE CLASSNAME="Win32_Process"><PROPERTY NAME="_PATH"
CLASSORIGIN="

Ruby-WMI example:

require ‘ruby-wmi’
=> true
proc = WMI::Win32_Process.find(:first)
=> #WIN32OLE:0x2be25e0
proc.gettext_(1)
=> “<PROPERTY NAME=”__PATH"
CLASSORIGIN="

Hope that helps.

Gordon

Cheers Gordon, you are a life saver. Whilst im on the same subject, i am
also having trouble creating a new GUID. With Powershell i can do:

$NEWGUID = [GUID]::NewGUID().ToString()

Do you think its possible to do this with Ruby and ruby-wmi?

Many thanks,

Nick

Gordon T. wrote:

On Thu, Jun 19, 2008 at 10:38 AM, Nicholas C.
[email protected] wrote:

I use these a lot with WMI code in powershell, an example:

$Var1 = path to WMI class or object
$Var1.psbase.gettext(1) > wmi.xml

This would give me pure XML of a WMI object.

I’m not sure that you need PSBASE outside of powershell, I could be
wrong, though. GetText in OLE land is called GetText_.

Win32OLE example:

require ‘win32ole’
=> true

?> wmi = WIN32OLE.connect(“winmgmts://”)
=> #WIN32OLE:0x2c50740

?> processes = wmi.ExecQuery(“select * from win32_process”)
=> #WIN32OLE:0x2c280c0

?>
?> for process in processes do
?> p process.gettext_(1)

break
end
"<INSTANCE CLASSNAME="Win32_Process"><PROPERTY NAME="_PATH"
CLASSORIGIN="

Ruby-WMI example:

require ‘ruby-wmi’
=> true
proc = WMI::Win32_Process.find(:first)
=> #WIN32OLE:0x2be25e0
proc.gettext_(1)
=> “<PROPERTY NAME=”__PATH"
CLASSORIGIN="

Hope that helps.

Gordon

On Fri, Jun 20, 2008 at 14:21, Nicholas C. [email protected]
wrote:

Cheers Gordon, you are a life saver. Whilst im on the same subject, i am
also having trouble creating a new GUID. With Powershell i can do:

$NEWGUID = [GUID]::NewGUID().ToString()

Do you think its possible to do this with Ruby and ruby-wmi?

This is how I create GUIDs (requires win32utils gem, might not be
tested - I’m reinstalling ruby right now):

require ‘windows/com’
require ‘windows/unicode’

class String

Return the portion of the string up to the first NULL character.

This

was added for both speed and convenience.

def nstrip
self[ /^[^\0]*/ ]
end
end

class Guid

BUFFER_SIZE = 100

attr_reader :data

def initialize(data = nil)
@data = data
create if data.nil?
end

def create
@data = 0.chr * 16
raise ‘GUID Error’ unless CoCreateGuid(@data)
end

def to_s
ret = 0.chr * BUFFER_SIZE
i = StringFromGUID2(@data, ret, BUFFER_SIZE)
wide_to_multi(ret[0…i*2]).nstrip
end

private

include Windows::COM
include Windows::Unicode

end

if File.expand_path(FILE) == File.expand_path($0)
puts Guid.new.to_s
end

Thanks Jano. If you have a minute, do you think you could run through
that code and explain what its doing? I am new to Ruby and a large
portion of that went over my head :slight_smile:

Nick

On Fri, Jun 20, 2008 at 16:05, Nicholas C. [email protected]
wrote:

Thanks Jano. If you have a minute, do you think you could run through
that code and explain what its doing? I am new to Ruby and a large
portion of that went over my head :slight_smile:

  1. You’ll find documentation for CoCreateGuid here:
    CoCreateGuid function (combaseapi.h) - Win32 apps | Microsoft Learn
    and for StringFromGUID2 here:
    StringFromGUID2 function (combaseapi.h) - Win32 apps | Microsoft Learn
    (these are C functions from ole32.dll)

  2. I call them using WIN32API, conveniently wrapped by windows-pr gem
    from win32utils project.

these are from windows-pr gem

require ‘windows/com’
require ‘windows/unicode’

helper function to strip everything past the first NULL character.

Copied from some file in win32utils
class String

Return the portion of the string up to the first NULL character.

This

was added for both speed and convenience.

def nstrip
self[ /^[^\0]*/ ]
end
end

class Guid

BUFFER_SIZE = 100

attr_reader :data

two ways of using this class - 1. either provide GUID in binary

form Guid.new(data) or create a new one (Guid.new)
def initialize(data = nil) ### nil is default value for data parameter
@data = data
create if data.nil? ### if there’s no data, call create
end

create new guid

def create
@data = 0.chr * 16 ### make empty buffer for the binary GUID
“\0\0\0\0…\0”
raise ‘GUID Error’ unless CoCreateGuid(@data) ### call the API. the
call will place the created GUID in @data.
end

convert binary guid to string representation

def to_s
ret = 0.chr * BUFFER_SIZE ### temporary buffer to place the string
form
i = StringFromGUID2(@data, ret, BUFFER_SIZE) ### call the API

API returns zero-terminated wide string. this is the conversion to

ordinary ruby string.

wide_to_multi is from windows/unicode

wide_to_multi(ret[0…i*2]).nstrip
end

private

this code includes COM and Unicode modules into this class, so

that we can use them.
include Windows::COM
include Windows::Unicode

end

this line is kind of idiom/guard

it allows to specify code to be run when the file is run directly.

This code will not run

if this file is required or included in another file. (script vs.

library)
if File.expand_path(FILE) == File.expand_path($0)
puts Guid.new.to_s
end


Ok, and now ask questions! :wink:
J.