fix set-service failing test (#4802)
* Add '-ErrorAction Stop' in Set-Service.Tests.ps1 to correctly test exceptions. * Refactor StartupType service code and add a throw for disabled startup types (System, Boot). * Made StartupType(-1) equivalent to Win32 SERVICE_NO_CHANGE.
This commit is contained in:
parent
da49841f16
commit
b723d6b7f2
|
@ -1511,8 +1511,6 @@ namespace Microsoft.PowerShell.Commands
|
|||
internal ServiceStartMode startupType = (ServiceStartMode)(-1);
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 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);
|
||||
|
||||
/// <summary>
|
||||
/// Get appropriate win32 StartupType
|
||||
/// </summary>
|
||||
/// <param name="StartupType">
|
||||
/// StartupType provided by the user.
|
||||
/// </param>
|
||||
/// <param name="dwStartType">
|
||||
/// Out parameter of the native win32 StartupType
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// If a supported StartupType is provided, funciton returns true, otherwise false.
|
||||
/// </returns>
|
||||
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
|
||||
}
|
||||
|
|
|
@ -201,4 +201,7 @@
|
|||
<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>
|
||||
<data name="UnsupportedStartupType" xml:space="preserve">
|
||||
<value>The startup type '{0}' is not supported by {1}.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
|
@ -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: <script>" -TestCases @(
|
||||
@{
|
||||
script = {Set-Service foo -StartupType bar};
|
||||
script = {Set-Service foo -StartupType bar -ErrorAction Stop};
|
||||
errorid = "CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.SetServiceCommand"
|
||||
}
|
||||
) {
|
||||
|
@ -58,6 +61,7 @@ Describe "Set/New-Service cmdlet tests" -Tags "Feature", "RequireAdminOnWindows"
|
|||
) {
|
||||
param($parameter, $value, $expected)
|
||||
$currentService = Get-CimInstance -ClassName Win32_Service -Filter "Name='spooler'"
|
||||
$originalStartupType = (Get-Service -Name spooler).StartType
|
||||
try {
|
||||
$setServiceCommand = [Microsoft.PowerShell.Commands.SetServiceCommand]::new()
|
||||
$setServiceCommand.Name = "Spooler"
|
||||
|
@ -76,7 +80,7 @@ Describe "Set/New-Service cmdlet tests" -Tags "Feature", "RequireAdminOnWindows"
|
|||
}
|
||||
finally {
|
||||
if ($parameter -eq "StartupType") {
|
||||
$setServiceCommand.StartupType = $currentService.StartMode
|
||||
$setServiceCommand.StartupType = $originalStartupType
|
||||
}
|
||||
else {
|
||||
$setServiceCommand.$parameter = $currentService.$parameter
|
||||
|
@ -158,17 +162,23 @@ Describe "Set/New-Service cmdlet tests" -Tags "Feature", "RequireAdminOnWindows"
|
|||
}
|
||||
}
|
||||
|
||||
It "New-Service with bad parameters will fail for '<name>' where '<parameter>' = '<value>'" -TestCases @(
|
||||
@{name = 'credtest' ; parameter = "Credential" ; value = (
|
||||
It "Using bad parameters will fail for '<name>' where '<parameter>' = '<value>'" -TestCases @(
|
||||
@{cmdlet="New-Service"; name = 'credtest' ; parameter = "Credential" ; value = (
|
||||
[System.Management.Automation.PSCredential]::new("username",
|
||||
(ConvertTo-SecureString "PlainTextPassword" -AsPlainText -Force)))
|
||||
},
|
||||
# This test case fails due to #4803. Disabled for now.
|
||||
# @{name = 'badstarttype'; parameter = "StartupType"; value = "System"},
|
||||
@{name = 'winmgmt' ; parameter = "DisplayName"; value = "foo"}
|
||||
(ConvertTo-SecureString "PlainTextPassword" -AsPlainText -Force)));
|
||||
errorid = "CouldNotNewService,Microsoft.PowerShell.Commands.NewServiceCommand"},
|
||||
@{cmdlet="New-Service"; name = 'badstarttype'; parameter = "StartupType"; value = "System";
|
||||
errorid = "CouldNotNewService,Microsoft.PowerShell.Commands.NewServiceCommand"},
|
||||
@{cmdlet="New-Service"; name = 'winmgmt' ; parameter = "DisplayName"; value = "foo";
|
||||
errorid = "CouldNotNewService,Microsoft.PowerShell.Commands.NewServiceCommand"},
|
||||
@{cmdlet="Set-Service"; name = 'winmgmt' ; parameter = "StartupType"; value = "Boot";
|
||||
errorid = "CouldNotSetService,Microsoft.PowerShell.Commands.SetServiceCommand"}
|
||||
) {
|
||||
param($name, $parameter, $value)
|
||||
$parameters = @{$parameter = $value; Name = $name; Binary = "$PSHOME\powershell.exe"; ErrorAction = "Stop"}
|
||||
{ New-Service @parameters } | ShouldBeErrorId "CouldNotNewService,Microsoft.PowerShell.Commands.NewServiceCommand"
|
||||
param($cmdlet, $name, $parameter, $value, $errorid)
|
||||
$parameters = @{$parameter = $value; Name = $name; ErrorAction = "Stop"}
|
||||
if ($cmdlet -eq "New-Service") {
|
||||
$parameters += @{Binary = "$PSHOME\powershell.exe"};
|
||||
}
|
||||
{ & $cmdlet @parameters } | ShouldBeErrorId $errorid
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue