-
Notifications
You must be signed in to change notification settings - Fork 8.3k
Get-Service Ignore common errors #24245
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -610,146 +610,160 @@ public string[] Name | |
| /// </summary> | ||
| protected override void ProcessRecord() | ||
| { | ||
| foreach (ServiceController service in MatchingServices()) | ||
| nint scManagerHandle = nint.Zero; | ||
| if (!DependentServices && !RequiredServices) | ||
| { | ||
| if (!DependentServices.IsPresent && !RequiredServices.IsPresent) | ||
| { | ||
| WriteObject(AddProperties(service)); | ||
| // As Get-Service only works on local services we get this once | ||
| // to retrieve extra properties added by PowerShell. | ||
| scManagerHandle = NativeMethods.OpenSCManagerW( | ||
| lpMachineName: null, | ||
| lpDatabaseName: null, | ||
| dwDesiredAccess: NativeMethods.SC_MANAGER_CONNECT); | ||
| if (scManagerHandle == nint.Zero) | ||
| { | ||
| Win32Exception exception = new(); | ||
| string message = StringUtil.Format(ServiceResources.FailToOpenServiceControlManager, exception.Message); | ||
| ServiceCommandException serviceException = new ServiceCommandException(message, exception); | ||
| ErrorRecord err = new ErrorRecord( | ||
| serviceException, | ||
| "FailToOpenServiceControlManager", | ||
| ErrorCategory.PermissionDenied, | ||
| null); | ||
| ThrowTerminatingError(err); | ||
| } | ||
| else | ||
| } | ||
|
|
||
| try | ||
| { | ||
| foreach (ServiceController service in MatchingServices()) | ||
| { | ||
| if (DependentServices.IsPresent) | ||
| if (!DependentServices.IsPresent && !RequiredServices.IsPresent) | ||
| { | ||
| foreach (ServiceController dependantserv in service.DependentServices) | ||
| WriteObject(AddProperties(scManagerHandle, service)); | ||
| } | ||
| else | ||
| { | ||
| if (DependentServices.IsPresent) | ||
| { | ||
| WriteObject(dependantserv); | ||
| foreach (ServiceController dependantserv in service.DependentServices) | ||
| { | ||
| WriteObject(dependantserv); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| if (RequiredServices.IsPresent) | ||
| { | ||
| foreach (ServiceController servicedependedon in service.ServicesDependedOn) | ||
| if (RequiredServices.IsPresent) | ||
| { | ||
| WriteObject(servicedependedon); | ||
| foreach (ServiceController servicedependedon in service.ServicesDependedOn) | ||
| { | ||
| WriteObject(servicedependedon); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| finally | ||
| { | ||
| if (scManagerHandle != nint.Zero) | ||
| { | ||
| bool succeeded = NativeMethods.CloseServiceHandle(scManagerHandle); | ||
| Diagnostics.Assert(succeeded, "SCManager handle close failed"); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| #endregion Overrides | ||
|
|
||
| #nullable enable | ||
| /// <summary> | ||
| /// Adds UserName, Description, BinaryPathName, DelayedAutoStart and StartupType to a ServiceController object. | ||
| /// </summary> | ||
| /// <param name="scManagerHandle">Handle to the local SCManager instance.</param> | ||
| /// <param name="service"></param> | ||
| /// <returns>ServiceController as PSObject with UserName, Description and StartupType added.</returns> | ||
| private PSObject AddProperties(ServiceController service) | ||
| private static PSObject AddProperties(nint scManagerHandle, ServiceController service) | ||
| { | ||
| NakedWin32Handle hScManager = IntPtr.Zero; | ||
| NakedWin32Handle hService = IntPtr.Zero; | ||
| int lastError = 0; | ||
| PSObject serviceAsPSObj = PSObject.AsPSObject(service); | ||
|
|
||
| // As these are optional values, a failure due to permissions or | ||
| // other problem is ignored and the properties are set to null. | ||
| bool isDelayedAutoStart = false; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does it make sense to have the default value for
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I can make it nullable, it just means that we would need to decide how
The former is simpler but it may not be true if the service is truly automatic but delayed and we couldn't get the correct result.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Given that
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Has been updated to keep it as
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
| string? binPath = null; | ||
| string? description = null; | ||
| string? startName = null; | ||
| ServiceStartupType startupType = ServiceStartupType.InvalidValue; | ||
| try | ||
| { | ||
| hScManager = NativeMethods.OpenSCManagerW( | ||
| lpMachineName: service.MachineName, | ||
| lpDatabaseName: null, | ||
| dwDesiredAccess: NativeMethods.SC_MANAGER_CONNECT | ||
| ); | ||
| if (hScManager == IntPtr.Zero) | ||
| { | ||
| lastError = Marshal.GetLastWin32Error(); | ||
| Win32Exception exception = new(lastError); | ||
| WriteNonTerminatingError( | ||
| service, | ||
| exception, | ||
| "FailToOpenServiceControlManager", | ||
| ServiceResources.FailToOpenServiceControlManager, | ||
| ErrorCategory.PermissionDenied); | ||
| } | ||
|
|
||
| // We don't use service.ServiceHandle as that requests | ||
| // SERVICE_ALL_ACCESS when we only need SERVICE_QUERY_CONFIG. | ||
| hService = NativeMethods.OpenServiceW( | ||
| hScManager, | ||
| scManagerHandle, | ||
| service.ServiceName, | ||
| NativeMethods.SERVICE_QUERY_CONFIG | ||
| ); | ||
| if (hService == IntPtr.Zero) | ||
| if (hService != nint.Zero) | ||
| { | ||
| lastError = Marshal.GetLastWin32Error(); | ||
| Win32Exception exception = new(lastError); | ||
| WriteNonTerminatingError( | ||
| service, | ||
| exception, | ||
| "CouldNotGetServiceInfo", | ||
| ServiceResources.CouldNotGetServiceInfo, | ||
| ErrorCategory.PermissionDenied); | ||
| } | ||
|
|
||
| NativeMethods.SERVICE_DESCRIPTIONW description = new(); | ||
| bool querySuccessful = NativeMethods.QueryServiceConfig2<NativeMethods.SERVICE_DESCRIPTIONW>(hService, NativeMethods.SERVICE_CONFIG_DESCRIPTION, out description); | ||
|
|
||
| NativeMethods.SERVICE_DELAYED_AUTO_START_INFO autostartInfo = new(); | ||
| querySuccessful = querySuccessful && NativeMethods.QueryServiceConfig2<NativeMethods.SERVICE_DELAYED_AUTO_START_INFO>(hService, NativeMethods.SERVICE_CONFIG_DELAYED_AUTO_START_INFO, out autostartInfo); | ||
| if (NativeMethods.QueryServiceConfig2( | ||
| hService, | ||
| NativeMethods.SERVICE_CONFIG_DESCRIPTION, | ||
| out NativeMethods.SERVICE_DESCRIPTIONW descriptionInfo)) | ||
| { | ||
| description = descriptionInfo.lpDescription; | ||
| } | ||
|
|
||
| NativeMethods.QUERY_SERVICE_CONFIG serviceInfo = new(); | ||
| querySuccessful = querySuccessful && NativeMethods.QueryServiceConfig(hService, out serviceInfo); | ||
| if (NativeMethods.QueryServiceConfig2( | ||
| hService, | ||
| NativeMethods.SERVICE_CONFIG_DELAYED_AUTO_START_INFO, | ||
| out NativeMethods.SERVICE_DELAYED_AUTO_START_INFO autostartInfo)) | ||
| { | ||
| isDelayedAutoStart = autostartInfo.fDelayedAutostart; | ||
| } | ||
|
|
||
| if (!querySuccessful) | ||
| { | ||
| WriteNonTerminatingError( | ||
| service: service, | ||
| innerException: null, | ||
| errorId: "CouldNotGetServiceInfo", | ||
| errorMessage: ServiceResources.CouldNotGetServiceInfo, | ||
| category: ErrorCategory.PermissionDenied | ||
| ); | ||
| if (NativeMethods.QueryServiceConfig( | ||
| hService, | ||
| out NativeMethods.QUERY_SERVICE_CONFIG serviceInfo)) | ||
| { | ||
| binPath = serviceInfo.lpBinaryPathName; | ||
| startName = serviceInfo.lpServiceStartName; | ||
| startupType = NativeMethods.GetServiceStartupType( | ||
|
daxian-dbw marked this conversation as resolved.
Outdated
|
||
| (ServiceStartMode)serviceInfo.dwStartType, | ||
| isDelayedAutoStart); | ||
| } | ||
| } | ||
|
|
||
| PSProperty noteProperty = new("UserName", serviceInfo.lpServiceStartName); | ||
| serviceAsPSObj.Properties.Add(noteProperty, true); | ||
| serviceAsPSObj.TypeNames.Insert(0, "System.Service.ServiceController#UserName"); | ||
|
|
||
| noteProperty = new PSProperty("Description", description.lpDescription); | ||
| serviceAsPSObj.Properties.Add(noteProperty, true); | ||
| serviceAsPSObj.TypeNames.Insert(0, "System.Service.ServiceController#Description"); | ||
|
|
||
| noteProperty = new PSProperty("DelayedAutoStart", autostartInfo.fDelayedAutostart); | ||
| serviceAsPSObj.Properties.Add(noteProperty, true); | ||
| serviceAsPSObj.TypeNames.Insert(0, "System.Service.ServiceController#DelayedAutoStart"); | ||
|
|
||
| noteProperty = new PSProperty("BinaryPathName", serviceInfo.lpBinaryPathName); | ||
| serviceAsPSObj.Properties.Add(noteProperty, true); | ||
| serviceAsPSObj.TypeNames.Insert(0, "System.Service.ServiceController#BinaryPathName"); | ||
|
|
||
| noteProperty = new PSProperty("StartupType", NativeMethods.GetServiceStartupType(service.StartType, autostartInfo.fDelayedAutostart)); | ||
| serviceAsPSObj.Properties.Add(noteProperty, true); | ||
| serviceAsPSObj.TypeNames.Insert(0, "System.Service.ServiceController#StartupType"); | ||
| } | ||
| finally | ||
| { | ||
| if (hService != IntPtr.Zero) | ||
| { | ||
| bool succeeded = NativeMethods.CloseServiceHandle(hService); | ||
| if (!succeeded) | ||
| { | ||
| Diagnostics.Assert(lastError != 0, "ErrorCode not success"); | ||
| } | ||
| } | ||
|
|
||
| if (hScManager != IntPtr.Zero) | ||
| { | ||
| bool succeeded = NativeMethods.CloseServiceHandle(hScManager); | ||
| if (!succeeded) | ||
| { | ||
| Diagnostics.Assert(lastError != 0, "ErrorCode not success"); | ||
| } | ||
| Diagnostics.Assert(succeeded, "Failed to close service handle"); | ||
| } | ||
| } | ||
|
|
||
| PSObject serviceAsPSObj = PSObject.AsPSObject(service); | ||
| PSNoteProperty noteProperty = new("UserName", startName); | ||
| serviceAsPSObj.Properties.Add(noteProperty, true); | ||
| serviceAsPSObj.TypeNames.Insert(0, "System.Service.ServiceController#UserName"); | ||
|
|
||
| noteProperty = new PSNoteProperty("Description", description); | ||
| serviceAsPSObj.Properties.Add(noteProperty, true); | ||
| serviceAsPSObj.TypeNames.Insert(0, "System.Service.ServiceController#Description"); | ||
|
|
||
| noteProperty = new PSNoteProperty("DelayedAutoStart", isDelayedAutoStart); | ||
| serviceAsPSObj.Properties.Add(noteProperty, true); | ||
| serviceAsPSObj.TypeNames.Insert(0, "System.Service.ServiceController#DelayedAutoStart"); | ||
|
|
||
| noteProperty = new PSNoteProperty("BinaryPathName", binPath); | ||
| serviceAsPSObj.Properties.Add(noteProperty, true); | ||
| serviceAsPSObj.TypeNames.Insert(0, "System.Service.ServiceController#BinaryPathName"); | ||
|
|
||
| noteProperty = new PSNoteProperty("StartupType", startupType); | ||
| serviceAsPSObj.Properties.Add(noteProperty, true); | ||
| serviceAsPSObj.TypeNames.Insert(0, "System.Service.ServiceController#StartupType"); | ||
|
daxian-dbw marked this conversation as resolved.
Outdated
|
||
|
|
||
| return serviceAsPSObj; | ||
| } | ||
| } | ||
| #nullable disable | ||
| #endregion GetServiceCommand | ||
|
|
||
| #region ServiceOperationBaseCommand | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.