diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs index 293778b74d..29c407c50d 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs @@ -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)); } - - /// - /// Writes a non-terminating error on computer name. - /// - /// - /// - /// - /// - /// - /// - 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 services = new List(); - - 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 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 OneService(string nameOfService) + internal ServiceController GetOneService(string nameOfService) { Dbg.Assert(!WildcardPattern.ContainsWildcardCharacters(nameOfService), "Caller should verify that nameOfService doesn't contain wildcard characters"); - List services = new List(); - 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; } - /// - /// The computer from which to retrieve processes. - /// - [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] - protected string[] SuppliedComputerName { get; set; } = Utils.EmptyArray(); - /// /// 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 } } - /// - /// gets/sets the destination computer name - /// - [Parameter( - Mandatory = false, - ValueFromPipelineByPropertyName = true)] - [ValidateNotNullOrEmpty()] - [Alias("Cn")] - [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] - public string[] ComputerName - { - get - { - return SuppliedComputerName; - } - set - { - SuppliedComputerName = value; - } - } - /// /// This returns the DependentServices of the specified service. /// @@ -999,7 +904,6 @@ namespace Microsoft.PowerShell.Commands stoppedServices.Add(serviceController); } - return stoppedServices; } @@ -1417,21 +1321,6 @@ namespace Microsoft.PowerShell.Commands { #region Parameters - /// - /// 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. - /// - [Parameter(ValueFromPipelineByPropertyName = true)] - [ValidateNotNullOrEmpty] - [Alias("cn")] - [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] - public String[] ComputerName { get; set; } = new string[] { "." }; - /// /// service name /// @@ -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; } - /// - /// 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. - /// - [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 diff --git a/src/Microsoft.PowerShell.Commands.Management/resources/ServiceResources.resx b/src/Microsoft.PowerShell.Commands.Management/resources/ServiceResources.resx index 8c94d5bb35..4a1aa45ee7 100644 --- a/src/Microsoft.PowerShell.Commands.Management/resources/ServiceResources.resx +++ b/src/Microsoft.PowerShell.Commands.Management/resources/ServiceResources.resx @@ -201,8 +201,8 @@ Service '{1} ({0})' resume failed. - - 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. + + Failed to configure the service '{1} ({0})' due to the following error: {2}. Run PowerShell as admin and run your command again. The startup type '{0}' is not supported by {1}. diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/Get-Service.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/Get-Service.Tests.ps1 index be01791419..99163036b0 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/Get-Service.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Get-Service.Tests.ps1 @@ -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) { diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 index 3776ad5d1b..4ef784b11e 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 @@ -10,7 +10,6 @@ Describe "Set/New/Remove-Service cmdlet tests" -Tags "Feature", "RequireAdminOnW } It "SetServiceCommand can be used as API for '' with ''" -TestCases @( - @{parameter = "ComputerName"; value = "foo"}, @{parameter = "Name" ; value = "bar"}, @{parameter = "DisplayName" ; value = "hello"}, @{parameter = "Description" ; value = "hello world"},