Closed zhenggu closed 5 years ago
I'm curious if this is even the right direction. Doesn't Stop-Service -Force
do this already? Shouldn't Set-Service
only support a a very basic stop? The -Status
on Set-Service
is redundant to stop-service
which should be the de facto way to stop services.
We have a similar question in #5471
I think it is necessary to remove the ServicesDependedOn check for it will block the normal function. and for parameter "Force", we can discuss it in other thread, if the parameter may be not acceptable.
@SteveL-MSFT Could you please review the PR with #5471 on PowerShell committee?
Yes, Set-Service -Status
duplicates Start-Service
/ Resume-Service
/ Stop-Service
/ Suspend-Service
functionality, but:
Start-Service
doesn't have: if the target service's startup mode is currently Disabled
, Start-Service
invariably fails. By contrast, you can use Set-Service -StartupType Manual -State Running
in such a case, for instance.On the flip side, it currently doesn't support -Force
in order to stop a service that have dependents - which I think should be fixed too.
As for the issue at hand:
Preventing a service from stopping because it depends on other services - as opposed to having other services depend on it (having dependents) - is an arbitrary and nonsensical restriction.
I presume it was introduced based on a misconception and should therefore be removed, which will make -Status Stopped
work as expected, as long as the target service doesn't have dependents.
@iSazonov: How is #5471 related to this?
@mklement0 Thanks for useful comments!
How is #5471 Start-Process: add parameter 'ExitTimeout' related to this?
Design review needed.
@mklement0
it is a one-stop solution with more of a desired-state feel.
Yea, but stopping a service is NOT setting a service. We have specific verbs for that kind of action. if there is a current bug in how it operates, that should be fixed, but adding -force
for set-
to only affect the stop
is ridiculous. We have the stop
verb, use it for advanced stop functionality. If you can get away with basic stop on set
, so be it, that's what stop
is for. If I could go back in time I would say the set
verb should not have had this functionality to begin with. if it did, then the stop
verb should not have been included.
On your second point about start-service
, I will say that set
is also not start
and including it originally is silly, IMO. The correction there is to add a -force
to start
if it is not already there that enables the service if it is not disabled and starts any services it depends on.
I'm just trying to keep things simple here and it seems like this PR is going in the wrong direction from simple. There is nothing wrong with doing something like set-service @params -PassThru | stop-service
or set-service @params -PassThru | start-service
. That keeps to the do one thing philosophy. increasing complexity in a command to do another thing when there is another command that does that one thing is an odd design choice. (setting aside any perceived convenience in doing so).
I don't why it was decided to provide duplicate functionality in Set-Service
, but given that it was:
fixing the bug is a must, as we agree.
however, not duplicating all the functionality seems silly, if adding -Force
is all that it takes, especially given that, as demonstrated, in other aspects it can do more than one of its counterparts.
(On a side note: status value suspended
should probably be added as an alias for paused
).
Adding a -Force
switch to Start-Service
is not a solution, because there is no sensible default for the startup type that invariably has to change in that case - unless you add -StartupType
to Start-Service
too, but that would then duplicate what Set-Service
already does.
Yes, you can argue that the -Status
parameter should never have been implemented, but, looking at the bigger picture, the Set
verb has always had desired-state aspects in certain cmdlets, resulting in duplication as well; two examples:
You can use Set-Variable
without ever having to touch New-Variable
- the variable is created on demand.
You can use Set-Content
to create a file on demand, without needing to use New-Item
.
And, finally, another aspect in which Set-Service -Status
provides extra (again, desired-state) functionality is that -Status Running
either starts or resumes (continues) a service, as appropriate, whereas applying Start-Service
to a suspended (paused) service results in an error.
however, not duplicating all the functionality seems silly,
No, it doesn't at all. Set-
is for setting, Stop-
is for stopping. if the ability to stop on set-
goes beyond anything basic, you should use stop-
. The ability to stop on set-
is a convenience that arguably should not be there (and I'm not advocating for its removal, for clarity).
Tell me, absent -Status Stopped
, what purposed does -Force
have? If I see -Force
on Set-Service
is expect it to allow me to force service settings. In this case, the only thing force is good for is stopping the service. We already have Stop-Service -Force
for that. For desired state, you are not likely going to be forcing the service to stop. Again, this adds complexity and redundancy, and I'm arguing for simplicity.
Edit: as a compromise, if everyone really thinks that having set-
force stop a service is not as crazy as I think it is, how about -Status StoppedForced
or something instead of -Force
switch that only works for a specific single value on a single parameter?
Adding a -Force switch to Start-Service is not a solution, because there is no sensible default for the startup type that invariably has to change in that case
I disagree, setting it to manual, when you are "manually" forcing the service to start certainly serves as a sensible setting. But this is a discussion for another time, lets not continue it in this thread.
@iSazonov committee is on taking time off this week for Thanksgiving (US holiday), will resume next week
@PowerShell/powershell-committee reviewed this. Given that -Status Stopped
is already there, it would make sense to support -Force
for Set-Service
@SteveL-MSFT I would like the comittee to reconsider the approval of -Force
for this PR. RE: https://github.com/PowerShell/PowerShell/pull/6113#discussion_r167348028 and a few other discussions we have had here. The -Force
in this PR not only applies to a single parameter, it also only applies to a single option for that parameter. I still believe including a ForceStopped
or StoppedForced
option for -Status
is the better design choice and that we should avoid -Force
abuse.
@PowerShell/powershell-committee reviewed this. The only applicable parameter to -Force
is -Status
(when value is Stopped
) and there's no applicability to other parameters for this cmdlet. The usage is consistent with other cmdlets like Stop-Service
, so committee continues to recommend using -Force
for this case.
@zhenggu Thanks for your contribution. Please add the PR submission template and update the appropriate fields. https://github.com/PowerShell/PowerShell/blob/master/.github/CONTRIBUTING.md#pull-request---submission
This PR has been automatically marked as stale because it has not had activity in the last 30 days. It will be closed if no further activity occurs within 10 days. Thank you for your contributions.
This PR has be automatically close because it is stale. If you wish to continue working on the PR, please first update the PR, then reopen it. Thanks again for your contribution. Community members are welcome to grab these works.
I want to reopen this PR, but how can I do it?
@zhenggu The PR is reopened. Thanks!
Thanks @iSazonov
any idea about CodeFactor issues? Seems no issue is caused by my code.
@zhenggu You must fix style issues in new code and changed code but you shouldn't fix all CodeFactor issues.
@iSazonov got it, I will take care of this
I don't see style errors in your code.
one question, There are many test cases uses pwsh.exe as the the binary file of the service in Set-Service.Tests.ps1, but actually we cannot run pwsh.exe as a service for it will not response any thing to the OS. As in this way, can I implement a new service by powershell to test the stop case, or I can just use wuauserv in #5517 as the service.
I have added one test case to check -Status Stopped can run normally to stop wuauserv.
Hi @iSazonov, can you please help to review again.
It will be difficult to add test cases -Force parameter, for I cannot find two services which has dependency relationship, and I can stop them both without any impact to the test windows server. Any suggestion?
We could create simple custom services for the test.
@iSazonov So can I put my custom service into test\powershell\Modules\Microsoft.PowerShell.Management\assets? And is there any variable which points to the source code base directory in the test case?
I guess it will be binary test module in /test/tools/
. I can look WebListener as a sample.
@iSazonov Thanks very much
Have added one TestService written in C, but still don't know how to let the whole project call this CMakeFile.txt. And if it is called, will it be built in the same directory as pwsh? Please help to confirm them, and then I can continue. Thanks
@adityapatwardhan @JamesWTruher Could you please help? Perhaps there is more simple way to create test windows services to test *-Service cmdlets.
For I don't find a way to add a custom service, remove force flag and do the bug fix first.
Thanks @iSazonov for your always support.
@iSazonov there is one interesting thing that when I try your way, System.ServiceProcess.ServiceBase is only provided by .net framework, not .net core, according: http://dotnet.github.io/dotnet-web/api/System.ServiceProcess.html, it seems there is one RP of dotnet to add this: https://github.com/dotnet/corefx/pull/22920, but it is in minestone 2.1.0, and we are still using 2.0.0 according the build document.
test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1, line 339 at r4 (raw file):
Thanks @iSazonov I will modify it.
I don't think spooler always exists. Can we add a check if it exists ahead of time and skip the test if it doesn'?
test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1, line 339 at r4 (raw file):
I don't think spooler always exists. Can we add a check if it exists ahead of time and skip the test if it doesn'?
I verified. I believe this is the minimal set of services:
Status Name DisplayName
------ ---- -----------
Running cexecsvc Container Execution Agent
Running CryptSvc Cryptographic Services
Running DcomLaunch DCOM Server Process Launcher
Running Dhcp DHCP Client
Running DiagTrack Connected User Experiences and Tele...
Running Dnscache DNS Client
Running EventLog Windows Event Log
Stopped KeyIso CNG Key Isolation
Stopped LanmanServer Server
Running LanmanWorkstation Workstation
Stopped lmhosts TCP/IP NetBIOS Helper
Stopped mpssvc Windows Defender Firewall
Stopped Netlogon Netlogon
Stopped NetSetupSvc Network Setup Service
Running nsi Network Store Interface Service
Stopped Power Power
Running ProfSvc User Profile Service
Running RpcEptMapper RPC Endpoint Mapper
Running RpcSs Remote Procedure Call (RPC)
Running SamSs Security Accounts Manager
Running Schedule Task Scheduler
Stopped seclogon Secondary Logon
Running SystemEventsBroker System Events Broker
Running TimeBrokerSvc Time Broker
Stopped TrustedInstaller TrustedInstaller
Running UserManager User Manager
Stopped VaultSvc Credential Manager
Stopped WerSvc Windows Error Reporting Service
Stopped WinHttpAutoProx... WinHTTP Web Proxy Auto-Discovery Se...
Stopped wisvc Windows Insider Service
test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1, line 339 at r4 (raw file):
I verified. I believe this is the minimal set of services: ``` Status Name DisplayName ------ ---- ----------- Running cexecsvc Container Execution Agent Running CryptSvc Cryptographic Services Running DcomLaunch DCOM Server Process Launcher Running Dhcp DHCP Client Running DiagTrack Connected User Experiences and Tele... Running Dnscache DNS Client Running EventLog Windows Event Log Stopped KeyIso CNG Key Isolation Stopped LanmanServer Server Running LanmanWorkstation Workstation Stopped lmhosts TCP/IP NetBIOS Helper Stopped mpssvc Windows Defender Firewall Stopped Netlogon Netlogon Stopped NetSetupSvc Network Setup Service Running nsi Network Store Interface Service Stopped Power Power Running ProfSvc User Profile Service Running RpcEptMapper RPC Endpoint Mapper Running RpcSs Remote Procedure Call (RPC) Running SamSs Security Accounts Manager Running Schedule Task Scheduler Stopped seclogon Secondary Logon Running SystemEventsBroker System Events Broker Running TimeBrokerSvc Time Broker Stopped TrustedInstaller TrustedInstaller Running UserManager User Manager Stopped VaultSvc Credential Manager Stopped WerSvc Windows Error Reporting Service Stopped WinHttpAutoProx... WinHTTP Web Proxy Auto-Discovery Se... Stopped wisvc Windows Insider Service ```
have added a pre check of spooler for that.
test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1, line 339 at r4 (raw file):
have added a pre check of spooler for that.
Done.
there is one interesting thing that when I try your way, System.ServiceProcess.ServiceBase is only provided by .net framework, not .net core,
The API is in WCP https://blogs.msdn.microsoft.com/dotnet/2017/11/16/announcing-the-windows-compatibility-pack-for-net-core/ . We use WCP in PowerShell Core and I think we can use it in test module too.
any other thing can I do for this PR?
@TravisEz13 can you continue your review?
test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1, line 358 at r12 (raw file):
(Get-Service $testservicename2).Status | Should -BeExactly "Stopped" # stop a service with running dependent service
It seems that this should be a separate it statement
and Set-Service -Status Running $testservicename2 | Should -Not -Throw
should be part of a BeforeEach
test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1, line 367 at r12 (raw file):
(Get-Service $testservicename2).Status | Should -BeExactly "Running" # stop a service with running dependent service by -Force
This looks like a separate it
as well, maybe a separate context
because it may have a different BeforeEach
test/tools/TestService/Program.cs, line 1 at r12 (raw file):
using System.ServiceProcess;
missing copyright headers
test/tools/TestService/Service1.cs, line 1 at r12 (raw file):
using System.ServiceProcess;
missing copyright headers
PR Summary
Fixes #5517
In the previous version, if one service has dependency services, it cannot be stopped by "Set-Service -Stop", this PR fixes this issue.
And also add the Parameter "-Force" to Set-Service, when it is enabled, the function will stop it's dependent services, and then stop the target's service itself.
Without the parameter "-Force" it will raise a exception, if the service has running dependent services.
PR Checklist
.h
,.cpp
,.cs
,.ps1
and.psm1
files have the correct copyright headerWIP:
to the beginning of the title and remove the prefix when the PR is ready.[feature]
if the change is significant or affects feature testsThis change is