Remove '-ComputerName' from 'Get/Set/Remove-Service' (#5094)

This commit is contained in:
Dongbo Wang 2017-10-13 11:06:46 -07:00 committed by Ilya
parent 7df3a3f3fb
commit f2eaeb8b8e
4 changed files with 350 additions and 496 deletions

View file

@ -103,50 +103,14 @@ namespace Microsoft.PowerShell.Commands
string message = StringUtil.Format(errorMessage,
serviceName,
displayName,
(null == innerException) ? "" : innerException.Message
);
ServiceCommandException exception =
new ServiceCommandException(message, innerException);
(null == innerException) ? String.Empty : innerException.Message);
var exception = new ServiceCommandException(message, innerException);
exception.ServiceName = serviceName;
if (innerException != null)
{
}
else
{
}
WriteError(new ErrorRecord(exception, errorId, category, targetObject));
}
/// <summary>
/// Writes a non-terminating error on computer name.
/// </summary>
/// <param name="service"></param>
/// <param name="computername"></param>
/// <param name="innerException"></param>
/// <param name="errorId"></param>
/// <param name="errorMessage"></param>
/// <param name="category"></param>
internal void WriteNonTerminatingError(
ServiceController service,
string computername,
Exception innerException,
string errorId,
string errorMessage,
ErrorCategory category)
{
WriteNonTerminatingError(
service.ServiceName,
computername,
service,
innerException,
errorId,
errorMessage,
category);
}
#endregion Internal
} // class ServiceBaseCommand
#endregion ServiceBaseCommand
@ -299,71 +263,32 @@ namespace Microsoft.PowerShell.Commands
{
if (null == _allServices)
{
List<ServiceController> services = new List<ServiceController>();
if (SuppliedComputerName.Length > 0)
{
foreach (string computerName in SuppliedComputerName)
{
services.AddRange(ServiceController.GetServices(computerName));
}
}
else
{
services.AddRange(ServiceController.GetServices());
}
_allServices = services.ToArray();
_allServices = ServiceController.GetServices();
}
return _allServices;
}
}
private ServiceController[] _allServices = null;
private void AddIfValidService(IList<ServiceController> listOfValidServices, string nameOfService, string computerName)
{
try
{
ServiceController sc = new ServiceController(nameOfService, computerName);
ServiceControllerStatus tmp = sc.Status; // this will throw if the service doesn't exist
// no exceptions = this is an existing, valid service = add
listOfValidServices.Add(sc);
}
catch (InvalidOperationException)
{
}
catch (ArgumentException)
{
}
}
internal List<ServiceController> OneService(string nameOfService)
internal ServiceController GetOneService(string nameOfService)
{
Dbg.Assert(!WildcardPattern.ContainsWildcardCharacters(nameOfService), "Caller should verify that nameOfService doesn't contain wildcard characters");
List<ServiceController> services = new List<ServiceController>();
if (SuppliedComputerName.Length > 0)
try
{
foreach (string computerName in SuppliedComputerName)
{
AddIfValidService(services, nameOfService, computerName);
}
}
else
{
AddIfValidService(services, nameOfService, ".");
}
var sc = new ServiceController(nameOfService);
// This will throw if the service doesn't exist
var unused = sc.Status;
return services;
// No exception, then this is an existing, valid service. Return it.
return sc;
}
catch (InvalidOperationException) { }
catch (ArgumentException) { }
return null;
}
/// <summary>
/// The computer from which to retrieve processes.
/// </summary>
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
protected string[] SuppliedComputerName { get; set; } = Utils.EmptyArray<string>();
/// <summary>
/// Retrieve the list of all services matching the ServiceName,
/// DisplayName, Include and Exclude parameters, sorted by ServiceName.
@ -440,7 +365,8 @@ namespace Microsoft.PowerShell.Commands
}
else
{
foreach (ServiceController service in OneService(pattern))
ServiceController service = GetOneService(pattern);
if (service != null)
{
found = true;
IncludeExcludeAdd(matchingServices, service, true);
@ -451,7 +377,7 @@ namespace Microsoft.PowerShell.Commands
{
WriteNonTerminatingError(
pattern,
"",
String.Empty,
pattern,
null,
"NoServiceFoundForGivenName",
@ -493,7 +419,7 @@ namespace Microsoft.PowerShell.Commands
if (!found && !WildcardPattern.ContainsWildcardCharacters(pattern))
{
WriteNonTerminatingError(
"",
String.Empty,
pattern,
pattern,
null,
@ -618,27 +544,6 @@ namespace Microsoft.PowerShell.Commands
}
}
/// <summary>
/// gets/sets the destination computer name
/// </summary>
[Parameter(
Mandatory = false,
ValueFromPipelineByPropertyName = true)]
[ValidateNotNullOrEmpty()]
[Alias("Cn")]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public string[] ComputerName
{
get
{
return SuppliedComputerName;
}
set
{
SuppliedComputerName = value;
}
}
/// <summary>
/// This returns the DependentServices of the specified service.
/// </summary>
@ -999,7 +904,6 @@ namespace Microsoft.PowerShell.Commands
stoppedServices.Add(serviceController);
}
return stoppedServices;
}
@ -1417,21 +1321,6 @@ namespace Microsoft.PowerShell.Commands
{
#region Parameters
/// <summary>
/// The following is the definition of the input parameter "ComputerName".
/// Set the properties of service running on the list of computer names
/// specified. The default is the local computer.
/// Type the NETBIOS name, an IP address, or a fully-qualified domain name of
/// one or more remote computers. To indicate the local computer, use the
/// computer name, "localhost" or a dot (.). When the computer is in a different
/// domain than the user, the fully-qualified domain name is required.
/// </summary>
[Parameter(ValueFromPipelineByPropertyName = true)]
[ValidateNotNullOrEmpty]
[Alias("cn")]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public String[] ComputerName { get; set; } = new string[] { "." };
/// <summary>
/// service name
/// </summary>
@ -1592,86 +1481,127 @@ namespace Microsoft.PowerShell.Commands
protected override void ProcessRecord()
{
ServiceController service = null;
string ServiceComputerName = null;
IntPtr password = IntPtr.Zero;
foreach (string computer in ComputerName)
bool objServiceShouldBeDisposed = false;
try
{
bool objServiceShouldBeDisposed = false;
if (InputObject != null)
{
service = InputObject;
Name = service.ServiceName;
objServiceShouldBeDisposed = false;
}
else
{
service = new ServiceController(serviceName);
objServiceShouldBeDisposed = true;
}
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.
string unusedByDesign = service.DisplayName;
}
catch (ArgumentException ex)
{
//cannot use WriteNonterminatingError as service is null
ErrorRecord er = new ErrorRecord(ex, "ArgumentException", ErrorCategory.ObjectNotFound, Name);
WriteError(er);
return;
}
catch (InvalidOperationException ex)
{
//cannot use WriteNonterminatingError as service is null
ErrorRecord er = new ErrorRecord(ex, "InvalidOperationException", ErrorCategory.ObjectNotFound, Name);
WriteError(er);
return;
}
try // In finally we ensure dispose, if object not pipelined.
{
// confirm the operation first
// this is always false if WhatIf is set
if (!ShouldProcessServiceOperation(service))
{
return;
}
NakedWin32Handle hScManager = IntPtr.Zero;
NakedWin32Handle hService = IntPtr.Zero;
try
{
if (InputObject != null)
{
service = InputObject;
Name = service.ServiceName;
ServiceComputerName = service.MachineName;
//computer = service.MachineName;
objServiceShouldBeDisposed = false;
}
else
{
ServiceComputerName = computer;
service = new ServiceController(serviceName, ServiceComputerName);
objServiceShouldBeDisposed = true;
}
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.
hScManager = NativeMethods.OpenSCManagerW(
String.Empty,
null,
NativeMethods.SC_MANAGER_CONNECT
);
string unusedByDesign = service.DisplayName;
}
catch (ArgumentException ex)
{
//cannot use WriteNonterminatingError as service is null
ErrorRecord er = new ErrorRecord(ex, "ArgumentException", ErrorCategory.ObjectNotFound, computer);
WriteError(er);
continue;
}
catch (InvalidOperationException ex)
{
//cannot use WriteNonterminatingError as service is null
ErrorRecord er = new ErrorRecord(ex, "InvalidOperationException", ErrorCategory.ObjectNotFound, computer);
WriteError(er);
continue;
}
try // In finally we ensure dispose, if object not pipelined.
{
// confirm the operation first
// this is always false if WhatIf is set
if (!ShouldProcessServiceOperation(service))
if (IntPtr.Zero == hScManager)
{
continue;
int lastError = Marshal.GetLastWin32Error();
Win32Exception exception = new Win32Exception(lastError);
WriteNonTerminatingError(
service,
exception,
"FailToOpenServiceControlManager",
ServiceResources.FailToOpenServiceControlManager,
ErrorCategory.PermissionDenied);
return;
}
hService = NativeMethods.OpenServiceW(
hScManager,
Name,
NativeMethods.SERVICE_CHANGE_CONFIG
);
if (IntPtr.Zero == hService)
{
int lastError = Marshal.GetLastWin32Error();
Win32Exception exception = new Win32Exception(lastError);
WriteNonTerminatingError(
service,
exception,
"CouldNotSetService",
ServiceResources.CouldNotSetService,
ErrorCategory.PermissionDenied);
return;
}
NakedWin32Handle hScManager = IntPtr.Zero;
NakedWin32Handle hService = IntPtr.Zero;
try
// Modify startup type or display name or credential
if (!String.IsNullOrEmpty(DisplayName)
|| (ServiceStartMode)(-1) != StartupType || null != Credential)
{
hScManager = NativeMethods.OpenSCManagerW(
ServiceComputerName,
null,
NativeMethods.SC_MANAGER_CONNECT
);
if (IntPtr.Zero == hScManager)
DWORD dwStartType = NativeMethods.SERVICE_NO_CHANGE;
if (!NativeMethods.TryGetNativeStartupType(StartupType, out dwStartType))
{
int lastError = Marshal.GetLastWin32Error();
Win32Exception exception = new Win32Exception(lastError);
WriteNonTerminatingError(
service,
ServiceComputerName,
exception,
"ComputerAccessDenied",
ServiceResources.ComputerAccessDenied,
ErrorCategory.PermissionDenied);
continue;
WriteNonTerminatingError(StartupType.ToString(), "Set-Service", Name,
new ArgumentException(), "CouldNotSetService",
ServiceResources.UnsupportedStartupType,
ErrorCategory.InvalidArgument);
return;
}
hService = NativeMethods.OpenServiceW(
hScManager,
Name,
NativeMethods.SERVICE_CHANGE_CONFIG
string username = null;
if (null != Credential)
{
username = Credential.UserName;
password = Marshal.SecureStringToCoTaskMemUnicode(Credential.Password);
}
bool succeeded = NativeMethods.ChangeServiceConfigW(
hService,
NativeMethods.SERVICE_NO_CHANGE,
dwStartType,
NativeMethods.SERVICE_NO_CHANGE,
null,
null,
IntPtr.Zero,
null,
username,
password,
DisplayName
);
if (IntPtr.Zero == hService)
if (!succeeded)
{
int lastError = Marshal.GetLastWin32Error();
Win32Exception exception = new Win32Exception(lastError);
@ -1681,68 +1611,93 @@ namespace Microsoft.PowerShell.Commands
"CouldNotSetService",
ServiceResources.CouldNotSetService,
ErrorCategory.PermissionDenied);
continue;
return;
}
} // modify startup type or display name
// Modify startup type or display name or credential
if (!String.IsNullOrEmpty(DisplayName)
|| (ServiceStartMode)(-1) != StartupType || null != Credential)
NativeMethods.SERVICE_DESCRIPTIONW sd = new NativeMethods.SERVICE_DESCRIPTIONW();
sd.lpDescription = Description;
int size = Marshal.SizeOf(sd);
IntPtr buffer = Marshal.AllocCoTaskMem(size);
Marshal.StructureToPtr(sd, buffer, false);
bool status = NativeMethods.ChangeServiceConfig2W(
hService,
NativeMethods.SERVICE_CONFIG_DESCRIPTION,
buffer);
if (!status)
{
int lastError = Marshal.GetLastWin32Error();
Win32Exception exception = new Win32Exception(lastError);
WriteNonTerminatingError(
service,
exception,
"CouldNotSetServiceDescription",
ServiceResources.CouldNotSetServiceDescription,
ErrorCategory.PermissionDenied);
}
// Handle the '-Status' parameter
if (!string.IsNullOrEmpty(Status))
{
if (Status.Equals("Running", StringComparison.OrdinalIgnoreCase))
{
DWORD dwStartType = NativeMethods.SERVICE_NO_CHANGE;
if (!NativeMethods.TryGetNativeStartupType(StartupType, out dwStartType))
if (!service.Status.Equals(ServiceControllerStatus.Running))
{
WriteNonTerminatingError(StartupType.ToString(), "Set-Service", Name,
new ArgumentException(), "CouldNotSetService",
ServiceResources.UnsupportedStartupType,
ErrorCategory.InvalidArgument);
return;
if (service.Status.Equals(ServiceControllerStatus.Paused))
//resume service
DoResumeService(service);
else
//start service
DoStartService(service);
}
string username = null;
if (null != Credential)
}
else if (Status.Equals("Stopped", StringComparison.CurrentCultureIgnoreCase))
{
if (!service.Status.Equals(ServiceControllerStatus.Stopped))
{
username = Credential.UserName;
password = Marshal.SecureStringToCoTaskMemUnicode(Credential.Password);
//check for the dependent services as set-service dont have force parameter
ServiceController[] dependentServices = service.DependentServices;
if ((dependentServices != null) && (dependentServices.Length > 0))
{
WriteNonTerminatingError(service, null, "ServiceHasDependentServicesNoForce", ServiceResources.ServiceHasDependentServicesNoForce, ErrorCategory.InvalidOperation);
return;
}
ServiceController[] servicedependedon = service.ServicesDependedOn;
if ((servicedependedon != null) && (servicedependedon.Length > 0))
{
WriteNonTerminatingError(service, null, "ServiceIsDependentOnNoForce", ServiceResources.ServiceIsDependentOnNoForce, ErrorCategory.InvalidOperation);
return;
}
// Stop service, pass 'true' to the force parameter as we have already checked for the dependent services.
DoStopService(service, force: true, waitForServiceToStop: true);
}
bool succeeded = NativeMethods.ChangeServiceConfigW(
hService,
NativeMethods.SERVICE_NO_CHANGE,
dwStartType,
NativeMethods.SERVICE_NO_CHANGE,
null,
null,
IntPtr.Zero,
null,
username,
password,
DisplayName
);
if (!succeeded)
}
else if (Status.Equals("Paused", StringComparison.CurrentCultureIgnoreCase))
{
if (!service.Status.Equals(ServiceControllerStatus.Paused))
{
int lastError = Marshal.GetLastWin32Error();
Win32Exception exception = new Win32Exception(lastError);
WriteNonTerminatingError(
service,
exception,
"CouldNotSetService",
ServiceResources.CouldNotSetService,
ErrorCategory.PermissionDenied);
continue;
DoPauseService(service);
}
} // modify startup type or display name
NativeMethods.SERVICE_DESCRIPTIONW sd = new NativeMethods.SERVICE_DESCRIPTIONW();
sd.lpDescription = Description;
int size = Marshal.SizeOf(sd);
IntPtr buffer = Marshal.AllocCoTaskMem(size);
Marshal.StructureToPtr(sd, buffer, false);
bool status = NativeMethods.ChangeServiceConfig2W(
hService,
NativeMethods.SERVICE_CONFIG_DESCRIPTION,
buffer);
if (!status)
}
}
if (PassThru.IsPresent)
{
// To display the service, refreshing the service would not show the display name after updating
ServiceController displayservice = new ServiceController(Name);
WriteObject(displayservice);
}
}
finally
{
if (IntPtr.Zero != hService)
{
bool succeeded = NativeMethods.CloseServiceHandle(hService);
if (!succeeded)
{
int lastError = Marshal.GetLastWin32Error();
Win32Exception exception = new Win32Exception(lastError);
@ -1753,117 +1708,39 @@ namespace Microsoft.PowerShell.Commands
ServiceResources.CouldNotSetServiceDescription,
ErrorCategory.PermissionDenied);
}
}
//Addition by v-ramch Mar 11 2008
//if Status parameter specified do the necessary action
//to bring about the desired result
if (!string.IsNullOrEmpty(Status))
if (IntPtr.Zero != hScManager)
{
bool succeeded = NativeMethods.CloseServiceHandle(hScManager);
if (!succeeded)
{
if (Status.Equals("Running", StringComparison.OrdinalIgnoreCase))
{
if (!service.Status.Equals(ServiceControllerStatus.Running))
{
if (service.Status.Equals(ServiceControllerStatus.Paused))
//resume service
DoResumeService(service);
else
//start service
DoStartService(service);
}
}
else if (Status.Equals("Stopped", StringComparison.CurrentCultureIgnoreCase))
{
if (!service.Status.Equals(ServiceControllerStatus.Stopped))
{
//check for the dependent services as set-service dont have force parameter
ServiceController[] dependentServices = service.DependentServices;
if ((dependentServices != null) && (dependentServices.Length > 0))
{
WriteNonTerminatingError(service, null, "ServiceHasDependentServicesNoForce", ServiceResources.ServiceHasDependentServicesNoForce, ErrorCategory.InvalidOperation);
continue;
}
ServiceController[] servicedependedon = service.ServicesDependedOn;
if ((servicedependedon != null) && (servicedependedon.Length > 0))
{
WriteNonTerminatingError(service, null, "ServiceIsDependentOnNoForce", ServiceResources.ServiceIsDependentOnNoForce, ErrorCategory.InvalidOperation);
continue;
}
//stop service,give the force parameter always true as we have already checked for the dependent services
//Specify NoWait parameter as always false since we are not adding this switch to this cmdlet
DoStopService(service, true, true);
}
}
else if (Status.Equals("Paused", StringComparison.CurrentCultureIgnoreCase))
{
if (!service.Status.Equals(ServiceControllerStatus.Paused))
//pause service
DoPauseService(service);
}
}
if (PassThru.IsPresent)
{
//to display the service,refreshing the service would not show the display name after updating
ServiceController displayservice = new ServiceController(Name, ServiceComputerName);
WriteObject(displayservice);
int lastError = Marshal.GetLastWin32Error();
Win32Exception exception = new Win32Exception(lastError);
WriteNonTerminatingError(
service,
exception,
"CouldNotSetServiceDescription",
ServiceResources.CouldNotSetServiceDescription,
ErrorCategory.PermissionDenied);
}
}
finally
{
if (IntPtr.Zero != hService)
{
bool succeeded = NativeMethods.CloseServiceHandle(hService);
if (!succeeded)
{
int lastError = Marshal.GetLastWin32Error();
Win32Exception exception = new Win32Exception(lastError);
WriteNonTerminatingError(
service,
exception,
"CouldNotSetServiceDescription",
ServiceResources.CouldNotSetServiceDescription,
ErrorCategory.PermissionDenied);
}
}
if (IntPtr.Zero != hScManager)
{
bool succeeded = NativeMethods.CloseServiceHandle(hScManager);
if (!succeeded)
{
int lastError = Marshal.GetLastWin32Error();
Win32Exception exception = new Win32Exception(lastError);
WriteNonTerminatingError(
service,
exception,
"CouldNotSetServiceDescription",
ServiceResources.CouldNotSetServiceDescription,
ErrorCategory.PermissionDenied);
}
}
} // finally
} //End try
finally
} // finally
} //End try
finally
{
if (IntPtr.Zero != password)
{
if (IntPtr.Zero != password)
{
Marshal.ZeroFreeCoTaskMemUnicode(password);
}
if (objServiceShouldBeDisposed)
{
service.Dispose();
}
Marshal.ZeroFreeCoTaskMemUnicode(password);
}
}//end for
if (objServiceShouldBeDisposed)
{
service.Dispose();
}
}
}
#endregion Overrides
} // class SetServiceCommand
#endregion SetServiceCommand
@ -1979,7 +1856,7 @@ namespace Microsoft.PowerShell.Commands
// confirm the operation first
// this is always false if WhatIf is set
if (!ShouldProcessServiceOperation(DisplayName ?? "", Name))
if (!ShouldProcessServiceOperation(DisplayName ?? String.Empty, Name))
{
return;
}
@ -2190,21 +2067,6 @@ namespace Microsoft.PowerShell.Commands
[Parameter(ValueFromPipeline = true, ParameterSetName = "InputObject")]
public ServiceController InputObject { get; set; }
/// <summary>
/// The following is the definition of the input parameter "ComputerName".
/// Set the properties of service running on the list of computer names
/// specified. The default is the local computer.
/// Type the NETBIOS name, an IP address, or a fully-qualified domain name of
/// one or more remote computers. To indicate the local computer, use the
/// computer name, "localhost" or a dot (.). When the computer is in a different
/// domain than the user, the fully-qualified domain name is required.
/// </summary>
[Parameter(ValueFromPipelineByPropertyName = true)]
[ValidateNotNullOrEmpty]
[Alias("cn")]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public String[] ComputerName { get; set; } = new string[] { "." };
#endregion Parameters
#region Overrides
@ -2215,140 +2077,134 @@ namespace Microsoft.PowerShell.Commands
protected override void ProcessRecord()
{
ServiceController service = null;
string serviceComputerName = null;
foreach (string computer in ComputerName)
bool objServiceShouldBeDisposed = false;
try
{
bool objServiceShouldBeDisposed = false;
if (InputObject != null)
{
service = InputObject;
Name = service.ServiceName;
objServiceShouldBeDisposed = false;
}
else
{
service = new ServiceController(Name);
objServiceShouldBeDisposed = true;
}
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.
string unusedByDesign = service.DisplayName;
}
catch (ArgumentException ex)
{
// Cannot use WriteNonterminatingError as service is null
ErrorRecord er = new ErrorRecord(ex, "ArgumentException", ErrorCategory.ObjectNotFound, Name);
WriteError(er);
return;
}
catch (InvalidOperationException ex)
{
// Cannot use WriteNonterminatingError as service is null
ErrorRecord er = new ErrorRecord(ex, "InvalidOperationException", ErrorCategory.ObjectNotFound, Name);
WriteError(er);
return;
}
try // In finally we ensure dispose, if object not pipelined.
{
// Confirm the operation first.
// This is always false if WhatIf is set.
if (!ShouldProcessServiceOperation(service))
{
return;
}
NakedWin32Handle hScManager = IntPtr.Zero;
NakedWin32Handle hService = IntPtr.Zero;
try
{
if (InputObject != null)
hScManager = NativeMethods.OpenSCManagerW(
lpMachineName: String.Empty,
lpDatabaseName: null,
dwDesiredAccess: NativeMethods.SC_MANAGER_ALL_ACCESS
);
if (IntPtr.Zero == hScManager)
{
service = InputObject;
Name = service.ServiceName;
serviceComputerName = service.MachineName;
objServiceShouldBeDisposed = false;
int lastError = Marshal.GetLastWin32Error();
Win32Exception exception = new Win32Exception(lastError);
WriteObject(exception);
WriteNonTerminatingError(
service,
exception,
"FailToOpenServiceControlManager",
ServiceResources.FailToOpenServiceControlManager,
ErrorCategory.PermissionDenied);
return;
}
else
hService = NativeMethods.OpenServiceW(
hScManager,
Name,
NativeMethods.SERVICE_DELETE
);
if (IntPtr.Zero == hService)
{
serviceComputerName = computer;
// "new ServiceController" will succeed even if there is no such service.
// This checks whether the service actually exists.
service = new ServiceController(Name, serviceComputerName);
objServiceShouldBeDisposed = true;
int lastError = Marshal.GetLastWin32Error();
Win32Exception exception = new Win32Exception(lastError);
WriteNonTerminatingError(
service,
exception,
"CouldNotRemoveService",
ServiceResources.CouldNotSetService,
ErrorCategory.PermissionDenied);
return;
}
bool status = NativeMethods.DeleteService(hService);
if (!status)
{
int lastError = Marshal.GetLastWin32Error();
Win32Exception exception = new Win32Exception(lastError);
WriteNonTerminatingError(
service,
exception,
"CouldNotRemoveService",
ServiceResources.CouldNotRemoveService,
ErrorCategory.PermissionDenied);
}
Diagnostics.Assert(!String.IsNullOrEmpty(Name), "null ServiceName");
string unusedByDesign = service.DisplayName;
}
catch (ArgumentException ex)
{
// Cannot use WriteNonterminatingError as service is null
ErrorRecord er = new ErrorRecord(ex, "ArgumentException", ErrorCategory.ObjectNotFound, computer);
WriteError(er);
continue;
}
catch (InvalidOperationException ex)
{
// Cannot use WriteNonterminatingError as service is null
ErrorRecord er = new ErrorRecord(ex, "InvalidOperationException", ErrorCategory.ObjectNotFound, computer);
WriteError(er);
continue;
}
try // In finally we ensure dispose, if object not pipelined.
{
// Confirm the operation first.
// This is always false if WhatIf is set.
if (!ShouldProcessServiceOperation(service))
{
continue;
}
NakedWin32Handle hScManager = IntPtr.Zero;
NakedWin32Handle hService = IntPtr.Zero;
try
{
hScManager = NativeMethods.OpenSCManagerW(
lpMachineName: serviceComputerName,
lpDatabaseName: null,
dwDesiredAccess: NativeMethods.SC_MANAGER_ALL_ACCESS
);
if (IntPtr.Zero == hScManager)
{
int lastError = Marshal.GetLastWin32Error();
Win32Exception exception = new Win32Exception(lastError);
WriteObject(exception);
WriteNonTerminatingError(
service,
serviceComputerName,
exception,
"ComputerAccessDenied",
ServiceResources.ComputerAccessDenied,
ErrorCategory.PermissionDenied);
continue;
}
hService = NativeMethods.OpenServiceW(
hScManager,
Name,
NativeMethods.SERVICE_DELETE
);
if (IntPtr.Zero == hService)
{
int lastError = Marshal.GetLastWin32Error();
Win32Exception exception = new Win32Exception(lastError);
WriteNonTerminatingError(
service,
exception,
"CouldNotRemoveService",
ServiceResources.CouldNotSetService,
ErrorCategory.PermissionDenied);
continue;
}
bool status = NativeMethods.DeleteService(hService);
if (!status)
{
int lastError = Marshal.GetLastWin32Error();
Win32Exception exception = new Win32Exception(lastError);
WriteNonTerminatingError(
service,
exception,
"CouldNotRemoveService",
ServiceResources.CouldNotRemoveService,
ErrorCategory.PermissionDenied);
}
}
finally
{
if (IntPtr.Zero != hService)
{
bool succeeded = NativeMethods.CloseServiceHandle(hService);
if (!succeeded)
{
int lastError = Marshal.GetLastWin32Error();
Diagnostics.Assert(lastError != 0, "ErrorCode not success");
}
}
if (IntPtr.Zero != hScManager)
{
bool succeeded = NativeMethods.CloseServiceHandle(hScManager);
if (!succeeded)
{
int lastError = Marshal.GetLastWin32Error();
Diagnostics.Assert(lastError != 0, "ErrorCode not success");
}
}
} // Finally
} // End try
finally
{
if (objServiceShouldBeDisposed)
if (IntPtr.Zero != hService)
{
service.Dispose();
bool succeeded = NativeMethods.CloseServiceHandle(hService);
if (!succeeded)
{
int lastError = Marshal.GetLastWin32Error();
Diagnostics.Assert(lastError != 0, "ErrorCode not success");
}
}
if (IntPtr.Zero != hScManager)
{
bool succeeded = NativeMethods.CloseServiceHandle(hScManager);
if (!succeeded)
{
int lastError = Marshal.GetLastWin32Error();
Diagnostics.Assert(lastError != 0, "ErrorCode not success");
}
}
} // Finally
} // End try
finally
{
if (objServiceShouldBeDisposed)
{
service.Dispose();
}
}// End for
}
}
#endregion Overrides
} // class RemoveServiceCommand

View file

@ -201,8 +201,8 @@
<data name="ResumeServiceFailed" xml:space="preserve">
<value>Service '{1} ({0})' resume failed.</value>
</data>
<data name="ComputerAccessDenied" xml:space="preserve">
<value>The command cannot be used to configure the service '{0}' because access to computer '{1}' is denied. Run PowerShell as admin and run your command again.</value>
<data name="FailToOpenServiceControlManager" xml:space="preserve">
<value>Failed to configure the service '{1} ({0})' due to the following error: {2}. Run PowerShell as admin and run your command again.</value>
</data>
<data name="UnsupportedStartupType" xml:space="preserve">
<value>The startup type '{0}' is not supported by {1}.</value>

View file

@ -47,8 +47,7 @@
@{ parameter = "Include" ; value = "foo","bar" },
@{ parameter = "Exclude" ; value = "bar","foo" },
@{ parameter = "InputObject" ; script = { Get-Service | Select-Object -First 1 } },
@{ parameter = "Name" ; value = "foo","bar" },
@{ parameter = "ComputerName"; value = "bar","foo" }
@{ parameter = "Name" ; value = "foo","bar" }
) {
param($parameter, $value, $script)
if ($script -ne $null) {

View file

@ -10,7 +10,6 @@ Describe "Set/New/Remove-Service cmdlet tests" -Tags "Feature", "RequireAdminOnW
}
It "SetServiceCommand can be used as API for '<parameter>' with '<value>'" -TestCases @(
@{parameter = "ComputerName"; value = "foo"},
@{parameter = "Name" ; value = "bar"},
@{parameter = "DisplayName" ; value = "hello"},
@{parameter = "Description" ; value = "hello world"},