@@ -110,142 +110,142 @@ function Update-ServiceStatus {
110110 $cimObject = $service._CimObject
111111 if (($cimObject.State -eq " Running" -and $action -eq " start" ) -or ($cimObject.State -eq " Stopped" -and $action -eq " stop" )) {
112112 $service | Add-Member - Force - NotePropertyName Status - NotePropertyValue " Successful" - PassThru |
113- Add-Member - Force - NotePropertyName Message - NotePropertyValue " The service is already $actionText , no action required" - PassThru
114- } elseif ($cimObject.StartMode -eq " Disabled" -and $action -in " start" , " restart" ) {
115- $service | Add-Member - Force - NotePropertyName Status - NotePropertyValue " Failed" - PassThru |
116- Add-Member - Force - NotePropertyName Message - NotePropertyValue " The service is disabled and cannot be $actionText " - PassThru
117- } else {
118- $servicesToRestart += $service
113+ Add-Member - Force - NotePropertyName Message - NotePropertyValue " The service is already $actionText , no action required" - PassThru
114+ } elseif ($cimObject.StartMode -eq " Disabled" -and $action -in " start" , " restart" ) {
115+ $service | Add-Member - Force - NotePropertyName Status - NotePropertyValue " Failed" - PassThru |
116+ Add-Member - Force - NotePropertyName Message - NotePropertyValue " The service is disabled and cannot be $actionText " - PassThru
117+ } else {
118+ $servicesToRestart += $service
119+ }
120+ } else {
121+ throw " Unknown object in pipeline - make sure to use Get-DbaService cmdlet"
122+ }
119123 }
120- } else {
121- throw " Unknown object in pipeline - make sure to use Get-DbaService cmdlet"
122- }
123- }
124- # Set desired $action
125- if ($action -in " start" , " restart" ) {
126- $methodName = " StartService"
127- $desiredState = " Running"
128- $undesiredState = " Stopped"
129- } elseif ($action -eq " stop" ) {
130- $methodName = " StopService"
131- $desiredState = " Stopped"
132- $undesiredState = " Running"
133- }
134- $invokeResults = @ ()
135- foreach ($service in $servicesToRestart ) {
136- if ($Pscmdlet.ShouldProcess (" Sending $action request to service $ ( $service.ServiceName ) on $ ( $service.ComputerName ) " )) {
137- # Get a fresh CIM instance via the DCOM session to avoid issues with deserialized
138- # CIM objects crossing runspace boundaries without their session context.
139- if ($cimSession ) {
140- try {
141- $splatGetFreshCim = @ {
142- CimSession = $cimSession
143- Namespace = " root\cimv2"
144- Query = " SELECT * FROM Win32_Service WHERE Name = '$ ( $service.ServiceName ) '"
124+ # Set desired $action
125+ if ($action -in " start" , " restart" ) {
126+ $methodName = " StartService"
127+ $desiredState = " Running"
128+ $undesiredState = " Stopped"
129+ } elseif ($action -eq " stop" ) {
130+ $methodName = " StopService"
131+ $desiredState = " Stopped"
132+ $undesiredState = " Running"
133+ }
134+ $invokeResults = @ ()
135+ foreach ($service in $servicesToRestart ) {
136+ if ($Pscmdlet.ShouldProcess (" Sending $action request to service $ ( $service.ServiceName ) on $ ( $service.ComputerName ) " )) {
137+ # Get a fresh CIM instance via the DCOM session to avoid issues with deserialized
138+ # CIM objects crossing runspace boundaries without their session context.
139+ if ($cimSession ) {
140+ try {
141+ $splatGetFreshCim = @ {
142+ CimSession = $cimSession
143+ Namespace = " root\cimv2"
144+ Query = " SELECT * FROM Win32_Service WHERE Name = '$ ( $service.ServiceName ) '"
145+ }
146+ $freshCimObj = Get-CimInstance @splatGetFreshCim
147+ if ($freshCimObj ) {
148+ $service._CimObject = $freshCimObj
149+ }
150+ } catch {
151+ # Fall back to using the existing deserialized CIM object if session refresh fails
152+ }
145153 }
146- $freshCimObj = Get-CimInstance @splatGetFreshCim
147- if ($freshCimObj ) {
148- $service._CimObject = $freshCimObj
154+ # Invoke corresponding CIM method
155+ $invokeResult = Invoke-CimMethod - InputObject $service._CimObject - MethodName $methodName
156+ $invokeResults += [psobject ]@ {
157+ InvokeResult = $invokeResult
158+ ServiceState = $invokeResult.State
159+ ServiceExitCode = $invokeResult.ReturnValue
160+ CheckPending = $true
161+ Service = $service
149162 }
150- } catch {
151- # Fall back to using the existing deserialized CIM object if session refresh fails
152163 }
153164 }
154- # Invoke corresponding CIM method
155- $invokeResult = Invoke-CimMethod - InputObject $service._CimObject - MethodName $methodName
156- $invokeResults += [psobject ]@ {
157- InvokeResult = $invokeResult
158- ServiceState = $invokeResult.State
159- ServiceExitCode = $invokeResult.ReturnValue
160- CheckPending = $true
161- Service = $service
162- }
163- }
164- }
165165
166- $startTime = Get-Date
167- if ($Pscmdlet.ShouldProcess (" Waiting the services to $action on $computerName " )) {
168- # Wait for the service to complete the action until timeout
169- while ($invokeResults.CheckPending -contains $true ) {
170- foreach ($result in ($invokeResults | Where-Object CheckPending -eq $true )) {
171- try {
172- # Refresh Cim instance - not using Get-DbaCmObject because module is not loaded here, but it only refreshes existing object
173- if ($cimSession ) {
174- $splatRefreshCim = @ {
175- CimSession = $cimSession
176- Namespace = " root\cimv2"
177- Query = " SELECT State FROM Win32_Service WHERE Name = '$ ( $result.Service.ServiceName ) '"
166+ $startTime = Get-Date
167+ if ($Pscmdlet.ShouldProcess (" Waiting the services to $action on $computerName " )) {
168+ # Wait for the service to complete the action until timeout
169+ while ($invokeResults.CheckPending -contains $true ) {
170+ foreach ($result in ($invokeResults | Where-Object CheckPending -eq $true )) {
171+ try {
172+ # Refresh Cim instance - not using Get-DbaCmObject because module is not loaded here, but it only refreshes existing object
173+ if ($cimSession ) {
174+ $splatRefreshCim = @ {
175+ CimSession = $cimSession
176+ Namespace = " root\cimv2"
177+ Query = " SELECT State FROM Win32_Service WHERE Name = '$ ( $result.Service.ServiceName ) '"
178+ }
179+ $refreshedCimObj = Get-CimInstance @splatRefreshCim
180+ if ($refreshedCimObj ) {
181+ $result.Service._CimObject = $refreshedCimObj
182+ }
183+ } else {
184+ $result.Service._CimObject = $result.Service._CimObject | Get-CimInstance
185+ }
186+ } catch {
187+ $result.ServiceExitCode = -3
188+ $result.ServiceState = " Unknown"
189+ $result.CheckPending = $false
190+ continue
178191 }
179- $refreshedCimObj = Get-CimInstance @splatRefreshCim
180- if ($refreshedCimObj ) {
181- $result.Service._CimObject = $refreshedCimObj
192+ $result.ServiceState = $result.Service._CimObject.State
193+ # Failed or succeeded
194+ if ($result.ServiceExitCode -ne 0 -or $result.ServiceState -eq $desiredState ) {
195+ $result.CheckPending = $false
196+ continue
182197 }
183- } else {
184- $result.Service._CimObject = $result.Service._CimObject | Get-CimInstance
198+ # Failed after being in the Pending state
199+ if ($result.CheckPending -and $result.ServiceState -eq $undesiredState ) {
200+ $result.ServiceExitCode = -2
201+ $result.CheckPending = $false
202+ continue
203+ }
204+ # Timed out
205+ if ($timeout -gt 0 -and ((Get-Date ) - $startTime ).TotalSeconds -gt $timeout ) {
206+ $result.ServiceExitCode = -1
207+ $result.CheckPending = $false
208+ continue
209+ }
210+ # Still pending - leave CheckPending as is and run again
185211 }
186- } catch {
187- $result.ServiceExitCode = -3
188- $result.ServiceState = " Unknown"
189- $result.CheckPending = $false
190- continue
212+ Start-Sleep - Milliseconds 200
191213 }
192- $result.ServiceState = $result.Service._CimObject.State
193- # Failed or succeeded
194- if ($result.ServiceExitCode -ne 0 -or $result.ServiceState -eq $desiredState ) {
195- $result.CheckPending = $false
196- continue
197- }
198- # Failed after being in the Pending state
199- if ($result.CheckPending -and $result.ServiceState -eq $undesiredState ) {
200- $result.ServiceExitCode = -2
201- $result.CheckPending = $false
202- continue
214+ }
215+ foreach ($result in $invokeResults ) {
216+ # Add status
217+ $status = switch ($result.ServiceExitCode ) {
218+ 0 { " Successful" }
219+ 10 { " Successful " } # Already running - FullText service is started automatically
220+ default { " Failed" }
203221 }
204- # Timed out
205- if ($timeout -gt 0 -and ((Get-Date ) - $startTime ).TotalSeconds -gt $timeout ) {
206- $result.ServiceExitCode = -1
207- $result.CheckPending = $false
208- continue
222+ Add-Member - Force - InputObject $result.Service - NotePropertyName Status - NotePropertyValue $status
223+ # Add error message
224+ $errorMessageFromReturnValue = if ($result.ServiceExitCode -in 0 .. ($errorCodes.Length - 1 )) {
225+ $errorCodes [$result.ServiceExitCode ]
226+ } else { " Unknown error." }
227+ $message = switch ($result.ServiceExitCode ) {
228+ -2 { " The service failed to $action ." }
229+ -1 { " The attempt to $action the service has timed out." }
230+ 0 { " Service was successfully $actionText ." }
231+ default { " The attempt to $action the service returned the following error: $errorMessageFromReturnValue " }
209232 }
210- # Still pending - leave CheckPending as is and run again
233+ Add-Member - Force - InputObject $result.Service - NotePropertyName Message - NotePropertyValue $message
234+ # Refresh service state for the object
235+ if ($result.ServiceState ) { $result.Service.State = $result.ServiceState }
236+ $result
211237 }
212- Start-Sleep - Milliseconds 200
213- }
214- }
215- foreach ($result in $invokeResults ) {
216- # Add status
217- $status = switch ($result.ServiceExitCode ) {
218- 0 { " Successful" }
219- 10 { " Successful " } # Already running - FullText service is started automatically
220- default { " Failed" }
221238 }
222- Add-Member - Force - InputObject $result.Service - NotePropertyName Status - NotePropertyValue $status
223- # Add error message
224- $errorMessageFromReturnValue = if ($result.ServiceExitCode -in 0 .. ($errorCodes.Length - 1 )) {
225- $errorCodes [$result.ServiceExitCode ]
226- } else { " Unknown error." }
227- $message = switch ($result.ServiceExitCode ) {
228- -2 { " The service failed to $action ." }
229- -1 { " The attempt to $action the service has timed out." }
230- 0 { " Service was successfully $actionText ." }
231- default { " The attempt to $action the service returned the following error: $errorMessageFromReturnValue " }
239+ } finally {
240+ if ($cimSession ) {
241+ Remove-CimSession - CimSession $cimSession - ErrorAction " SilentlyContinue"
232242 }
233- Add-Member - Force - InputObject $result.Service - NotePropertyName Message - NotePropertyValue $message
234- # Refresh service state for the object
235- if ($result.ServiceState ) { $result.Service.State = $result.ServiceState }
236- $result
237243 }
238244 }
239- } finally {
240- if ($cimSession ) {
241- Remove-CimSession - CimSession $cimSession - ErrorAction " SilentlyContinue"
242- }
243- }
244- }
245245
246- $actionText = switch ($action ) { stop { ' stopped' }; start { ' started' }; restart { ' restarted' } }
247- $errorCodes = Get-DbaServiceErrorMessage
248- }
246+ $actionText = switch ($action ) { stop { ' stopped' }; start { ' started' }; restart { ' restarted' } }
247+ $errorCodes = Get-DbaServiceErrorMessage
248+ }
249249
250250process {
251251 # Group services for each computer
0 commit comments