go.mondoo.com/cnquery@v0.0.0-20231005093811-59568235f6ea/providers/os/resources/services/ps1getservice.go (about) 1 // Copyright (c) Mondoo, Inc. 2 // SPDX-License-Identifier: BUSL-1.1 3 4 package services 5 6 import ( 7 "encoding/json" 8 "io" 9 10 "go.mondoo.com/cnquery/providers/os/connection/shared" 11 "go.mondoo.com/cnquery/providers/os/resources/powershell" 12 ) 13 14 // WindowsService calls powershell Get-Service 15 // 16 // Get-Service | Select-Object -Property * 17 // Name : defragsvc 18 // RequiredServices : {RPCSS} 19 // CanPauseAndContinue : False 20 // CanShutdown : False 21 // CanStop : False 22 // DisplayName : Optimize drives 23 // DependentServices : {} 24 // MachineName : . 25 // ServiceName : defragsvc 26 // ServicesDependedOn : {RPCSS} 27 // ServiceHandle : SafeServiceHandle 28 // Status : Stopped 29 // ServiceType : Win32OwnProcess 30 // StartType : Manual 31 // Site : 32 // Container : 33 type WindowsService struct { 34 Status int 35 Name string 36 DisplayName string 37 StartType int 38 } 39 40 // State returns the State value for a Windows service 41 // 42 // int values of the services have the following values: 43 // 1: Stopped 44 // 2: Starting 45 // 3: Stopping 46 // 4: Running 47 // 5: Continue Pending 48 // 6: Pause Pending 49 // 7: Paused 50 // 51 // those are documented in https://msdn.microsoft.com/en-us/library/windows/desktop/ms685996(v=vs.85).aspx 52 func (s WindowsService) State() State { 53 res := ServiceUnknown 54 switch s.Status { 55 case 1: 56 res = ServiceStopped 57 case 2: 58 res = ServiceStartPending 59 case 3: 60 res = ServiceStopped 61 case 4: 62 res = ServiceRunning 63 case 5: 64 res = ServiceContinuePending 65 case 6: 66 res = ServicePausePending 67 case 7: 68 res = ServicePaused 69 } 70 return res 71 } 72 73 func (s WindowsService) IsRunning() bool { 74 return s.State() == ServiceRunning 75 } 76 77 // Modes are documented in https://docs.microsoft.com/en-us/dotnet/api/system.serviceprocess.servicestartmode?view=netframework-4.8 78 // NOTE: only newer powershell versions support this approach, we may need WMI fallback later 79 // see: https://mikefrobbins.com/2015/12/17/starttype-property-added-to-get-service-in-powershell-version-5-build-10586-on-windows-10-version-1511/ 80 // 0: Boot 81 // 1: System 82 // 2: Automatic 83 // 3: Manual 84 // 4: Disabled 85 func (s WindowsService) Enabled() bool { 86 if s.StartType <= 3 { 87 return true 88 } 89 return false 90 } 91 92 func (s WindowsService) Service() *Service { 93 return &Service{ 94 Name: s.Name, 95 Description: s.DisplayName, 96 Installed: true, 97 Running: s.IsRunning(), 98 Enabled: s.Enabled(), 99 State: s.State(), 100 Type: "windows", 101 } 102 } 103 104 func ParseWindowsService(r io.Reader) ([]*Service, error) { 105 data, err := io.ReadAll(r) 106 if err != nil { 107 return nil, err 108 } 109 110 var srvs []WindowsService 111 err = json.Unmarshal(data, &srvs) 112 if err != nil { 113 return nil, err 114 } 115 116 res := make([]*Service, len(srvs)) 117 for i := range srvs { 118 res[i] = srvs[i].Service() 119 } 120 121 return res, nil 122 } 123 124 type WindowsServiceManager struct { 125 conn shared.Connection 126 } 127 128 func (s *WindowsServiceManager) Name() string { 129 return "Windows Service Manager" 130 } 131 132 func (s *WindowsServiceManager) List() ([]*Service, error) { 133 c, err := s.conn.RunCommand(powershell.Wrap("Get-Service | Select-Object -Property Status, Name, DisplayName, StartType | ConvertTo-Json")) 134 if err != nil { 135 return nil, err 136 } 137 return ParseWindowsService(c.Stdout) 138 }