Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 5 additions & 15 deletions lib/beaker/host/pswindows/exec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,26 +61,16 @@ def path
end

def get_ip
# when querying for an IP this way the return value can be formatted like:
# IPAddress=
# IPAddress={"129.168.0.1"}
# IPAddress={"192.168.0.1","2001:db8:aaaa:bbbb:cccc:dddd:eeee:0001"}
ips = execute('powershell.exe -NoProfile -NonInteractive -Command "(Get-CimInstance Win32_NetworkAdapterConfiguration -Filter \'IPEnabled=True\' | ForEach-Object { $_.IPAddress })"')

ips = execute("wmic nicconfig where ipenabled=true GET IPAddress /format:list")

ip = ''
ips.each_line do |line|

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thoughts about:

def get_ip
  ips = execute('...')
  ips.lines.map(&:strip).find { |line| Resolv::IPv4::Regex.match?(line) } || ''
end

matches = line.split('=')
next if matches.length <= 1

matches = matches[1].match(/^{"(.*?)"/)
next if matches.nil? || matches.captures.nil? || matches.captures.empty?
ip = line.strip
next unless ip.match?(/^\d{1,3}(?:\.\d{1,3}){3}$/)

ip = matches.captures[0] if matches && matches.captures
break if ip != ''
return ip
end

ip
''
end

# Attempt to ping the provided target hostname
Expand Down
7 changes: 5 additions & 2 deletions lib/beaker/host/pswindows/group.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ module PSWindows::Group
include Beaker::CommandFactory

def group_list
execute('cmd /c echo "" | wmic group where localaccount="true" get name /format:value') do |result|
execute('powershell.exe -NoProfile -NonInteractive -Command "Get-CimInstance Win32_Group -Filter \'LocalAccount=True\' | Select-Object -ExpandProperty Name"') do |result|
groups = []
result.stdout.each_line do |line|
groups << (line.match(/^Name=(.+)$/) or next)[1]
group = line.strip
next if group.empty?

groups << group
end
Comment on lines 6 to 12

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about:

groups = result.stdout.lines.map(&:strip).reject(&:empty?)

This is also a repeated pattern in other files we can use to simplify the parsing.


yield result if block_given?
Expand Down
2 changes: 1 addition & 1 deletion lib/beaker/host/pswindows/pkg.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def uninstall_package(_name, _cmdline_args = '')
0
end

# Examine the host system to determine the architecture, overrides default host determine_if_x86_64 so that wmic is used
# Examine the host system to determine the architecture
# @return [Boolean] true if x86_64, false otherwise
def determine_if_x86_64
identify_windows_architecture.include?('AMD64')
Expand Down
7 changes: 5 additions & 2 deletions lib/beaker/host/pswindows/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ module PSWindows::User
include Beaker::CommandFactory

def user_list
execute('cmd /c echo "" | wmic useraccount where localaccount="true" get name /format:value') do |result|
execute('powershell.exe -NoProfile -NonInteractive -Command "Get-CimInstance Win32_UserAccount -Filter \'LocalAccount=True\' | Select-Object -ExpandProperty Name"') do |result|
users = []
result.stdout.each_line do |line|
users << (line.match(/^Name=(.+)/) or next)[1]
user = line.strip
next if user.empty?

users << user
end

yield result if block_given?
Expand Down
20 changes: 5 additions & 15 deletions lib/beaker/host/windows/exec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,26 +24,16 @@ def path
end

def get_ip
# when querying for an IP this way the return value can be formatted like:
# IPAddress=
# IPAddress={"129.168.0.1"}
# IPAddress={"192.168.0.1","2001:db8:aaaa:bbbb:cccc:dddd:eeee:0001"}
ips = execute('powershell.exe -NoProfile -NonInteractive -Command "(Get-CimInstance Win32_NetworkAdapterConfiguration -Filter \'IPEnabled=True\' | ForEach-Object { $_.IPAddress })"')

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My understanding of the exec implementation is that it's the non-PowerShell implementation so can we really count on powershell.exe being present? If we can, is there any reason the user should even use this implementation or can we deprecate it altogether?


ips = execute("wmic nicconfig where ipenabled=true GET IPAddress /format:list")

ip = ''
ips.each_line do |line|
matches = line.split('=')
next if matches.length <= 1

matches = matches[1].match(/^{"(.*?)"/)
next if matches.nil? || matches.captures.nil? || matches.captures.empty?
ip = line.strip
next unless ip.match?(/^\d{1,3}(?:\.\d{1,3}){3}$/)

ip = matches.captures[0] if matches && matches.captures
break if ip != ''
return ip
end

ip
''
end

# Attempt to ping the provided target hostname
Expand Down
9 changes: 6 additions & 3 deletions lib/beaker/host/windows/group.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ module Windows::Group
include Beaker::CommandFactory

def group_list
execute('cmd /c echo "" | wmic group where localaccount="true" get name /format:value') do |result|
execute('powershell.exe -NoProfile -NonInteractive -Command "Get-CimInstance Win32_Group -Filter \'LocalAccount=True\' | Select-Object -ExpandProperty Name"') do |result|
groups = []
result.stdout.each_line do |line|
groups << (line.match(/^Name=(.+)$/) or next)[1]
group = line.strip
next if group.empty?

groups << group
end

yield result if block_given?
Expand All @@ -14,7 +17,7 @@ def group_list
end
end

# using powershell commands as wmic is deprecated in windows 2025
# using powershell commands as wmic is deprecated/removed on newer Windows
def group_list_using_powershell
execute('cmd /c echo "" | powershell.exe "Get-LocalGroup | Select-Object -ExpandProperty Name"') do |result|
groups = []
Expand Down
2 changes: 1 addition & 1 deletion lib/beaker/host/windows/pkg.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def uninstall_package(name, _cmdline_args = '')
raise "Package #{name} cannot be uninstalled on #{self}"
end

# Examine the host system to determine the architecture, overrides default host determine_if_x86_64 so that wmic is used
# Examine the host system to determine the architecture
# @return [Boolean] true if x86_64, false otherwise
def determine_if_x86_64
identify_windows_architecture.include?('64')
Expand Down
9 changes: 6 additions & 3 deletions lib/beaker/host/windows/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ module Windows::User
include Beaker::CommandFactory

def user_list
execute('cmd /c echo "" | wmic useraccount where localaccount="true" get name /format:value') do |result|
execute('powershell.exe -NoProfile -NonInteractive -Command "Get-CimInstance Win32_UserAccount -Filter \'LocalAccount=True\' | Select-Object -ExpandProperty Name"') do |result|
users = []
result.stdout.each_line do |line|
users << (line.match(/^Name=(.+)/) or next)[1]
user = line.strip
next if user.empty?

users << user
end

yield result if block_given?
Expand All @@ -14,7 +17,7 @@ def user_list
end
end

# using powershell commands as wmic is deprecated in windows 2025
# using powershell commands as wmic is deprecated/removed on newer Windows
def user_list_using_powershell
execute('cmd /c echo "" | powershell.exe "Get-LocalUser | Select-Object -ExpandProperty Name"') do |result|
users = []
Expand Down
8 changes: 8 additions & 0 deletions spec/beaker/host/pswindows/exec_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@ def to_s
end
end

describe '#get_ip' do
it 'returns the first IPv4 address from CIM output' do
output = "fe80::1\n192.168.0.1\n10.0.0.2\n"
expect(instance).to receive(:execute).with(/Win32_NetworkAdapterConfiguration/).and_return(output)
expect(instance.get_ip).to eq('192.168.0.1')
end
end

describe '#modified_at' do
before do
allow(instance).to receive(:execute).and_return(stdout)
Expand Down
36 changes: 10 additions & 26 deletions spec/beaker/host/pswindows/user_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,17 @@ class PSWindowsUserTest
end

describe PSWindowsUserTest do
let(:wmic_output) do
let(:user_list_output) do
<<~EOS
Name=Administrator
Administrator

bob foo

bob-dash

bob.foo


Name=bob foo





Name=bob-dash





Name=bob.foo





Name=cyg_server
cyg_server



Expand All @@ -42,22 +26,22 @@ class PSWindowsUserTest

EOS
end
let(:command) { 'cmd /c echo "" | wmic useraccount where localaccount="true" get name /format:value' }
let(:command) { %q(powershell.exe -NoProfile -NonInteractive -Command "Get-CimInstance Win32_UserAccount -Filter 'LocalAccount=True' | Select-Object -ExpandProperty Name") }
let(:host) { double.as_null_object }
let(:result) { Beaker::Result.new(host, command) }

describe '#user_list' do
it 'returns user names list correctly' do
result.stdout = wmic_output
result.stdout = user_list_output
expect(subject).to receive(:execute).with(command).and_yield(result)
expect(subject.user_list).to be === ['Administrator', 'bob foo', 'bob-dash', 'bob.foo', 'cyg_server']
end

it 'yields correctly with the result object' do
result.stdout = wmic_output
result.stdout = user_list_output
expect(subject).to receive(:execute).and_yield(result)
subject.user_list do |result|
expect(result.stdout).to be === wmic_output
expect(result.stdout).to be === user_list_output
end
end
end
Expand Down
8 changes: 8 additions & 0 deletions spec/beaker/host/windows/exec_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,14 @@ def to_s
end
end

describe '#get_ip' do
it 'returns the first IPv4 address from CIM output' do
output = "fe80::1\n192.168.0.1\n10.0.0.2\n"
expect(instance).to receive(:execute).with(/Win32_NetworkAdapterConfiguration/).and_return(output)
expect(instance.get_ip).to eq('192.168.0.1')
end
end

describe '#cygwin_installed?' do
let(:response) { double('response') }

Expand Down
9 changes: 4 additions & 5 deletions spec/beaker/host/windows/group_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,25 +12,24 @@ class WindowsGroupTest
let(:result) { double(:result, :stdout => group_list_output) }
let(:group_list_output) do
<<~EOS
Name=Foo
Foo


Name=Bar6
Bar6


EOS
end

def add_group(group_name)
group_list_output << <<~EOS
Name=#{group_name}
#{group_name}


EOS
end

before do
expect(instance).to receive(:execute).with(/wmic group where/).and_yield(result)
expect(instance).to receive(:execute).with(/Win32_Group/).and_yield(result)
end

it "gets a group_list" do
Expand Down
36 changes: 10 additions & 26 deletions spec/beaker/host/windows/user_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,35 +9,19 @@ class WindowsUserTest
let(:result) { Beaker::Result.new(host, command) }

describe '#user_list' do
let(:command) { 'cmd /c echo "" | wmic useraccount where localaccount="true" get name /format:value' }
let(:command) { %q(powershell.exe -NoProfile -NonInteractive -Command "Get-CimInstance Win32_UserAccount -Filter 'LocalAccount=True' | Select-Object -ExpandProperty Name") }

let(:wmic_output) do
let(:user_list_output) do
<<~EOS
Name=Administrator





Name=bob foo





Name=bob-dash





Name=bob.foo

Administrator

bob foo

bob-dash

bob.foo

Name=cyg_server
cyg_server



Expand All @@ -50,16 +34,16 @@ class WindowsUserTest
end

it 'returns user names list correctly' do
result.stdout = wmic_output
result.stdout = user_list_output
expect(subject).to receive(:execute).with(command).and_yield(result)
expect(subject.user_list).to be === ['Administrator', 'bob foo', 'bob-dash', 'bob.foo', 'cyg_server']
end

it 'yields correctly with the result object' do
result.stdout = wmic_output
result.stdout = user_list_output
expect(subject).to receive(:execute).and_yield(result)
subject.user_list do |result|
expect(result.stdout).to be === wmic_output
expect(result.stdout).to be === user_list_output
end
end
end
Expand Down