Skip to content

Conversation

@joandrsn
Copy link
Contributor

I have added the function Remove-Service to the Management module.
The functions New-Service and Set-Service were already present, I thought it would be a good idea to have a Remove-Service

Issue #4717

@msftclas
Copy link

@joandrsn,
Thanks for having already signed the Contribution License Agreement. Your agreement was validated by Microsoft. We will now review your pull request.
Thanks,
Microsoft Pull Request Bot

{
hScManager = NativeMethods.OpenSCManagerW(
ServiceComputerName,
null,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use named parameters.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't quite follow you. Did you want to use the variable ComputerName ? Since the method supports both a Name on the local computer and a servicecontroller on a remote machine, I believe I have to use the ServiceComputerName variable.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -1,4 +1,5 @@
Describe "Set/New-Service cmdlet tests" -Tags "Feature", "RequireAdminOnWindows" {
Import-Module ".\Microsoft.PowerShell.Commands.Management.dll"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should not be required. Can you remove this?

finally {
Get-CimInstance Win32_Service -Filter "name='$servicename'" | Remove-CimInstance -ErrorAction SilentlyContinue
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you also add tests which validates the error cases?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also add tests for pipeline input.

/// This class implements the set-service command
/// </summary>
[Cmdlet(VerbsCommon.Remove, "Service", SupportsShouldProcess = true, DefaultParameterSetName = "Name")]
[OutputType(typeof(ServiceController))]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typically Remove* cmdlets do not return anything.

finally {
Get-CimInstance Win32_Service -Filter "name='$servicename'" | Remove-CimInstance -ErrorAction SilentlyContinue
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also add tests for pipeline input.

Copy link
Contributor

@markekraus markekraus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor formatting and comment/summary rewording suggestions.


#region Overrides
/// <summary>
/// Create the service
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be Remove the service?


#region RemoveServiceCommand
/// <summary>
/// This class implements the set-service command
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be Remove-Service?

#region Parameters

/// <summary>
/// Name of the service to create
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be Name of the service to remove?


/// <summary>
/// The following is the definition of the input parameter "InputObject".
/// Specifies ServiceController object representing the services to be stopped.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be the services to be removed.?

continue;
}


Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove extra line.

@@ -1,4 +1,5 @@
Describe "Set/New-Service cmdlet tests" -Tags "Feature", "RequireAdminOnWindows" {
Import-Module "C:\Users\jsa\code\PowerShell\src\powershell-win-core\bin\Debug\netcoreapp2.0\win7-x64\Microsoft.PowerShell.Commands.Management.dll"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please Remove

{ Remove-Service -Name "testremoveservice" -ErrorAction 'Stop' } | Should Throw
}


Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove extra line

@markekraus
Copy link
Contributor

@joandrsn it looks like the cmdlet doesn't export. I can repro on win10 x64. No clue why, though.

@joandrsn
Copy link
Contributor Author

@markekraus If I import the cmdlet with my import statement that I previously committed (and removed again), I can get it to work. Somehow the travis build gets the module imported (it doesn't fail).
I'm not sure why that is.
If I try a Get-Command Get-Service I get a version 3.1.0.0 and after importing the .dll i get 6.0.0.0

@adityapatwardhan
Copy link
Member

/// <summary>
/// Name of the service to remove
/// </summary>
/// <value></value>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should probably remove this

protected override void ProcessRecord()
{
ServiceController service = null;
string ServiceComputerName = null;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for consistency, should use camelCasing

{
hScManager = NativeMethods.OpenSCManagerW(
ServiceComputerName,
null,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WriteNonTerminatingError(
service,
exception,
"CouldNotRemoveService",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't seem to the right error. According to the docs, CloseServiceHandle only fails if it's an invalid handle which is probably never going to the be case here. Anyways, even if this fails, it would seem that the service was still deleted. Maybe this should just be a diagnostic assert?

bool succeeded = NativeMethods.CloseServiceHandle(hScManager);
if (!succeeded)
{
int lastError = Marshal.GetLastWin32Error();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above, perhaps just an assert?

}
$service = New-Service @parameters
$service | Should Not BeNullOrEmpty
Get-Service -Name $servicename | Remove-Service -ErrorAction SilentlyContinue
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you want -ErrorAction SilentlyContinue there in case something fails

Diagnostics.Assert(!String.IsNullOrEmpty(Name), "null ServiceName");
// "new ServiceController" will succeed even if
// there is no such service. This checks whether
// the service actually exists.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we put the comment before Diagnostics.Assert?
And please reformat the comment - we can use wider lines.


#region RemoveServiceCommand
/// <summary>
/// This class implements the remove-service command
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Case - Remove-Service.

bool objServiceShouldBeDisposed = false;
try
{
if (_ParameterSetName.Equals("InputObject", StringComparison.OrdinalIgnoreCase) && InputObject != null)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we using _ParameterSetName in the file (twice)? In all other files we use ParameterSetName.
I believe we should fix this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like line 1604 used this and @joandrsn was just following this pattern. Agree that we should change it to just ParameterSetName (including line 1604) for consistency.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems we could remove _ParameterSetName.Equals("InputObject", StringComparison.OrdinalIgnoreCase) at all.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. InputObject check should be sufficient

}
catch (ArgumentException ex)
{
//Cannot use WriteNonterminatingError as service is null
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add space // Cannot.

}
catch (InvalidOperationException ex)
{
//Cannot use WriteNonterminatingError as service is null
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add space // Cannot

@iSazonov
Copy link
Collaborator

@joandrsn Please add Remove-Service in DefaultCommands.Tests.ps1 to pass CI.

"Cmdlet", "Set-PSDebug", , $($FullCLR -or $CoreWindows -or $CoreUnix)
"Cmdlet", "Set-PSSessionConfiguration", , $($FullCLR -or $CoreWindows -or $CoreUnix)
"Cmdlet", "Set-Service", , $($FullCLR -or $CoreWindows )
"Cmdlet", "Remove-Service", , $($FullCLR -or $CoreWindows )
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you move this up in the list so it is in alphabetical order? Should go between Remove-PSSnapin and Remove-TypeData

…e test which used the function class directly
@joandrsn
Copy link
Contributor Author

I think I figured it out.
I changed the inheritance from Cmdlet to PSCmdlet to use ParameterSetName instead of _ParameterSetName.
This meant I had to rewrite a test which used the class directly. Unfortunatly, the test was too complicated for me to rewrite in the same function as before, so I split the test into 4 separate tests.
Also I'm not sure if the last test actually does anything. On my computer, the service was already running. So maybe I should create a service and then change that service? Looking for feedback.

@markekraus
Copy link
Contributor

I think this probably needs to be reverted. I believe ServiceBaseCommand intentionally derives from Cmdlet so that the service cmdlets can be directly invoked. This would likely be a Bucket 1 or 2 Breaking Change.

@joandrsn
Copy link
Contributor Author

Do you have a suggestion on how I would be able to use ParameterSetName instead? I can't currently see the solution if changing the inheiritance to PSCmdlet would be a breaking change.

@markekraus
Copy link
Contributor

I think it was using _ParameterSetName "by design" as ParameterSetName is not available in commands that derive from Cmdlet instead of PSCmdlet. RemoveServiceCommand could derive from PSCmdlet but that would break the derived methods. ServiceBaseCommand could be switched to derive from PSCmdlet, but that would probably take a review committee approval.

Looking for guidance from other cmdlets, many of them are using

if (InputObject != null)

and

if (Name != null)

Example RenameLocalGroupCommand

I lean towards either switching to the null checks or just leaving it as _ParameterSetName. I can see benefits to the Service Cmdlets being directly invoked fro host apps, so Moving to PSCmdlet seems like a bad option.

@SteveL-MSFT @iSazonov thoughts?

@SteveL-MSFT
Copy link
Member

Seems like the best solution here (preferring simplicity) is to revert back to deriving from Cmdlet as it originally was which perhaps was intentional. Would like to see the tests back to being -TestCases as it seems there a bunch of similar code having split up due to the change in inheritance.

@iSazonov
Copy link
Collaborator

Oops, I again got an artifact 😄
I unlike using _ParameterSetName because it is marked as "internal" and available through a hack with InternalsVisibleTo.
So I agree that we should revert last changes and remove _ParameterSetName.

Copy link
Member

@SteveL-MSFT SteveL-MSFT left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the contribution!

Copy link
Member

@adityapatwardhan adityapatwardhan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Contributor

@markekraus markekraus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@adityapatwardhan adityapatwardhan merged commit f281671 into PowerShell:master Sep 21, 2017
@adityapatwardhan
Copy link
Member

@joandrsn Thanks for your contribution!

@PingPongSet
Copy link

What vesion of PowerShell is Remove-service available for? What about version 4?

@iSazonov
Copy link
Collaborator

@PingPongSet Windows PowerShell is frozen. All new features will be only added to PowerShell Core. Feel free download latest version, try and feedback.

@PingPongSet
Copy link

@iSazonov What vesion of PowerShell is Remove-service available for?

@iSazonov
Copy link
Collaborator

@PingPongSet I don' remember the version but you could look release notes for PowerShell Core 6.0. Also make only sense download latest PowerShell Core 6.0 version.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants