Refactor and implement Restart-Computer for Un*x and macOS (#11319)

Co-authored-by: Ilya <darpa@yandex.ru>
This commit is contained in:
Brendan Burns
2020-02-03 14:57:17 -08:00
committed by GitHub
co-authored by Ilya
parent 6c6c9cc41e
commit 127fec5eb9
6 changed files with 99 additions and 37 deletions
@@ -6,10 +6,48 @@
using System;
using System.Diagnostics;
using System.Management.Automation;
using System.Management.Automation.Internal;
using System.Runtime.InteropServices;
namespace Microsoft.PowerShell.Commands
{
#region Restart-Computer
/// <summary>
/// Cmdlet to restart computer.
/// </summary>
[Cmdlet(VerbsLifecycle.Restart, "Computer", SupportsShouldProcess = true,
HelpUri = "https://go.microsoft.com/fwlink/?LinkID=2097060", RemotingCapability = RemotingCapability.SupportedByCommand)]
public sealed class RestartComputerCommand : CommandLineCmdletBase
{
// TODO: Support remote computers?
#region "Overrides"
/// <summary>
/// BeginProcessing.
/// </summary>
protected override void BeginProcessing()
{
if (InternalTestHooks.TestStopComputer)
{
var retVal = InternalTestHooks.TestStopComputerResults;
if (retVal != 0)
{
string errMsg = StringUtil.Format("Command returned 0x{0:X}", retVal);
ErrorRecord error = new ErrorRecord(
new InvalidOperationException(errMsg), "Command Failed", ErrorCategory.OperationStopped, "localhost");
WriteError(error);
}
return;
}
RunCommand("/sbin/shutdown", "-r now");
}
#endregion "Overrides"
}
#endregion Restart-Computer
#region Stop-Computer
/// <summary>
@@ -17,16 +55,49 @@ namespace Microsoft.PowerShell.Commands
/// </summary>
[Cmdlet(VerbsLifecycle.Stop, "Computer", SupportsShouldProcess = true,
HelpUri = "https://go.microsoft.com/fwlink/?LinkID=2097151", RemotingCapability = RemotingCapability.SupportedByCommand)]
public sealed class StopComputerCommand : PSCmdlet, IDisposable
public sealed class StopComputerCommand : CommandLineCmdletBase
{
// TODO: Support remote computers?
#region "Overrides"
/// <summary>
/// BeginProcessing.
/// </summary>
protected override void BeginProcessing()
{
var args = "-P now";
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
args = "now";
}
if (InternalTestHooks.TestStopComputer)
{
var retVal = InternalTestHooks.TestStopComputerResults;
if (retVal != 0)
{
string errMsg = StringUtil.Format("Command returned 0x{0:X}", retVal);
ErrorRecord error = new ErrorRecord(
new InvalidOperationException(errMsg), "Command Failed", ErrorCategory.OperationStopped, "localhost");
WriteError(error);
}
return;
}
RunCommand("/sbin/shutdown", args);
}
#endregion "Overrides"
}
/// <summary>
/// A base class for cmdlets that can run shell commands.
/// </summary>
public class CommandLineCmdletBase : PSCmdlet, IDisposable
{
#region Private Members
private Process _process = null;
#endregion
// TODO: Support remote computers?
#region "IDisposable Members"
/// <summary>
@@ -40,15 +111,6 @@ namespace Microsoft.PowerShell.Commands
#endregion "IDisposable Members"
#region "Overrides"
/// <summary>
/// BeginProcessing.
/// </summary>
protected override void BeginProcessing()
{
doShutdown();
}
/// <summary>
/// To implement ^C.
/// </summary>
@@ -67,21 +129,15 @@ namespace Microsoft.PowerShell.Commands
catch (InvalidOperationException) {}
catch (NotSupportedException) {}
}
#endregion "Overrides"
#region "Internals"
private void doShutdown() {
/// <summary>
/// Run a command.
/// </summary>
protected void RunCommand(String command, String args) {
String cmd = "";
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
cmd = "-P now";
}
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
cmd = "now";
}
_process = new Process()
{
@@ -55,5 +55,6 @@ CmdletsToExport=@("Add-Content",
"Set-Content",
"Set-ItemProperty",
"Get-TimeZone",
"Stop-Computer")
"Stop-Computer",
"Restart-Computer")
}
@@ -9,7 +9,6 @@ $DefaultResultValue = 0
try
{
# set up for testing
$PSDefaultParameterValues["it:skip"] = ! $IsWindows
Enable-Testhook -testhookName $restartTesthookName
Describe "Restart-Computer" -Tag Feature,RequireAdminOnWindows {
@@ -29,13 +28,13 @@ try
Restart-Computer -ErrorAction Stop | Should -BeNullOrEmpty
}
It "Should support -computer parameter" {
It "Should support -computer parameter" -Skip:(!$IsWindows) {
Set-TesthookResult -testhookName $restartTesthookResultName -value $defaultResultValue
$computerNames = "localhost","${env:COMPUTERNAME}"
Restart-Computer -Computer $computerNames -ErrorAction Stop | Should -BeNullOrEmpty
}
It "Should support WsmanAuthentication types" {
It "Should support WsmanAuthentication types" -Skip:(!$IsWindows) {
$authChoices = "Default","Basic","Negotiate","CredSSP","Digest","Kerberos"
foreach ( $auth in $authChoices ) {
Restart-Computer -WsmanAuthentication $auth | Should -BeNullOrEmpty
@@ -45,7 +44,7 @@ try
# this requires setting a test hook, so we wrap the execution with try/finally of the
# set operation. Internally, we want to suppress the progress, so
# that is also wrapped in try/finally
It "Should wait for a remote system" {
It "Should wait for a remote system" -Skip:(!$IsWindows) {
try
{
Enable-Testhook -testhookname TestWaitStopComputer
@@ -77,16 +76,24 @@ try
$RestartError.Exception.Message | Should -Match 0x300000
}
It "Should produce an error when 'Delay' is specified" {
It "Should produce an error when 'Delay' is specified" -Skip:(!$IsWindows) {
{ Restart-Computer -Delay 30 } | Should -Throw -ErrorId "RestartComputerInvalidParameter,Microsoft.PowerShell.Commands.RestartComputerCommand"
}
It "Should not support timeout on localhost" {
It "Should not support timeout on Unix" -Skip:($IsWindows) {
{ Restart-Computer -timeout 3 -ErrorAction Stop } | Should -Throw -ErrorId "NamedParameterNotFound,Microsoft.PowerShell.Commands.RestartComputerCommand"
}
It "Should not support Delay on Unix" -Skip:($IsWindows) {
{ Restart-Computer -Delay 30 } | Should -Throw -ErrorId "NamedParameterNotFound,Microsoft.PowerShell.Commands.RestartComputerCommand"
}
It "Should not support timeout on localhost" -Skip:(!$IsWindows) {
Set-TesthookResult -testhookName $restartTesthookResultName -value $defaultResultValue
{ Restart-Computer -timeout 3 -ErrorAction Stop } | Should -Throw -ErrorId "RestartComputerInvalidParameter,Microsoft.PowerShell.Commands.RestartComputerCommand"
}
It "Should not support timeout on localhost" {
It "Should not support timeout on localhost" -Skip:(!$IsWindows) {
Set-TesthookResult -testhookName $restartTesthookResultName -value $defaultResultValue
{ Restart-Computer -timeout 3 -ErrorAction Stop } | Should -Throw -ErrorId "RestartComputerInvalidParameter,Microsoft.PowerShell.Commands.RestartComputerCommand"
}
@@ -10,7 +10,6 @@ $DefaultResultValue = 0
try
{
# set up for testing
$PSDefaultParameterValues["it:skip"] = ! $IsWindows
Enable-Testhook -testhookName $stopTesthook
Describe "Stop-Computer" -Tag Feature {
@@ -30,13 +29,13 @@ try
Stop-Computer -ErrorAction Stop | Should -BeNullOrEmpty
}
It "Should support -Computer parameter" {
It "Should support -Computer parameter" -Skip:(!$IsWindows) {
Set-TesthookResult -testhookName $stopTesthookResultName -Value $defaultResultValue
$computerNames = "localhost","${env:COMPUTERNAME}"
Stop-Computer -Computer $computerNames -ErrorAction Stop | Should -BeNullOrEmpty
}
It "Should support WsmanAuthentication types" {
It "Should support WsmanAuthentication types" -Skip:(!$IsWindows) {
$authChoices = "Default","Basic","Negotiate","CredSSP","Digest","Kerberos"
foreach ( $auth in $authChoices ) {
Stop-Computer -WsmanAuthentication $auth | Should -BeNullOrEmpty
@@ -12,7 +12,6 @@ Describe "Unimplemented Management Cmdlet Tests" -Tags "CI" {
"Set-Service",
"New-Service",
"Restart-Computer",
"Rename-Computer",
"Get-ComputerInfo",
@@ -407,7 +407,7 @@ Describe "Verify approved aliases list" -Tags "CI" {
"Cmdlet", "Rename-ItemProperty", "", $($FullCLR -or $CoreWindows -or $CoreUnix), "", "", "Medium"
"Cmdlet", "Reset-ComputerMachinePassword", "", $($FullCLR ), "", "", ""
"Cmdlet", "Resolve-Path", "", $($FullCLR -or $CoreWindows -or $CoreUnix), "", "", "None"
"Cmdlet", "Restart-Computer", "", $($FullCLR -or $CoreWindows ), "", "", "Medium"
"Cmdlet", "Restart-Computer", "", $($FullCLR -or $CoreWindows -or $CoreUnix), "", "", "Medium"
"Cmdlet", "Restart-Service", "", $($FullCLR -or $CoreWindows ), "", "", "Medium"
"Cmdlet", "Restore-Computer", "", $($FullCLR ), "", "", ""
"Cmdlet", "Resume-Job", "", $($FullCLR ), "", "", ""