PowerShell / PowerShell

PowerShell for every system!
https://microsoft.com/PowerShell
MIT License
44.61k stars 7.22k forks source link

Some drivers throw an exception when fetched with Get-Service, but still return the object anyway #10371

Open irisxzhou opened 5 years ago

irisxzhou commented 5 years ago

Steps to reproduce

Run in elevated PowerShell prompt:

Get-Service -Name msquic

If not run in an elevated prompt, no object is returned in PS6/7, and only the exception is shown. In PS5, the object is returned and there is no exception.

Expected behavior

From PowerShell 5:


Status   Name               DisplayName
------   ----               -----------
Running  MsQuic             msquic

Actual behavior

From PowerShell 6.2 and 7:

get-service : Service 'MsQuic (MsQuic)' cannot be queried due to the following error:
At line:1 char:1
+ get-service -name msquic
+ ~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : PermissionDenied: (System.ServiceProcess.ServiceController:ServiceController) [Get-Service], ServiceCommandException
+ FullyQualifiedErrorId : CouldNotGetServiceInfo,Microsoft.PowerShell.Commands.GetServiceCommand

Status   Name               DisplayName
------   ----               -----------
Running  MsQuic             MsQuic

Environment data

PowerShell 6.2:

Name                           Value
----                           -----
PSVersion                      6.2.1
PSEdition                      Core
GitCommitId                    6.2.1
OS                             Microsoft Windows 10.0.18956
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

PowerShell 7:

Name                           Value
----                           -----
PSVersion                      7.0.0-preview.1
PSEdition                      Core
GitCommitId                    7.0.0-preview.1
OS                             Microsoft Windows 10.0.18956
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0
iSazonov commented 5 years ago

What is MsQuic? How could we install it? Maybe you know another repo scenario?

irisxzhou commented 5 years ago

MsQuic is a driver. The way that I obtained it is by first getting a list of drivers, then iterating through their names with Get-Service, as follows:

$drivers = Get-CimInstance win32_SystemDriver
foreach ($driver in $drivers) 
{
    $svcObj = Get-Service -Name $driver.Name 
}

When I do this, then I get a few drivers on my computer that return the same error (MsQuic is just the first one for me). If I say

$svcObj = Get-Service -Name $driver.Name -ErrorAction -SilentlyContinue

we can bypass that problem and access the driver objects that throw exceptions, because the correct object is still returned, but in that case it just seems like the exception is wrong.

iSazonov commented 5 years ago

I can repo with


Get-Service -Name WinQuic
Get-Service : Service 'WinQuic (WinQuic)' cannot be queried due to the following error:
At line:1 char:1
+ Get-Service -Name WinQuic
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : PermissionDenied: (System.ServiceProcess.ServiceController:ServiceController) [Get-Service], ServiceCommandException
+ FullyQualifiedErrorId : CouldNotGetServiceInfo,Microsoft.PowerShell.Commands.GetServiceCommand

Status   Name               DisplayName
------   ----               -----------
Running  WinQuic            WinQuic

PS > $error[0] | fl * -Force

PSMessageDetails      :
Exception             : Microsoft.PowerShell.Commands.ServiceCommandException: Service 'WinQuic (WinQuic)' cannot be qu
                        eried due to the following error:
TargetObject          : WinQuic
CategoryInfo          : PermissionDenied: (System.ServiceProcess.ServiceController:ServiceController) [Get-Service], Se
                        rviceCommandException
FullyQualifiedErrorId : CouldNotGetServiceInfo,Microsoft.PowerShell.Commands.GetServiceCommand
ErrorDetails          :
InvocationInfo        : System.Management.Automation.InvocationInfo
ScriptStackTrace      : at <ScriptBlock>, <No file>: line 1
PipelineIterationInfo : {0, 1}
iSazonov commented 5 years ago

/cc @daxian-dbw @bergmeister @SteveL-MSFT It seems it is again an issue with ServiceController. Should we report in CoreFX repo?

KalleOlaviNiemitalo commented 5 years ago

In PowerShell Core 6.2.0, I get two errors, whether elevated or not:

get-service : Service 'WinQuic (WinQuic)' cannot be queried due to the following error:
At line:1 char:1
+ get-service -name winquic
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : PermissionDenied: (System.ServiceProcess.ServiceController:ServiceController) [Get-Service], ServiceCommandException
+ FullyQualifiedErrorId : CouldNotGetServiceInfo,Microsoft.PowerShell.Commands.GetServiceCommand

The first error above is reported by Microsoft.PowerShell.Commands.GetServiceCommand.AddProperties after its QueryServiceConfig2 call returns false and sets Win32 error 15100 "The resource loader failed to find MUI file". This error has ErrorCategory.PermissionDenied even though permission was not denied.

get-service : The resource loader failed to find MUI file
At line:1 char:1
+ get-service -name winquic
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : NotSpecified: (:) [Get-Service], Win32Exception
+ FullyQualifiedErrorId : System.ComponentModel.Win32Exception,Microsoft.PowerShell.Commands.GetServiceCommand

The second error above comes from a Win32Exception thrown by System.ServiceProcess.ServiceController.get_StartType after its QueryServiceConfig call returns false and sets Win32 error 15100 "The resource loader failed to find MUI file".

Process Monitor shows that [HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\WinQuic] "DisplayName" is "@%SystemRoot%\system32\drivers\winquic.sys,-1" and "Description" is "@%SystemRoot%\system32\drivers\winquic.sys,-2". services.exe tries to access "C:\Windows\System32\drivers\winquic.sys" (success, but apparently lacks the resources), "C:\WINDOWS\system32\SystemResources\winquic.sys.mun" (directory does not exist), "C:\Windows\System32\drivers\en-US\winquic.sys.mui" (file does not exist), and "C:\WINDOWS\system32\drivers\en\winquic.sys.mui" (directory does not exist).

Get-Service -Name SshdBroker triggers similar errors.

Even if CoreFX fixes ServiceController… although I am not sure how it can be fixed, since QueryServiceConfig is failing… it seems the ErrorCategory.PermissionDenied should still be corrected at the PowerShell side.

SteveL-MSFT commented 5 years ago

The problem is actually here: https://github.com/PowerShell/PowerShell/blob/master/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs#L677

The cmdlet fails at querying some information and writes a non-terminating error. This doesn't happen in Windows PowerShell because these are actually additional note properties being added. Seems like the right thing to do is just to not emit the non-terminating error at all and doc that some of these properties will be $null if they cannot be retrieved.

GitHub
PowerShell/PowerShell
PowerShell for every system! Contribute to PowerShell/PowerShell development by creating an account on GitHub.
iSazonov commented 5 years ago

not emit the non-terminating error

How does an user know that a property cannot be read? I believe the non-terminating error is right thing in the case.

jhoneill commented 5 years ago

I get this issue with ssd-broker service from Open-ssh . Fine in Windows PowerShell ; error in 6/7

get-service : Service 'SshdBroker (SshdBroker)' cannot be queried due to the following error:
At line:1 char:1
+ get-service
+ ~~~~~~~~~~~
+ CategoryInfo          : PermissionDenied: (System.ServiceProcess.ServiceController:ServiceController) [Get-Service], ServiceCommandException
+ FullyQualifiedErrorId : CouldNotGetServiceInfo,Microsoft.PowerShell.Commands.GetServiceCommand

So it appears to be more than drivers. (It also may be an easier one to test with).

joeyaiello commented 5 years ago

Not sure which OpenSSH you're talking about, using the built-in one in Windows 10 I only have sshd and ssh-agent, and they both work fine.

As others have said, my take is that if we fail to retrieve a property, it's perfectly fine to emit a non-terminating error as long as we still emit what we were able to retrieve.

Is it also possibly the case that we're trying to retrieve more properties than Windows PowerShell did, and that's why we're hitting this now?

SteveL-MSFT commented 5 years ago

@iSazonov there are other cases where failure to retrieve specific information simply has that property be $null without emitting any error

daxian-dbw commented 5 years ago

get-service : Service 'MsQuic (MsQuic)' cannot be queried due to the following error: At line:1 char:1

At least the error message needs to be updated.

jhoneill commented 5 years ago

@joeyaiello

Not sure which OpenSSH you're talking about, using the built-in one in Windows 10 I only have sshd and ssh-agent, and they both work fine.

I'm not sure how I've configured mine differently, but I don't think it was delivered in Windows (the EXE files are not signed, and have no copyright notice. But when I look in the Services GUI I get this in the description box. Failed to Read Description. Error Code: 15100

15100 is The resource loader failed to find MUI file, so it looks like it should be loading a language specific description and can't find it. (en-GB instead of en-US ? who knows).

As others have said, my take is that if we fail to retrieve a property, it's perfectly fine to emit a non-terminating error as long as we still emit what we were able to retrieve.

My first reaction was NO! But having seen that services has ERROR in the the description, I've changed to "yeah, OK, that's what happens elsewhere". The other information IS returned, so that's OK. I was anti-producing an error because it caused a pester test I had to fail (get-service was get-anyRandomData) and including -errorAction fixes that.

Is it also possibly the case that we're trying to retrieve more properties than Windows PowerShell did, and that's why we're hitting this now?

Yep. Windows PowerShell does not get the description. So no error. A quick reg hack will probably fix the description.

joeyaiello commented 5 years ago

@jhoneill We had the discussion last week in the @PowerShell/powershell-committee and we agree that there is differing behavior between cmdlets in throwing non-terminating errors vs. just blanking the information that can't be retrieved. For instance, there's a (maybe bug, maybe by-design) behavior in Get-Process on macOS where Get-Process can't always retrieve the name of a process. Today, we just return what we can get (like the PID) and we return the process name as $null.

However, we may not need to make a broad call on that, as I believe @JamesWTruher is investigating whether there's just a bug here we can fix.

jhoneill commented 5 years ago

@joeyaiello Yes, that makes sense. This seems an odd case where other things in Windows were saying "error." when anything tried to read the description of that service (a reg hack did make it go away - there was an invalid reference to a resource in a DLL), I think if reading something causes an error reporting that error is better than swallowing it. If something is unexpectedly blank when the OS returns it's better to roll with it rather than "What no process name ! I'm chucking an error"

SteveL-MSFT commented 5 years ago

@PowerShell/powershell-committee reviewed this, we agree that if a property value cannot be retrieved, then suppressing the error will be a better user experience. If an entire object cannot be retrieved, then a non-terminating error is appropriate (with a good error message).

mattcargile commented 1 year ago

FYI, I see this happening now with gsv McpManagementService | select *.

mniederw commented 1 year ago

I got the same problem, so it is still not fixed. Here an actualized description:

Step to reproduce (no difference if elevated or not): Get-Service McpManagementService; # also for: Get-Service *;

Actual behaviour: On Powershell 5.x : OK, it shows the service properties without an error. On Powershell 7.3.2 on Win10Pro: It shows the service properties BUT it first output the line in red (with no more info): "Get-Service: Service 'McpManagementService (McpManagementService)' cannot be queried due to the following error: " The problem arises if this is used in a script with trapping enabled: $ErrorActionPreference="Stop"; Get-Service McpManagementService; then it throws and ends the script.

Reason: Usually for all services a description is provided but for this specific service the description property is is not correctly stored. For example if service.msc is called then the entry McpManagementService is shown with the description "<Failed to read description, Error Code: 15100>". The reason is that the registry key items:

HKLM\SYSTEM\CurrentControlSet\Services\McpManagementService:Description 
       = @%SystemRoot%\system32\McpManagementService.dll,-101
   HKLM\SYSTEM\CurrentControlSet\Services\McpManagementService:DisplayName 
       = @%SystemRoot%\system32\McpManagementService.dll,-100

contains probably a reference to a string in a dll which not exists. As a workaround1 the two registry key items can be corrected to the string "Universal Print Management Service", but in my opinion the owner of the service and the dll (microsoft) should provide here fix for this. Workaround2: Use $ErrorActionPreference="Stop"; Get-Service -ErrorAction SilentlyContinue McpManagementService; Ignoring error is not best practice and should regular not be nessessary.

Expected behaviour: It should NOT THROW, it should just display "<Failed to read description, Error Code: 15100>" or a similar error-message for the description as service.msc or PS 5 does. The concept of Get-Service should be to provide the service properties and not to guarantee that each creator of a service is providing a proper description!

iSazonov commented 1 year ago

If somebody could create a simple repro on C# one could open issue in .Net Runtime.

eabase commented 1 year ago

Any plans to fix this?

Came here after googling for a solution of: https://stackoverflow.com/questions/76981412/why-doesnt-get-service-show-services-with-the-kerneldriver-servicetype

Stack Overflow
Why doesn't Get-Service show services with the KernelDriver ServiceType?
I was playing around with the Get-Service to list certain types of services. Then I ran into the service shown as RDPDR: # Get-Service RDPDR | Select-Object * UserName : Description ...
eabase commented 1 year ago

Also related to: https://github.com/PowerShell/PowerShell/issues/20188

mattcargile commented 6 months ago

Still a problem as of 7.4.1 on gsv McpManagementService.

nanoDBA commented 4 months ago

Still an issue in 7.4.2 image

Windows PowerShell doesn't seem to have the error: image

eabase commented 4 months ago

@mniederw

As a Workaround-1 the two registry key items can be corrected to the string "Universal Print Management Service", but in my opinion the owner of the service and the dll (microsoft) should provide here fix for this.

  1. How do you implement this in practice?
  2. What about other services, how to find the correct string to replace with?
eabase commented 1 month ago

This issue is now nearly 5 years old, could someone at MS please spend 10 minutes to fix this?

B-Art commented 1 month ago

@iSazonov there are other cases where failure to retrieve specific information simply has that property be $null without emitting any error

Not all code tests $null in the correct order. Testing if ($a -eq $null) will give a different answer than if ($null -eq $a).

jborean93 commented 1 week ago

https://github.com/PowerShell/PowerShell/pull/24245 does what the WG has recommended which is to suppress the error when the description contains an invalid MUI entry and return $null. It also handles the scenario where the caller does not have the SERVICE_QUERY_CONFIG access right but keep in mind the returned props for those services will be limited.

kilasuit commented 1 week ago

FYI using this test, no longer repo's in this win 11 build 10.0.27695 as seems the fix has happened in Windows for this service

FYI, I see this happening now with gsv McpManagementService | select *.

However get-service 'WaaSMedicSvc' | select * does repro it (for now) & is only missing the UserName, Description & BinaryPathName properties, which aren't returned in PowerShell v5

I feel that it's ok to have a docs update stating why these properties may be blank once #24245 gets merged, but we should in future emit a message ( I'm thinking Verbose as we already don't emit any verbose messages in Get-Service ) to inform user that not all properties could be returned likely due to them being incorrectly set as part of creating the service.