From 7c4813a7e90adad2f5f6d0cda16e4c8407fecfd8 Mon Sep 17 00:00:00 2001 From: Leidong Wang Date: Fri, 29 Nov 2024 11:36:29 +0800 Subject: [PATCH] Replace WMIC with powershell cmd From Win11-24H2, WMIC is an optional feature for Windows, And it will be fully removed in the future.So replace the related cmd Signed-off-by: Leidong Wang --- virttest/utils_disk.py | 2 +- virttest/utils_misc.py | 15 +++++--- virttest/utils_net.py | 45 +++++++++++++++++------- virttest/utils_netperf.py | 3 +- virttest/utils_test/__init__.py | 15 ++++---- virttest/utils_test/qemu/__init__.py | 2 +- virttest/utils_windows/drive.py | 52 +++++++++++++++++++--------- virttest/utils_windows/system.py | 21 ++++++++--- virttest/utils_windows/virtio_win.py | 2 +- 9 files changed, 108 insertions(+), 49 deletions(-) diff --git a/virttest/utils_disk.py b/virttest/utils_disk.py index 57d54992c4..0ea6bd7ee7 100644 --- a/virttest/utils_disk.py +++ b/virttest/utils_disk.py @@ -835,7 +835,7 @@ def get_disk_size_windows(session, did): e.g. 0, 1 :return: disk size. """ - cmd = "wmic diskdrive get size, index" + cmd = 'powershell -command "Get-CimInstance Win32_DiskDrive | Select-Object Index, Size"' return int(re.findall(r"%s\s+(\d+)" % did, session.cmd_output(cmd))[0]) diff --git a/virttest/utils_misc.py b/virttest/utils_misc.py index 6f08dcbb45..01f218aa98 100644 --- a/virttest/utils_misc.py +++ b/virttest/utils_misc.py @@ -2351,8 +2351,8 @@ def get_free_disk(session, mount): :return string: freespace M-bytes """ if re.match(r"[a-zA-Z]:", mount): - cmd = "wmic logicaldisk where \"DeviceID='%s'\" " % mount - cmd += "get FreeSpace" + cmd = ('powershell -command "Get-CimInstance Win32_LogicalDisk | Where-Object {$_.DeviceID -eq \'%s\'}' + ' | Select-Object FreeSpace"') % mount output = session.cmd_output(cmd) free = "%sK" % re.findall(r"\d+", output)[0] else: @@ -2375,7 +2375,9 @@ def get_free_mem(session, os_type): if os_type != "windows": free = "%s kB" % get_mem_info(session, "MemFree") else: - output = session.cmd_output("wmic OS get FreePhysicalMemory") + output = session.cmd_output( + 'powershell -command "Get-CimInstance Win32_OperatingSystem | ' + 'Select-Object FreePhysicalMemory"') free = "%sK" % re.findall("\d+", output)[0] free = float(normalize_data_size(free, order_magnitude="M")) return int(free) @@ -2475,11 +2477,14 @@ def get_win_disk_vol(session, condition="VolumeName='WIN_UTILS'"): Getting logicaldisk drive letter in windows guest. :param session: session Object. - :param condition: supported condition via cmd "wmic logicaldisk list". + :param condition: supported condition via powershell cmd "Get-CimInstance Win32_LogicalDisk". :return: volume ID. """ - cmd = "wmic logicaldisk where (%s) get DeviceID" % condition + c_name, c_value = condition.split('=') + cmd = ( + 'powershell -command "Get-CimInstance -ClassName Win32_LogicalDisk | Where-Object {$_.%s -like %s}' + ' | Select-Object DeviceID"') % (c_name, c_value) output = session.cmd(cmd, timeout=120) device = re.search(r"(\w):", output, re.M) if not device: diff --git a/virttest/utils_net.py b/virttest/utils_net.py index 91715e1c88..4e73c0fb9b 100644 --- a/virttest/utils_net.py +++ b/virttest/utils_net.py @@ -1654,10 +1654,12 @@ def set_guest_ip_addr(session, mac, ip_addr, netmask="255.255.255.0", os_type="l session.cmd(cmd, timeout=360) elif os_type == "windows": info_cmd = "ipconfig /all" - cmd = ( - "wmic nicconfig where MACAddress='%s' call " - "enablestatic '%s','%s'" % (mac, ip_addr, netmask) - ) + get_nic_cmd = ('powershell -command "$Adapter=Get-CimInstance Win32_NetworkAdapterConfiguration | ' + 'Where-Object {$_.MACAddress -eq \'%s\'}; $Adapter.InterfaceIndex') % mac + nic_index = session.cmd_output(get_nic_cmd, timeout=120) + prefix_length = subnet_mask_to_prefix_length(netmask) + cmd = ('powershell -command "New-NetIPAddress -InterfaceIndex %s -IPAddress \'%s\' -PrefixLength %s"' % + (nic_index, ip_addr, prefix_length)) session.cmd(cmd, timeout=360) else: info_cmd = "" @@ -1666,6 +1668,23 @@ def set_guest_ip_addr(session, mac, ip_addr, netmask="255.255.255.0", os_type="l LOG.debug(session.cmd_output(info_cmd)) raise IPAddrSetError(mac, ip_addr, err) +def subnet_mask_to_prefix_length(subnet_mask): + """ + Convert subnet_mask from 255.*** to prefix length + + :param subnet_mask: nic subnet_mask + + :return: prefix length + """ + + octets = subnet_mask.split('.') + + prefix_length = 0 + for octet in octets: + prefix_length += bin(int(octet)).count('1') + + return prefix_length + def get_guest_nameserver(session): """ @@ -3788,7 +3807,8 @@ def str2ipaddr(str_ip): return None maps = {} - cmd = "wmic nicconfig where IPEnabled=True get ipaddress, macaddress" + cmd = ('powershell -command "Get-CimInstance Win32_NetworkAdapterConfiguration | ' + 'Where-Object {$_.IPEnabled -eq \'True\'} | Select-Object IPAddress, MACAddress"') out = session.cmd_output(cmd) regex = r".*\w{2}[:-]\w{2}[:-]\w{2}[:-]\w{2}[:-]\w{2}[:-]\w{2}\s*" lines = [l.strip() for l in out.splitlines() if l.strip()] @@ -3941,19 +3961,20 @@ def update_mac_ip_address(vm, timeout=240): def get_windows_nic_attribute( - session, key, value, target, timeout=240, global_switch="nic" + session, key, value, target, timeout=240, global_switch="NetworkAdapter" ): """ - Get the windows nic attribute using wmic. All the support key you can - using wmic to have a check. + Get the windows nic attribute using powershell. All the support key you can + using powershell to have a check. :param session: session to the virtual machine - :param key: the key supported by wmic + :param key: the key supported by Get-CimInstance :param value: the value of the key :param target: which nic attribute you want to get. """ - cmd = 'wmic %s where %s="%s" get %s' % (global_switch, key, value, target) + cmd = ('powershell -command "Get-CimInstance Win32_%s | Where-Object {$_.%s -eq \'%s\'} | Select-Object %s"' + % (global_switch, key, value, target)) status, out = session.cmd_status_output(cmd, timeout=timeout) if status != 0: err_msg = "Execute guest shell command('%s') " "failed with error: '%s'" % ( @@ -3993,7 +4014,7 @@ def restart_windows_guest_network(session, connection_id, timeout=240, mode="net :param session: session to virtual machine :param connection_id: windows nic connectionid,it means connection name, - you Can get connection id string via wmic + you Can get connection id string via wmic or powershell """ if mode == "netsh": disable_windows_guest_network(session, connection_id, timeout=timeout) @@ -4011,7 +4032,7 @@ def restart_windows_guest_network_by_key( using devcon mode must download devcon.exe and put it under c:\ :param session: session to virtual machine - :param key: the key supported by wmic nic + :param key: the key supported by Get-CimInstance nic :param value: the value of the key :param timeout: timeout :param mode: command mode netsh or devcon diff --git a/virttest/utils_netperf.py b/virttest/utils_netperf.py index 364e297be9..54708fc9a8 100644 --- a/virttest/utils_netperf.py +++ b/virttest/utils_netperf.py @@ -290,7 +290,8 @@ def __init__( def is_target_running(self, target): list_cmd = "ps -C %s" % target if self.client == "nc": - list_cmd = "wmic process where name='%s' list" % target + list_cmd = ('powershell -command "Get-CimInstance Win32_Process | Where-Object {$_.Name -eq \'%s\'}' + ' | Format-List *"') % target try: output = self.session.cmd_output_safe(list_cmd, timeout=120) check_reg = re.compile(r"%s" % target, re.I | re.M) diff --git a/virttest/utils_test/__init__.py b/virttest/utils_test/__init__.py index d687fccbaf..a9ff81a37d 100755 --- a/virttest/utils_test/__init__.py +++ b/virttest/utils_test/__init__.py @@ -300,18 +300,19 @@ def start_windows_service(session, service, timeout=120): def get_windows_file_abs_path(session, filename, extension="exe", tmout=240): """ - return file abs path "drive+path" by "wmic datafile" + return file abs path "drive+path" by Get-CimInstance """ - cmd_tmp = "wmic datafile where \"Filename='%s' and " - cmd_tmp += "extension='%s'\" get drive^,path" - cmd = cmd_tmp % (filename, extension) + full_name = filename + '.' + extension + cmd = ('powershell -command "Get-PSDrive -PSProvider FileSystem | ForEach-Object ' + '{Get-ChildItem -Path $_.Root -Filter \"%s\" -Recurse -ErrorAction SilentlyContinue} |' + ' Select-Object Fullname"') % full_name info = session.cmd_output(cmd, timeout=tmout).strip() - drive_path = re.search(r"(\w):\s+(\S+)", info, re.M) - if not drive_path: + file_abs_path = re.search(r"^[A-Z]:\\.*\.*$", info, re.M) + if not file_abs_path: raise exceptions.TestError( "Not found file %s.%s in your guest" % (filename, extension) ) - return ":".join(drive_path.groups()) + return file_abs_path.string def get_windows_disk_drive(session, filename, extension="exe", tmout=240): diff --git a/virttest/utils_test/qemu/__init__.py b/virttest/utils_test/qemu/__init__.py index 5f24a0c6ae..67aecf0803 100644 --- a/virttest/utils_test/qemu/__init__.py +++ b/virttest/utils_test/qemu/__init__.py @@ -488,7 +488,7 @@ def get_guest_total_mem(cls, vm): :return: physical memory report by guest OS in MB """ if vm.params.get("os_type") == "windows": - cmd = "wmic ComputerSystem get TotalPhysicalMemory" + cmd = 'powershell -command "(Get-CimInstance -ClassName Win32_ComputerSystem).TotalPhysicalMemory"' else: cmd = "grep 'MemTotal:' /proc/meminfo" return vm.get_memory_size(cmd) diff --git a/virttest/utils_windows/drive.py b/virttest/utils_windows/drive.py index f43ade4634..20d547f661 100644 --- a/virttest/utils_windows/drive.py +++ b/virttest/utils_windows/drive.py @@ -1,6 +1,7 @@ """ Windows drive utilities """ +import re from virttest import utils_misc @@ -8,11 +9,23 @@ def _logical_disks(session, cond=None, props=None): - cmd = wmic.make_query("LogicalDisk", cond, props, get_swch=wmic.FMT_TYPE_LIST) - out = utils_misc.wait_for( - lambda: wmic.parse_list(session.cmd(cmd, timeout=120)), 240 - ) - return out if out else [] + c_name, c_value = cond.split('=') + cmd = ( + 'powershell -command "Get-CimInstance -ClassName Win32_LogicalDisk | Where-Object {$_.%s -like %s}' + ' | Select-Object %s | Format-List *"') % (c_name, c_value, ','.join(props)) + out = session.cmd(cmd, timeout=120) + results = [] + for para in re.split("(?:\r?\n){2,}", out.strip()): + keys, vals = [], [] + for line in para.splitlines(): + key, val = line.split(":", 1) + keys.append(key.strip()) + vals.append(val.strip()) + if len(keys) == 1: + results.append(vals[0]) + else: + results.append(dict(zip(keys, vals))) + return results if results else [] def get_hard_drive_letter(session, label): @@ -24,7 +37,7 @@ def get_hard_drive_letter(session, label): :return: Hard drive's letter if found, otherwise `None`. """ - cond = "VolumeName like '%s'" % label + cond = "VolumeName='%s'" % label try: return _logical_disks(session, cond=cond, props=["DeviceID"])[0] except IndexError: @@ -103,13 +116,20 @@ def get_disk_props_by_serial_number(session, serial_number, props): :return: The mapping between properties and values. :rtype: dict """ - cond = "SerialNumber like '%s'" % serial_number - cmd = wmic.make_query("diskdrive", cond, props=props, get_swch=wmic.FMT_TYPE_LIST) - out = wmic.parse_list(session.cmd(cmd, timeout=120)) - - if out: - mapping = out[-1] - if isinstance(mapping, str): - return {props[0]: mapping} - return mapping - return {} + cmd = ( + 'powershell -command "Get-CimInstance -ClassName Win32_Diskdrive | Where-Object {$_.SerialNumber -eq %s}' + ' | Select-Object %s | Format-List *"') % (serial_number, ','.join(props)) + out = session.cmd(cmd, timeout=120) + results = [] + for para in re.split("(?:\r?\n){2,}", out.strip()): + print(para) + keys, vals = [], [] + for line in para.splitlines(): + key, val = line.split(":", 1) + keys.append(key.strip()) + vals.append(val.strip()) + if len(keys) == 1: + results.append(vals[0]) + else: + results.append(dict(zip(keys, vals))) + return results if results else [] diff --git a/virttest/utils_windows/system.py b/virttest/utils_windows/system.py index bf57605621..e76e49334c 100644 --- a/virttest/utils_windows/system.py +++ b/virttest/utils_windows/system.py @@ -1,16 +1,27 @@ """ Windows system utilities """ +import re from . import wmic def _osinfo(session, props=None): - cmd = wmic.make_query("os", props=props, get_swch=wmic.FMT_TYPE_LIST) - try: - return wmic.parse_list(session.cmd(cmd))[0] - except IndexError: - return None + cmd = ('powershell -command "Get-CimInstance -ClassName Win32_OperatingSystem | Select-Object %s | Format-List *"' + % (','.join(props))) + out = session.cmd(cmd, timeout=120) + results = [] + for para in re.split("(?:\r?\n){2,}", out.strip()): + keys, vals = [], [] + for line in para.splitlines(): + key, val = line.split(":", 1) + keys.append(key.strip()) + vals.append(val.strip()) + if len(keys) == 1: + results.append(vals[0]) + else: + results.append(dict(zip(keys, vals))) + return results[0] if results else [] def product_name(session): diff --git a/virttest/utils_windows/virtio_win.py b/virttest/utils_windows/virtio_win.py index 9bade71ade..6860b8f580 100644 --- a/virttest/utils_windows/virtio_win.py +++ b/virttest/utils_windows/virtio_win.py @@ -101,7 +101,7 @@ def drive_letter_iso(session): :return: Drive letter. """ - return drive.get_hard_drive_letter(session, "virtio-win%") + return drive.get_hard_drive_letter(session, "virtio-win*") def drive_letter_vfd(session):