diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs index c8986ab70..8d9ea2a0e 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs @@ -1511,8 +1511,6 @@ namespace Microsoft.PowerShell.Commands internal ServiceStartMode startupType = (ServiceStartMode)(-1); - - /// /// The following is the definition of the input parameter "Status". /// This specifies what state the service should be in (e.g. Running, Stopped, @@ -1684,22 +1682,13 @@ namespace Microsoft.PowerShell.Commands || (ServiceStartMode)(-1) != StartupType) { DWORD dwStartType = NativeMethods.SERVICE_NO_CHANGE; - switch (StartupType) + if (!NativeMethods.TryGetNativeStartupType(StartupType, out dwStartType)) { - case ServiceStartMode.Automatic: - dwStartType = NativeMethods.SERVICE_AUTO_START; - break; - case ServiceStartMode.Manual: - dwStartType = NativeMethods.SERVICE_DEMAND_START; - break; - case ServiceStartMode.Disabled: - dwStartType = NativeMethods.SERVICE_DISABLED; - break; - default: - Diagnostics.Assert( - ((ServiceStartMode)(-1)) == StartupType, - "bad StartupType"); - break; + WriteNonTerminatingError(StartupType.ToString(), "Set-Service", Name, + new ArgumentException(), "CouldNotSetService", + ServiceResources.UnsupportedStartupType, + ErrorCategory.InvalidArgument); + return; } bool succeeded = NativeMethods.ChangeServiceConfigW( hService, @@ -2002,25 +1991,14 @@ namespace Microsoft.PowerShell.Commands ErrorCategory.PermissionDenied); return; } - DWORD dwStartType = NativeMethods.SERVICE_AUTO_START; - switch (StartupType) + if (!NativeMethods.TryGetNativeStartupType(StartupType, out DWORD dwStartType)) { - case ServiceStartMode.Automatic: - dwStartType = NativeMethods.SERVICE_AUTO_START; - break; - case ServiceStartMode.Manual: - dwStartType = NativeMethods.SERVICE_DEMAND_START; - break; - case ServiceStartMode.Disabled: - dwStartType = NativeMethods.SERVICE_DISABLED; - break; - default: - Diagnostics.Assert( - ((ServiceStartMode)(-1)) == StartupType, - "bad StartupType"); - break; + WriteNonTerminatingError(StartupType.ToString(), "New-Service", Name, + new ArgumentException(), "CouldNotNewService", + ServiceResources.UnsupportedStartupType, + ErrorCategory.InvalidArgument); + return; } - // set up the double-null-terminated lpDependencies parameter IntPtr lpDependencies = IntPtr.Zero; if (null != DependsOn) @@ -2410,6 +2388,43 @@ namespace Microsoft.PowerShell.Commands public static extern bool QueryInformationJobObject(SafeHandle hJob, int JobObjectInfoClass, ref JOBOBJECT_BASIC_PROCESS_ID_LIST lpJobObjectInfo, int cbJobObjectLength, IntPtr lpReturnLength); + + /// + /// Get appropriate win32 StartupType + /// + /// + /// StartupType provided by the user. + /// + /// + /// Out parameter of the native win32 StartupType + /// + /// + /// If a supported StartupType is provided, funciton returns true, otherwise false. + /// + internal static bool TryGetNativeStartupType(ServiceStartMode StartupType, out DWORD dwStartType) + { + bool success = true; + dwStartType = NativeMethods.SERVICE_NO_CHANGE; + switch (StartupType) + { + case ServiceStartMode.Automatic: + dwStartType = NativeMethods.SERVICE_AUTO_START; + break; + case ServiceStartMode.Manual: + dwStartType = NativeMethods.SERVICE_DEMAND_START; + break; + case ServiceStartMode.Disabled: + dwStartType = NativeMethods.SERVICE_DISABLED; + break; + case (ServiceStartMode)(-1): + dwStartType = NativeMethods.SERVICE_NO_CHANGE; + break; + default: + success = false; + break; + } + return success; + } } #endregion NativeMethods } diff --git a/src/Microsoft.PowerShell.Commands.Management/resources/ServiceResources.resx b/src/Microsoft.PowerShell.Commands.Management/resources/ServiceResources.resx index 0f99f066c..60ecdd041 100644 --- a/src/Microsoft.PowerShell.Commands.Management/resources/ServiceResources.resx +++ b/src/Microsoft.PowerShell.Commands.Management/resources/ServiceResources.resx @@ -201,4 +201,7 @@ 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. + + The startup type '{0}' is not supported by {1}. + 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 5a30db2fe..90b46376d 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 @@ -22,15 +22,18 @@ Describe "Set/New-Service cmdlet tests" -Tags "Feature", "RequireAdminOnWindows" @{parameter = "Status" ; value = "Running"}, @{parameter = "Status" ; value = "Stopped"}, @{parameter = "Status" ; value = "Paused"}, - @{parameter = "InputObject" ; value = (Get-Service | Select-Object -First 1)}, + @{parameter = "InputObject" ; script = {Get-Service | Select-Object -First 1}}, # cmdlet inherits this property, but it's not exposed as parameter so it should be $null @{parameter = "Include" ; value = "foo", "bar" ; expectedNull = $true}, # cmdlet inherits this property, but it's not exposed as parameter so it should be $null @{parameter = "Exclude" ; value = "foo", "bar" ; expectedNull = $true} ) { - param($parameter, $value, $expectedNull) + param($parameter, $value, $script, $expectedNull) $setServiceCommand = [Microsoft.PowerShell.Commands.SetServiceCommand]::new() + if ($script -ne $Null) { + $value = & $script + } $setServiceCommand.$parameter = $value if ($expectedNull -eq $true) { $setServiceCommand.$parameter | Should BeNullOrEmpty @@ -42,7 +45,7 @@ Describe "Set/New-Service cmdlet tests" -Tags "Feature", "RequireAdminOnWindows" It "Set-Service parameter validation for invalid values: