go.mondoo.com/cnquery@v0.0.0-20231005093811-59568235f6ea/providers/os/detector/windows/build_version.go (about) 1 // Copyright (c) Mondoo, Inc. 2 // SPDX-License-Identifier: BUSL-1.1 3 4 package windows 5 6 import ( 7 "encoding/json" 8 "fmt" 9 "io" 10 "regexp" 11 "strconv" 12 13 "go.mondoo.com/cnquery/providers/os/connection/shared" 14 "go.mondoo.com/cnquery/providers/os/resources/powershell" 15 ) 16 17 var WinBuildVersionRegex = regexp.MustCompile(`^(\d+)(?:\.(\d+)){0,1}`) 18 19 type BuildVersion struct { 20 Build int 21 UBR int 22 } 23 24 // WindowsVersion parses the version generated by motor 25 // It uses the format: major.minor.build.ubr 26 func Version(ver string) (*BuildVersion, error) { 27 // check that we go a valid windows version 28 m := WinBuildVersionRegex.FindStringSubmatch(ver) 29 if len(m) < 2 { 30 return nil, fmt.Errorf("the requested windows version is not supported: %s", ver) 31 } 32 33 build, err := strconv.Atoi(m[1]) 34 if err != nil { 35 return nil, err 36 } 37 38 var ubr int 39 if len(m) == 3 && len(m[2]) > 0 { 40 ubr, err = strconv.Atoi(m[2]) 41 if err != nil { 42 return nil, err 43 } 44 } 45 46 return &BuildVersion{ 47 Build: build, 48 UBR: ubr, 49 }, nil 50 } 51 52 func (b BuildVersion) OSBuild() string { 53 if b.UBR > 0 { 54 return fmt.Sprintf("%d.%d", b.Build, b.UBR) 55 } else { 56 return fmt.Sprintf("%d", b.Build) 57 } 58 } 59 60 type WindowsCurrentVersion struct { 61 CurrentBuild string `json:"CurrentBuild"` 62 EditionID string `json:"EditionID"` 63 ReleaseId string `json:"ReleaseId"` 64 // Update Build Revision 65 UBR int `json:"UBR"` 66 } 67 68 func ParseWinRegistryCurrentVersion(r io.Reader) (*WindowsCurrentVersion, error) { 69 data, err := io.ReadAll(r) 70 if err != nil { 71 return nil, err 72 } 73 74 var winCurrentVersion WindowsCurrentVersion 75 err = json.Unmarshal(data, &winCurrentVersion) 76 if err != nil { 77 return nil, err 78 } 79 80 return &winCurrentVersion, nil 81 } 82 83 // powershellGetWindowsOSBuild runs a powershell script to retrieve the current version from windows 84 func powershellGetWindowsOSBuild(conn shared.Connection) (*WindowsCurrentVersion, error) { 85 pscommand := "Get-ItemProperty -Path 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion' -Name CurrentBuild, UBR, EditionID | ConvertTo-Json" 86 cmd, err := conn.RunCommand(powershell.Wrap(pscommand)) 87 if err != nil { 88 return nil, err 89 } 90 return ParseWinRegistryCurrentVersion(cmd.Stdout) 91 }