Git Product home page Git Product logo

Comments (15)

jborean93 avatar jborean93 commented on June 12, 2024 2

Changing this behaviour would probably have quite a large impact where people currently expect the -Name to match the display name. I see two potential options:

  • Add a -ServiceName parameter which only matches by the service name
  • Add a switch parameter like -SearchByNameOnly (or something along those lines) to only search by the service name

As for workarounds for this particular scenario you could:

  • Filter after the search Get-Service -Name Browser | Where-Object { $_.Name -eq 'Browser' }
  • Search by display name only Get-Service -DisplayName 'Computer Browser'
    • This has the downside if the display name is localised and you need to deal with different languages
  • Use the .NET API instead of these cmdlets

from powershell.

AaronMargosis avatar AaronMargosis commented on June 12, 2024 1

I agree that backward compatibility concerns make properly fixing the behavior of the -Name parameter less than feasible. But the Get-Help can at least be corrected to describe what the existing behavior is. (And if not actually backport that fix to Windows PowerShell, at least fix the documentation online.)

from powershell.

TuemmlerKelch avatar TuemmlerKelch commented on June 12, 2024 1

Is this really it? This is the equivalent of airbus adding "plane might lose a wing mid-flight" to the manual instead of making sure the wing sticks to the plane.
Is there any way to escalate or reevaluate this?
I get the argument that fixing this would break backwards compatibility for people that didn't use the command as they were intended and removing something that might have been designed as a fallback.

But just neglecting the idea to add another parameter to enforce correct behavior? I cannot wrap my head around that.
Please reconsider.

from powershell.

iSazonov avatar iSazonov commented on June 12, 2024

These parameters are definitely different.

[Parameter(Position = 0, ParameterSetName = "Default", ValueFromPipelineByPropertyName = true, ValueFromPipeline = true)]
[ValidateNotNullOrEmpty()]
[Alias("ServiceName")]
public string[] Name
{
get
{
return serviceNames;
}
set
{
serviceNames = value;
selectionMode = SelectionMode.ServiceName;
}
}

[Parameter(ParameterSetName = "DisplayName", Mandatory = true)]
public string[] DisplayName
{
get
{
return displayNames;
}
set
{
displayNames = value;
selectionMode = SelectionMode.DisplayName;
}
}

And they are handled differently

internal List<ServiceController> MatchingServices()
{
List<ServiceController> matchingServices;
switch (selectionMode)
{
case SelectionMode.DisplayName:
matchingServices = MatchingServicesByDisplayName();
break;
case SelectionMode.InputObject:
matchingServices = MatchingServicesByInput();
break;
default:
matchingServices = MatchingServicesByServiceName();
break;
}
// 2004/12/16 Note that the services will be sorted
// before being stopped. JimTru confirms that this is OK.
matchingServices.Sort(ServiceComparison);
return matchingServices;

Although it's not clear why the algorithms are different

private List<ServiceController> MatchingServicesByServiceName()

https://github.com/PowerShell/PowerShell/blob/master/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs#L435

I guess that's why we're getting weird results.
And that's not the only case. For example:

Get-Service -Name Browser

Status   Name               DisplayName
------   ----               -----------
Running  bowser             Browser


Get-Service | where Name -eq browser

<empty>

from powershell.

AaronMargosis avatar AaronMargosis commented on June 12, 2024

Also strange that I normally can't get Get-Service to return kernel drivers by name unless I explicitly provide the key name, or by display name at all:
Get-Service -Name b* doesn't return any drivers, just services.
Get-Service -DisplayName 'Browser' doesn't return the bowser driver.
Get-Service -Name 'Browser' returns the bowser driver, as does Get-Service -Name 'Bowser'.
This is just pretty badly broken.

from powershell.

AaronMargosis avatar AaronMargosis commented on June 12, 2024

Get-Service -Name 'Browser' | ?{ $_.Name -eq 'Browser' }

This is pretty bad.

from powershell.

rhubarb-geek-nz avatar rhubarb-geek-nz commented on June 12, 2024

I suggest compare it with "sc query", for instance

PS> sc query | findstr SERVICE_NAME | findstr bowser

does not return "bowser"

but asking specifically does get it

PS> sc query bowser | findstr SERVICE_NAME
SERVICE_NAME: bowser

PowerShell is not magic and does rely on the underlying APIs and commands

from powershell.

AaronMargosis avatar AaronMargosis commented on June 12, 2024

sc.exe is not an API. And the underlying APIs are not the problem -- it's how the provided cmdlets are calling them.

from powershell.

rhubarb-geek-nz avatar rhubarb-geek-nz commented on June 12, 2024

sc.exe is not an API.

DESCRIPTION:
        SC is a command line program used for communicating with the
        Service Control Manager and services.

I did say "API and commands". If one is writing a batch file then sc.exe is effectively an API. If you can call RESTful services an API then invoking an exe with a well documented interface can certainly be counted as an API.

sc.exe is also a good example of how the underlying API is expected to be used, If "sc query" does not return "bowser" then there must be a good reason why. Perhaps there may be a high cost to an exhaustive search for services that querying directly by name avoids.

Also, file system drivers might not be considered services in the true sense.

For instance

sc query | findstr FILE_SYSTEM_DRIVER

does not return any.

from powershell.

rhubarb-geek-nz avatar rhubarb-geek-nz commented on June 12, 2024

Looks like Get-Service finds more services than "sc query"

PS> (Get-Service).Count
Get-Service: Service 'McpManagementService (McpManagementService)' cannot be queried due to the following error: PermissionDenied
Get-Service: Service 'NPSMSvc_ef99075 (NPSMSvc_ef99075)' cannot be queried due to the following error: PermissionDenied
Get-Service: Service 'WaaSMedicSvc (WaaSMedicSvc)' cannot be queried due to the following error: PermissionDenied
292
PS> (sc query | findstr SERVICE_NAME).Count
130

from powershell.

AaronMargosis avatar AaronMargosis commented on June 12, 2024

The problem isn't the Win32 APIs. The PowerShell cmdlets are built on the .NET Framework and the ServiceController class in particular.

The ServiceController.GetServices() method correctly documents that it enumerates only services and not drivers. (The GetDevices() method retrieves drivers.) The ServiceController constructor that takes a string parameter documents that the input string can be the service name or its display name, and (although not explicitly documented) can refer to a service or a driver.

In the Get-Service implementation, if a supplied -Name parameter doesn't contain wildcard characters, the cmdlet doesn't call GetServices and filter its results; instead it uses the ServiceController constructor with the -Name parameter, resulting in incorrectly treating it as a service name or as a display name. The ServiceController class doesn't provide a constructor or method that explicitly takes just a service name. The "doesn't contain wildcard characters" shortcut is where the bug is. I think it would have been correct had the -Name parameter had been treated as a pattern.

from powershell.

SteveL-MSFT avatar SteveL-MSFT commented on June 12, 2024

@AaronMargosis as noted, this is the same behavior in WinPS5.1 so it would be a breaking change. However, as suggested by @jborean93 it may make sense to have a new switch (seems like -ServiceName is already an alias) to have it match ServiceName only (filtered within the cmdlet since the .NET API is too broad). Will have Cmdlets WG review.

from powershell.

AaronMargosis avatar AaronMargosis commented on June 12, 2024

How about changing -ServiceName from an alias to its own parameter. It shouldn't be a back-compat problem to make -ServiceName work the way it should, right? Today, Get-Service -ServiceName 'Browser' incorrectly returns the bowser.sys driver if the Computer Browser service isn't present.

from powershell.

SteveL-MSFT avatar SteveL-MSFT commented on June 12, 2024

@PowerShell/wg-powershell-cmdlets reviewed this. As this cmdlet behaves the same as 5.1 and has a strong chance of users depending (knowingly or not) on current behavior, we can't make any changes. However, we should improve our documentation to specify:

  • Enumeration does NOT include device driver services
  • When wild card is specified, the cmdlet performs filtering ONLY on Windows services (device services are NOT included)
  • If you specify the name which is an exact device service name or exact display name, then that instance will be returned

from powershell.

SteveL-MSFT avatar SteveL-MSFT commented on June 12, 2024

Doc bug MicrosoftDocs/PowerShell-Docs#10966

from powershell.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.