go.mondoo.com/cnquery@v0.0.0-20231005093811-59568235f6ea/providers/os/detector/windows/wmi.go (about)

     1  // Copyright (c) Mondoo, Inc.
     2  // SPDX-License-Identifier: BUSL-1.1
     3  
     4  package windows
     5  
     6  import (
     7  	"encoding/csv"
     8  	"errors"
     9  	"io"
    10  	"strconv"
    11  
    12  	"github.com/rs/zerolog/log"
    13  	"go.mondoo.com/cnquery/providers-sdk/v1/util/linefeed"
    14  	"go.mondoo.com/cnquery/providers/os/connection/shared"
    15  )
    16  
    17  type WmicOSInformation struct {
    18  	BootDevice                                string
    19  	BuildNumber                               string
    20  	BuildType                                 string
    21  	Caption                                   string
    22  	CodeSet                                   string
    23  	CountryCode                               string
    24  	CreationClassName                         string
    25  	CSCreationClassName                       string
    26  	CSDVersion                                string
    27  	CSName                                    string
    28  	CurrentTimeZone                           string
    29  	DataExecutionPrevention_32BitApplications string
    30  	DataExecutionPrevention_Available         string
    31  	DataExecutionPrevention_Drivers           string
    32  	DataExecutionPrevention_SupportPolicy     string
    33  	Debug                                     string
    34  	Description                               string
    35  	Distributed                               string
    36  	EncryptionLevel                           string
    37  	ForegroundApplicationBoost                string
    38  	FreePhysicalMemory                        string
    39  	FreeSpaceInPagingFiles                    string
    40  	FreeVirtualMemory                         string
    41  	InstallDate                               string
    42  	LargeSystemCache                          string
    43  	LastBootUpTime                            string
    44  	LocalDateTime                             string
    45  	Locale                                    string
    46  	Manufacturer                              string
    47  	MaxNumberOfProcesses                      string
    48  	MaxProcessMemorySize                      string
    49  	MUILanguages                              string
    50  	Name                                      string
    51  	NumberOfLicensedUsers                     string
    52  	NumberOfProcesses                         string
    53  	NumberOfUsers                             string
    54  	OperatingSystemSKU                        string
    55  	Organization                              string
    56  	OSArchitecture                            string
    57  	OSLanguage                                string
    58  	OSProductSuite                            string
    59  	OSType                                    string
    60  	OtherTypeDescription                      string
    61  	PAEEnabled                                string
    62  	PlusProductID                             string
    63  	PlusVersionNumber                         string
    64  	PortableOperatingSystem                   string
    65  	Primary                                   string
    66  	ProductType                               string
    67  	RegisteredUser                            string
    68  	SerialNumber                              string
    69  	ServicePackMajorVersion                   string
    70  	ServicePackMinorVersion                   string
    71  	SizeStoredInPagingFiles                   string
    72  	Status                                    string
    73  	SuiteMask                                 string
    74  	SystemDevice                              string
    75  	SystemDirectory                           string
    76  	SystemDrive                               string
    77  	TotalSwapSpaceSize                        string
    78  	TotalVirtualMemorySize                    string
    79  	TotalVisibleMemorySize                    string
    80  	Version                                   string
    81  	WindowsDirectory                          string
    82  }
    83  
    84  func ParseWinWmicOS(csvData io.Reader) (*WmicOSInformation, error) {
    85  	reader := csv.NewReader(linefeed.NewLineFeedReader(csvData))
    86  	os := []*WmicOSInformation{}
    87  	header := map[string]int{}
    88  
    89  	i := -1 // to ensure counting starts at 0
    90  	for {
    91  		i++
    92  		line, err := reader.Read()
    93  		if err == io.EOF {
    94  			break
    95  		} else if err != nil {
    96  			log.Error().Err(err).Msg("could not read from wmic stream")
    97  		}
    98  
    99  		// store header index
   100  		if i == 0 {
   101  			for j, item := range line {
   102  				header[item] = j
   103  			}
   104  
   105  			if len(header) < 10 {
   106  				return nil, errors.New("unexpected wmic result")
   107  			}
   108  
   109  			continue
   110  		}
   111  
   112  		os = append(os, &WmicOSInformation{
   113  			Name:           line[header["Name"]],
   114  			Caption:        line[header["Caption"]],
   115  			Manufacturer:   line[header["Manufacturer"]],
   116  			OSArchitecture: line[header["OSArchitecture"]],
   117  			Version:        line[header["Version"]],
   118  			BuildNumber:    line[header["BuildNumber"]],
   119  			Description:    line[header["Description"]],
   120  			OSType:         line[header["OSType"]],
   121  
   122  			// 1 = Desktop OS
   123  			// 2 = Server OS – Domain Controller
   124  			// 3 = Server OS – Not a Domain Controller
   125  			ProductType: line[header["ProductType"]],
   126  		})
   127  
   128  	}
   129  
   130  	if len(os) == 1 {
   131  		return os[0], nil
   132  	} else {
   133  		return nil, errors.New("could not parse wmic, retrieved unexpected amount of rows " + strconv.Itoa(len(os)))
   134  	}
   135  }
   136  
   137  func powershellGetWmiInformation(conn shared.Connection) (*WmicOSInformation, error) {
   138  	// wmic is available since Windows Server 2008/Vista
   139  	command := "wmic os get * /format:csv"
   140  	cmd, err := conn.RunCommand(command)
   141  	if err != nil {
   142  		return nil, err
   143  	}
   144  
   145  	return ParseWinWmicOS(cmd.Stdout)
   146  }