Skip to content

Commit

Permalink
Revert "Added compatibility hooks for future Windows versions"
Browse files Browse the repository at this point in the history
This reverts commit 98329455492f8413b700ebcf95bc410006b32744.
  • Loading branch information
Aperocky authored and VishnuKarthikRavindran committed Nov 1, 2024
1 parent bd7991c commit a0adbe9
Show file tree
Hide file tree
Showing 6 changed files with 173 additions and 300 deletions.
166 changes: 18 additions & 148 deletions agent/managedInstances/fingerprint/hardwareInfo_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,7 @@ package fingerprint

import (
"fmt"
"os/exec"
"path/filepath"
"strconv"
"strings"
"time"

"github.com/aws/amazon-ssm-agent/agent/appconfig"
Expand All @@ -34,23 +31,12 @@ import (
"golang.org/x/sys/windows/svc/mgr"
)

type WMIInterface string

const (
hardwareID = "uuid"
wmiServiceName = "Winmgmt"

serviceRetryInterval = 15 // Seconds
serviceRetry = 5

winVersionCommand = "Get-CimInstance -ClassName Win32_OperatingSystem | Format-List -Property Version"

win2025MajorVersion = 10
win2025MinorVersion = 0
win2025BuildNumber = 26040

wmic WMIInterface = "WMIC"
cimInstance WMIInterface = "CIM Instance"
)

func waitForService(log log.T, service *mgr.Service) error {
Expand Down Expand Up @@ -105,162 +91,46 @@ var currentHwHash = func() (map[string]string, error) {

log.Debug("WMI Service is ready to be queried....")

wmiInterface, _ := getWMIInterface(log)

hardwareHash[hardwareID], _ = csproductUuid(log, wmiInterface)
hardwareHash["processor-hash"], _ = processorInfoHash(wmiInterface)
hardwareHash["memory-hash"], _ = memoryInfoHash(wmiInterface)
hardwareHash["bios-hash"], _ = biosInfoHash(wmiInterface)
hardwareHash["system-hash"], _ = systemInfoHash(wmiInterface)
hardwareHash[hardwareID], _ = csproductUuid(log)
hardwareHash["processor-hash"], _ = processorInfoHash()
hardwareHash["memory-hash"], _ = memoryInfoHash()
hardwareHash["bios-hash"], _ = biosInfoHash()
hardwareHash["system-hash"], _ = systemInfoHash()
hardwareHash["hostname-info"], _ = hostnameInfo()
hardwareHash[ipAddressID], _ = primaryIpInfo()
hardwareHash["macaddr-info"], _ = macAddrInfo()
hardwareHash["disk-info"], _ = diskInfoHash(wmiInterface)
hardwareHash["disk-info"], _ = diskInfoHash()

return hardwareHash, nil
}

// get WMI interface which should be uses to retrieve the hardware info, if any error occur use WMIC by default
func getWMIInterface(logger log.T) (wmiInterface WMIInterface, err error) {
// get Windows version number via CIM Instance, as it works on all Windows versions
if outputBytes, err := exec.Command(appconfig.PowerShellPluginCommandName, winVersionCommand).Output(); err == nil {
outputStr := strings.Replace(strings.Replace(string(outputBytes), "\n", "", -1), "\r", "", -1) //removes any new lines from the output
logger.Debugf("Windows version property command output: %s", outputStr) //expected output format should be: Version : 10.0.26100
outputStrElements := strings.Split(outputStr, ":")
if len(outputStrElements) != 2 {
logger.Warnf("Unexpected command output format for Windows version property: %s, setting WMIC as WMI interface", outputStr)
return wmic, fmt.Errorf("Error while parsing command output for windows version property. Got %v elements and was expecting 2.",
len(outputStrElements))
}

winVersion := strings.Split(strings.TrimSpace(outputStrElements[1]), ".") //secend element in the output is the actual Windows version value
if len(winVersion) != 3 {
logger.Warnf("Unexpected format for the Windows version property value: %s, setting WMIC as WMI interface", outputStr)
return wmic, fmt.Errorf("Error while parsing the Windows version property value. Got %v elements and was expecting 3.", len(winVersion))
}

winMajorVersion, err := strconv.Atoi(winVersion[0])
if err != nil {
logger.Warnf("Bad format for the Windows major version value: %s, setting WMIC as WMI interface", winVersion[0])
return wmic, fmt.Errorf("Error while parsing Windows major version: %v", err)
}
winMinorVersion, err := strconv.Atoi(winVersion[1])
if err != nil {
logger.Warnf("Bad format for the Windows minor version value: %s, setting WMIC as WMI interface", winVersion[1])
return wmic, fmt.Errorf("Error while parsing Windows minor version: %v", err)
}
winBuildNumber, err := strconv.Atoi(winVersion[2])
if err != nil {
logger.Warnf("Bad format for the Windows build number value: %s, setting WMIC as WMI interface", winVersion[2])
return wmic, fmt.Errorf("Error while parsing Windows build number: %v", err)
}

// if it is Windows 2025 or later use CIM Instance, otherwise use WMIC
if winMajorVersion >= win2025MajorVersion && winMinorVersion >= win2025MinorVersion && winBuildNumber >= win2025BuildNumber {
return cimInstance, nil
} else {
return wmic, nil
}
}

logger.Warnf("There was an issue while retrieving Windows version data: %s, setting WMIC as WMI interface", err)
return wmic, err
}

func csproductUuid(logger log.T, wmiInterface WMIInterface) (encodedValue string, err error) {
var uuid string
switch wmiInterface {
case wmic:
encodedValue, uuid, err = commandOutputHash(wmicCommand, "csproduct", "get", "UUID")
case cimInstance:
encodedValue, uuid, err = commandOutputHash(appconfig.PowerShellPluginCommandName, getCimInstanceCmdArgs("Win32_ComputerSystemProduct", "UUID"))
default:
logger.Warnf("Unknown WMI interface: %v", wmiInterface)
}

func csproductUuid(logger log.T) (encodedValue string, err error) {
encodedValue, uuid, err := commandOutputHash(wmicCommand, "csproduct", "get", "UUID")
logger.Tracef("Current UUID value: /%v/", uuid)
return
}

func processorInfoHash(wmiInterface WMIInterface) (value string, err error) {
switch wmiInterface {
case wmic:
value, _, err = commandOutputHash(wmicCommand, "cpu", "list", "brief")
case cimInstance:
propertiesToRetrieve := []string{"Caption", "DeviceID", "Manufacturer", "MaxClockSpeed", "Name", "SocketDesignation"}
value, _, err = commandOutputHash(appconfig.PowerShellPluginCommandName, getCimInstanceCmdArgs("WIN32_PROCESSOR", propertiesToRetrieve...))
default:
logger.Warnf("Unknown WMI interface: %v", wmiInterface)
}

func processorInfoHash() (value string, err error) {
value, _, err = commandOutputHash(wmicCommand, "cpu", "list", "brief")
return
}

func memoryInfoHash(wmiInterface WMIInterface) (value string, err error) {
switch wmiInterface {
case wmic:
value, _, err = commandOutputHash(wmicCommand, "memorychip", "list", "brief")
case cimInstance:
propertiesToRetrieve := []string{"Capacity", "DeviceLocator", "MemoryType", "Name", "Tag", "TotalWidth"}
value, _, err = commandOutputHash(appconfig.PowerShellPluginCommandName, getCimInstanceCmdArgs("Win32_PhysicalMemory", propertiesToRetrieve...))
default:
logger.Warnf("Unknown WMI interface: %v", wmiInterface)
}

func memoryInfoHash() (value string, err error) {
value, _, err = commandOutputHash(wmicCommand, "memorychip", "list", "brief")
return
}

func biosInfoHash(wmiInterface WMIInterface) (value string, err error) {
switch wmiInterface {
case wmic:
value, _, err = commandOutputHash(wmicCommand, "bios", "list", "brief")
case cimInstance:
propertiesToRetrieve := []string{"Manufacturer", "Name", "SerialNumber", "SMBIOSBIOSVersion", "Version"}
value, _, err = commandOutputHash(appconfig.PowerShellPluginCommandName, getCimInstanceCmdArgs("Win32_BIOS", propertiesToRetrieve...))
default:
logger.Warnf("Unknown WMI interface: %v", wmiInterface)
}

func biosInfoHash() (value string, err error) {
value, _, err = commandOutputHash(wmicCommand, "bios", "list", "brief")
return
}

func systemInfoHash(wmiInterface WMIInterface) (value string, err error) {
switch wmiInterface {
case wmic:
value, _, err = commandOutputHash(wmicCommand, "computersystem", "list", "brief")
case cimInstance:
propertiesToRetrieve := []string{"Domain", "Manufacturer", "Model", "Name", "PrimaryOwnerName", "TotalPhysicalMemory"}
value, _, err = commandOutputHash(appconfig.PowerShellPluginCommandName, getCimInstanceCmdArgs("Win32_ComputerSystem", propertiesToRetrieve...))
default:
logger.Warnf("Unknown WMI interface: %v", wmiInterface)
}

func systemInfoHash() (value string, err error) {
value, _, err = commandOutputHash(wmicCommand, "computersystem", "list", "brief")
return
}

func diskInfoHash(wmiInterface WMIInterface) (value string, err error) {
switch wmiInterface {
case wmic:
value, _, err = commandOutputHash(wmicCommand, "diskdrive", "list", "brief")
case cimInstance:
propertiesToRetrieve := []string{"Caption", "DeviceID", "Model", "Partitions", "Size"}
value, _, err = commandOutputHash(appconfig.PowerShellPluginCommandName, getCimInstanceCmdArgs("Win32_DiskDrive", propertiesToRetrieve...))
default:
logger.Warnf("Unknown WMI interface: %v", wmiInterface)
}

func diskInfoHash() (value string, err error) {
value, _, err = commandOutputHash(wmicCommand, "diskdrive", "list", "brief")
return
}

func getCimInstanceCmdArgs(className string, properties ...string) string {
var sb strings.Builder
sb.WriteString(fmt.Sprintf("Get-CimInstance -ClassName %s", className))
if len(properties) > 0 {
sb.WriteString(" | Select-Object ")
for _, property := range properties {
sb.WriteString(fmt.Sprintf("%s, ", property))
}
}

return fmt.Sprintf("%s | ConvertTo-Json", strings.TrimRight(sb.String(), ", "))
}
30 changes: 15 additions & 15 deletions agent/platform/platform_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"fmt"
"os"
"os/exec"
"path/filepath"
"regexp"
"strconv"
"strings"
Expand All @@ -29,11 +30,9 @@ import (
"github.com/aws/amazon-ssm-agent/agent/log"
)

const (
caption = "Caption"
version = "Version"
sku = "OperatingSystemSKU"
)
const caption = "Caption"
const version = "Version"
const sku = "OperatingSystemSKU"

// Win32_OperatingSystems https://msdn.microsoft.com/en-us/library/aa394239%28v=vs.85%29.aspx
const (
Expand Down Expand Up @@ -110,8 +109,8 @@ func getPlatformDetails(property string, log log.T) (value string, err error) {
log.Debugf(gettingPlatformDetailsMessage)
value = notAvailableMessage

cmdName := appconfig.PowerShellPluginCommandName
cmdArgs := []string{fmt.Sprintf("Get-CimInstance -ClassName Win32_OperatingSystem | Format-List -Property %s", property)}
cmdName := "wmic"
cmdArgs := []string{"OS", "get", property, "/format:list"}
var cmdOut []byte
if cmdOut, err = exec.Command(cmdName, cmdArgs...).Output(); err != nil {
log.Debugf("There was an error running %v %v, err:%v", cmdName, cmdArgs, err)
Expand All @@ -122,7 +121,7 @@ func getPlatformDetails(property string, log log.T) (value string, err error) {
value = strings.TrimSpace(string(cmdOut))

// Match whitespaces between property and = sign and remove whitespaces
rp := regexp.MustCompile(fmt.Sprintf("%v(\\s*)%v", property, ":"))
rp := regexp.MustCompile(fmt.Sprintf("%v(\\s*)%v", property, "="))
value = rp.ReplaceAllString(value, "")

// Trim spaces again
Expand All @@ -132,12 +131,14 @@ func getPlatformDetails(property string, log log.T) (value string, err error) {
return
}

var wmicCommand = filepath.Join(appconfig.EnvWinDir, "System32", "wbem", "wmic.exe")

// fullyQualifiedDomainName returns the Fully Qualified Domain Name of the instance, otherwise the hostname
func fullyQualifiedDomainName(log log.T) string {
hostName, _ := os.Hostname()

dnsHostName := getWMIComputerSystemValue("DNSHostName")
domainName := getWMIComputerSystemValue("Domain")
dnsHostName := getWMICComputerSystemValue("DNSHostName")
domainName := getWMICComputerSystemValue("Domain")

if dnsHostName == "" || domainName == "" {
return hostName
Expand All @@ -146,12 +147,11 @@ func fullyQualifiedDomainName(log log.T) string {
return dnsHostName + "." + domainName
}

// getWMIComputerSystemValue return the specified attribute from WMI via powershell
func getWMIComputerSystemValue(attribute string) string {
cmdArgs := []string{fmt.Sprintf("Get-CimInstance -Class Win32_ComputerSystem | Format-List -Property %s", attribute)}
if contentBytes, err := exec.Command(appconfig.PowerShellPluginCommandName, cmdArgs...).Output(); err == nil {
// getWMICComputerSystemValue return the value part of the wmic computersystem command for the specified attribute
func getWMICComputerSystemValue(attribute string) string {
if contentBytes, err := exec.Command(wmicCommand, "computersystem", "get", attribute, "/value").Output(); err == nil {
contents := string(contentBytes)
data := strings.Split(contents, ":")
data := strings.Split(contents, "=")
if len(data) > 1 {
return strings.TrimSpace(data[1])
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ package windows

import (
"fmt"
"os"
"os/exec"
"path/filepath"
"regexp"

"github.com/aws/amazon-ssm-agent/agent/appconfig"
"github.com/aws/amazon-ssm-agent/agent/log"

c "github.com/aws/amazon-ssm-agent/agent/plugins/configurepackage/envdetect/constants"
Expand Down Expand Up @@ -61,8 +62,9 @@ func isWindowsNano(operatingSystemSKU string) bool {
}

func getWmiOSInfo() (string, error) {
cmdArgs := []string{"Get-CimInstance -ClassName Win32_OperatingSystem | Format-List -Property OperatingSystemSKU, Version"}
cmdOut, err := exec.Command(appconfig.PowerShellPluginCommandName, cmdArgs...).Output()
wmicCommand := filepath.Join(os.Getenv("WINDIR"), "System32", "wbem", "wmic.exe")
cmdArgs := []string{"OS", "get", "/format:list"}
cmdOut, err := exec.Command(wmicCommand, cmdArgs...).Output()
if err != nil {
return "", err
}
Expand All @@ -79,7 +81,7 @@ func parseOperatingSystemSKU(wmioutput string) (string, error) {
}

func parseProperty(wmioutput string, property string) (string, error) {
regex := fmt.Sprintf(`(?m)^\s*%s\s*:\s*(\S+)\s*$`, property)
regex := fmt.Sprintf(`(?m)^\s*%s\s*=\s*(\S+)\s*$`, property)
re := regexp.MustCompile(regex)
match := re.FindStringSubmatch(wmioutput)

Expand Down
Loading

0 comments on commit a0adbe9

Please sign in to comment.