diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/ComputerUnix.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/ComputerUnix.cs
index a11fb0270c9..eb286f7c190 100644
--- a/src/Microsoft.PowerShell.Commands.Management/commands/management/ComputerUnix.cs
+++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/ComputerUnix.cs
@@ -5,10 +5,13 @@
using System;
using System.Diagnostics;
+using System.IO;
using System.Management.Automation;
using System.Management.Automation.Internal;
using System.Runtime.InteropServices;
+#nullable enable
+
namespace Microsoft.PowerShell.Commands
{
#region Restart-Computer
@@ -36,13 +39,13 @@ protected override void BeginProcessing()
{
string errMsg = StringUtil.Format("Command returned 0x{0:X}", retVal);
ErrorRecord error = new ErrorRecord(
- new InvalidOperationException(errMsg), "Command Failed", ErrorCategory.OperationStopped, "localhost");
+ new InvalidOperationException(errMsg), "CommandFailed", ErrorCategory.OperationStopped, "localhost");
WriteError(error);
}
return;
}
- RunCommand("/sbin/shutdown", "-r now");
+ RunShutdown("-r now");
}
#endregion "Overrides"
}
@@ -78,13 +81,13 @@ protected override void BeginProcessing()
{
string errMsg = StringUtil.Format("Command returned 0x{0:X}", retVal);
ErrorRecord error = new ErrorRecord(
- new InvalidOperationException(errMsg), "Command Failed", ErrorCategory.OperationStopped, "localhost");
+ new InvalidOperationException(errMsg), "CommandFailed", ErrorCategory.OperationStopped, "localhost");
WriteError(error);
}
return;
}
- RunCommand("/sbin/shutdown", args);
+ RunShutdown(args);
}
#endregion "Overrides"
}
@@ -95,7 +98,7 @@ protected override void BeginProcessing()
public class CommandLineCmdletBase : PSCmdlet, IDisposable
{
#region Private Members
- private Process _process = null;
+ private Process? _process = null;
#endregion
#region "IDisposable Members"
@@ -150,22 +153,52 @@ protected override void StopProcessing()
#region "Internals"
+ private static string? shutdownPath;
+
///
- /// Run a command.
+ /// Run shutdown command.
///
- protected void RunCommand(String command, String args) {
+ protected void RunShutdown(String args)
+ {
+ if (shutdownPath is null)
+ {
+ CommandInfo cmdinfo = CommandDiscovery.LookupCommandInfo(
+ "shutdown", CommandTypes.Application,
+ SearchResolutionOptions.None, CommandOrigin.Internal, this.Context);
+
+ if (cmdinfo is not null)
+ {
+ shutdownPath = cmdinfo.Definition;
+ }
+ else
+ {
+ ErrorRecord error = new ErrorRecord(
+ new InvalidOperationException(ComputerResources.ShutdownCommandNotFound), "CommandNotFound", ErrorCategory.ObjectNotFound, targetObject: null);
+ ThrowTerminatingError(error);
+ }
+ }
+
_process = new Process()
{
StartInfo = new ProcessStartInfo
{
- FileName = "/sbin/shutdown",
+ FileName = shutdownPath,
Arguments = string.Empty,
RedirectStandardOutput = false,
+ RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true,
}
};
_process.Start();
+ _process.WaitForExit();
+ if (_process.ExitCode != 0)
+ {
+ string stderr = _process.StandardError.ReadToEnd();
+ ErrorRecord error = new ErrorRecord(
+ new InvalidOperationException(stderr), "CommandFailed", ErrorCategory.OperationStopped, null);
+ ThrowTerminatingError(error);
+ }
}
#endregion
}
diff --git a/src/Microsoft.PowerShell.Commands.Management/resources/ComputerResources.resx b/src/Microsoft.PowerShell.Commands.Management/resources/ComputerResources.resx
index 63a671c0248..95685239fd7 100644
--- a/src/Microsoft.PowerShell.Commands.Management/resources/ComputerResources.resx
+++ b/src/Microsoft.PowerShell.Commands.Management/resources/ComputerResources.resx
@@ -387,4 +387,7 @@
The {0} parameter is not supported for CoreCLR.
+
+ The required native command 'shutdown' was not found.
+
diff --git a/src/Microsoft.PowerShell.ConsoleHost/resources/ConsoleHostStrings.resx b/src/Microsoft.PowerShell.ConsoleHost/resources/ConsoleHostStrings.resx
index e8dcccb3dee..ce124ec084c 100644
--- a/src/Microsoft.PowerShell.ConsoleHost/resources/ConsoleHostStrings.resx
+++ b/src/Microsoft.PowerShell.ConsoleHost/resources/ConsoleHostStrings.resx
@@ -164,9 +164,6 @@ End time: {0:yyyyMMddHHmmss}
{0}:{1,-3} {2}
-
- An error occurred while running '{0}': {1}
-
The current session does not support debugging; execution will continue.
diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/Restart-Computer.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/Restart-Computer.Tests.ps1
index 8a2c050a90f..9f845f81af9 100644
--- a/test/powershell/Modules/Microsoft.PowerShell.Management/Restart-Computer.Tests.ps1
+++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Restart-Computer.Tests.ps1
@@ -107,3 +107,16 @@ finally
Disable-Testhook -testhookName $restartTesthookName
Set-TesthookResult -testhookName $restartTesthookResultName -value 0
}
+
+Describe 'Non-admin on Unix' {
+ BeforeAll {
+ $skip = $false
+ if ($IsWindows -or [environment]::IsPrivilegedProcess -or ($null -eq (Get-Command shutdown -CommandType Application -ErrorAction Ignore))) {
+ $skip = $true
+ }
+ }
+
+ It 'Reports error if not run under sudo' -Skip:($skip) {
+ { Restart-Computer -ErrorAction Stop } | Should -Throw -ErrorId "CommandFailed,Microsoft.PowerShell.Commands.RestartComputerCommand"
+ }
+}
diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/Stop-Computer.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/Stop-Computer.Tests.ps1
index c2a89117167..1bda1471e78 100644
--- a/test/powershell/Modules/Microsoft.PowerShell.Management/Stop-Computer.Tests.ps1
+++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Stop-Computer.Tests.ps1
@@ -58,3 +58,16 @@ finally
Disable-Testhook -testhookName $stopTesthook
Set-TesthookResult -testhookName $stopTesthookResultName -Value $DefaultResultValue
}
+
+Describe 'Non-admin on Unix' {
+ BeforeAll {
+ $skip = $false
+ if ($IsWindows -or [environment]::IsPrivilegedProcess -or ($null -eq (Get-Command shutdown -CommandType Application -ErrorAction Ignore))) {
+ $skip = $true
+ }
+ }
+
+ It 'Reports error if not run under sudo' -Skip:($skip) {
+ { Stop-Computer -ErrorAction Stop } | Should -Throw -ErrorId "CommandFailed,Microsoft.PowerShell.Commands.StopComputerCommand"
+ }
+}