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);
|
internal ServiceStartMode startupType = (ServiceStartMode)(-1);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The following is the definition of the input parameter "Status".
|
/// The following is the definition of the input parameter "Status".
|
||||||
/// This specifies what state the service should be in (e.g. Running, Stopped,
|
/// This specifies what state the service should be in (e.g. Running, Stopped,
|
||||||
|
@ -1684,22 +1682,13 @@ namespace Microsoft.PowerShell.Commands
|
||||||
|| (ServiceStartMode)(-1) != StartupType)
|
|| (ServiceStartMode)(-1) != StartupType)
|
||||||
{
|
{
|
||||||
DWORD dwStartType = NativeMethods.SERVICE_NO_CHANGE;
|
DWORD dwStartType = NativeMethods.SERVICE_NO_CHANGE;
|
||||||
switch (StartupType)
|
if (!NativeMethods.TryGetNativeStartupType(StartupType, out dwStartType))
|
||||||
{
|
{
|
||||||
case ServiceStartMode.Automatic:
|
WriteNonTerminatingError(StartupType.ToString(), "Set-Service", Name,
|
||||||
dwStartType = NativeMethods.SERVICE_AUTO_START;
|
new ArgumentException(), "CouldNotSetService",
|
||||||
break;
|
ServiceResources.UnsupportedStartupType,
|
||||||
case ServiceStartMode.Manual:
|
ErrorCategory.InvalidArgument);
|
||||||
dwStartType = NativeMethods.SERVICE_DEMAND_START;
|
return;
|
||||||
break;
|
|
||||||
case ServiceStartMode.Disabled:
|
|
||||||
dwStartType = NativeMethods.SERVICE_DISABLED;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
Diagnostics.Assert(
|
|
||||||
((ServiceStartMode)(-1)) == StartupType,
|
|
||||||
"bad StartupType");
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
bool succeeded = NativeMethods.ChangeServiceConfigW(
|
bool succeeded = NativeMethods.ChangeServiceConfigW(
|
||||||
hService,
|
hService,
|
||||||
|
@ -2002,25 +1991,14 @@ namespace Microsoft.PowerShell.Commands
|
||||||
ErrorCategory.PermissionDenied);
|
ErrorCategory.PermissionDenied);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
DWORD dwStartType = NativeMethods.SERVICE_AUTO_START;
|
if (!NativeMethods.TryGetNativeStartupType(StartupType, out DWORD dwStartType))
|
||||||
switch (StartupType)
|
|
||||||
{
|
{
|
||||||
case ServiceStartMode.Automatic:
|
WriteNonTerminatingError(StartupType.ToString(), "New-Service", Name,
|
||||||
dwStartType = NativeMethods.SERVICE_AUTO_START;
|
new ArgumentException(), "CouldNotNewService",
|
||||||
break;
|
ServiceResources.UnsupportedStartupType,
|
||||||
case ServiceStartMode.Manual:
|
ErrorCategory.InvalidArgument);
|
||||||
dwStartType = NativeMethods.SERVICE_DEMAND_START;
|
return;
|
||||||
break;
|
|
||||||
case ServiceStartMode.Disabled:
|
|
||||||
dwStartType = NativeMethods.SERVICE_DISABLED;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
Diagnostics.Assert(
|
|
||||||
((ServiceStartMode)(-1)) == StartupType,
|
|
||||||
"bad StartupType");
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// set up the double-null-terminated lpDependencies parameter
|
// set up the double-null-terminated lpDependencies parameter
|
||||||
IntPtr lpDependencies = IntPtr.Zero;
|
IntPtr lpDependencies = IntPtr.Zero;
|
||||||
if (null != DependsOn)
|
if (null != DependsOn)
|
||||||
|
@ -2410,6 +2388,43 @@ namespace Microsoft.PowerShell.Commands
|
||||||
public static extern bool QueryInformationJobObject(SafeHandle hJob, int JobObjectInfoClass,
|
public static extern bool QueryInformationJobObject(SafeHandle hJob, int JobObjectInfoClass,
|
||||||
ref JOBOBJECT_BASIC_PROCESS_ID_LIST lpJobObjectInfo,
|
ref JOBOBJECT_BASIC_PROCESS_ID_LIST lpJobObjectInfo,
|
||||||
int cbJobObjectLength, IntPtr lpReturnLength);
|
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
|
#endregion NativeMethods
|
||||||
}
|
}
|
||||||
|
|
|
@ -201,4 +201,7 @@
|
||||||
<data name="ComputerAccessDenied" xml:space="preserve">
|
<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>
|
<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>
|
||||||
|
<data name="UnsupportedStartupType" xml:space="preserve">
|
||||||
|
<value>The startup type '{0}' is not supported by {1}.</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
|
|
|
@ -22,15 +22,18 @@ Describe "Set/New-Service cmdlet tests" -Tags "Feature", "RequireAdminOnWindows"
|
||||||
@{parameter = "Status" ; value = "Running"},
|
@{parameter = "Status" ; value = "Running"},
|
||||||
@{parameter = "Status" ; value = "Stopped"},
|
@{parameter = "Status" ; value = "Stopped"},
|
||||||
@{parameter = "Status" ; value = "Paused"},
|
@{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
|
# cmdlet inherits this property, but it's not exposed as parameter so it should be $null
|
||||||
@{parameter = "Include" ; value = "foo", "bar" ; expectedNull = $true},
|
@{parameter = "Include" ; value = "foo", "bar" ; expectedNull = $true},
|
||||||
# cmdlet inherits this property, but it's not exposed as parameter so it should be $null
|
# cmdlet inherits this property, but it's not exposed as parameter so it should be $null
|
||||||
@{parameter = "Exclude" ; value = "foo", "bar" ; expectedNull = $true}
|
@{parameter = "Exclude" ; value = "foo", "bar" ; expectedNull = $true}
|
||||||
) {
|
) {
|
||||||
param($parameter, $value, $expectedNull)
|
param($parameter, $value, $script, $expectedNull)
|
||||||
|
|
||||||
$setServiceCommand = [Microsoft.PowerShell.Commands.SetServiceCommand]::new()
|
$setServiceCommand = [Microsoft.PowerShell.Commands.SetServiceCommand]::new()
|
||||||
|
if ($script -ne $Null) {
|
||||||
|
$value = & $script
|
||||||
|
}
|
||||||
$setServiceCommand.$parameter = $value
|
$setServiceCommand.$parameter = $value
|
||||||
if ($expectedNull -eq $true) {
|
if ($expectedNull -eq $true) {
|
||||||
$setServiceCommand.$parameter | Should BeNullOrEmpty
|
$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 @(
|
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"
|
errorid = "CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.SetServiceCommand"
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
|
@ -58,6 +61,7 @@ Describe "Set/New-Service cmdlet tests" -Tags "Feature", "RequireAdminOnWindows"
|
||||||
) {
|
) {
|
||||||
param($parameter, $value, $expected)
|
param($parameter, $value, $expected)
|
||||||
$currentService = Get-CimInstance -ClassName Win32_Service -Filter "Name='spooler'"
|
$currentService = Get-CimInstance -ClassName Win32_Service -Filter "Name='spooler'"
|
||||||
|
$originalStartupType = (Get-Service -Name spooler).StartType
|
||||||
try {
|
try {
|
||||||
$setServiceCommand = [Microsoft.PowerShell.Commands.SetServiceCommand]::new()
|
$setServiceCommand = [Microsoft.PowerShell.Commands.SetServiceCommand]::new()
|
||||||
$setServiceCommand.Name = "Spooler"
|
$setServiceCommand.Name = "Spooler"
|
||||||
|
@ -76,7 +80,7 @@ Describe "Set/New-Service cmdlet tests" -Tags "Feature", "RequireAdminOnWindows"
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
if ($parameter -eq "StartupType") {
|
if ($parameter -eq "StartupType") {
|
||||||
$setServiceCommand.StartupType = $currentService.StartMode
|
$setServiceCommand.StartupType = $originalStartupType
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$setServiceCommand.$parameter = $currentService.$parameter
|
$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 @(
|
It "Using bad parameters will fail for '<name>' where '<parameter>' = '<value>'" -TestCases @(
|
||||||
@{name = 'credtest' ; parameter = "Credential" ; value = (
|
@{cmdlet="New-Service"; name = 'credtest' ; parameter = "Credential" ; value = (
|
||||||
[System.Management.Automation.PSCredential]::new("username",
|
[System.Management.Automation.PSCredential]::new("username",
|
||||||
(ConvertTo-SecureString "PlainTextPassword" -AsPlainText -Force)))
|
(ConvertTo-SecureString "PlainTextPassword" -AsPlainText -Force)));
|
||||||
},
|
errorid = "CouldNotNewService,Microsoft.PowerShell.Commands.NewServiceCommand"},
|
||||||
# This test case fails due to #4803. Disabled for now.
|
@{cmdlet="New-Service"; name = 'badstarttype'; parameter = "StartupType"; value = "System";
|
||||||
# @{name = 'badstarttype'; parameter = "StartupType"; value = "System"},
|
errorid = "CouldNotNewService,Microsoft.PowerShell.Commands.NewServiceCommand"},
|
||||||
@{name = 'winmgmt' ; parameter = "DisplayName"; value = "foo"}
|
@{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)
|
param($cmdlet, $name, $parameter, $value, $errorid)
|
||||||
$parameters = @{$parameter = $value; Name = $name; Binary = "$PSHOME\powershell.exe"; ErrorAction = "Stop"}
|
$parameters = @{$parameter = $value; Name = $name; ErrorAction = "Stop"}
|
||||||
{ New-Service @parameters } | ShouldBeErrorId "CouldNotNewService,Microsoft.PowerShell.Commands.NewServiceCommand"
|
if ($cmdlet -eq "New-Service") {
|
||||||
|
$parameters += @{Binary = "$PSHOME\powershell.exe"};
|
||||||
|
}
|
||||||
|
{ & $cmdlet @parameters } | ShouldBeErrorId $errorid
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue