Fix Hyper-V Remoting when the module is imported via implicit remoting (#24032)

This commit is contained in:
Jordan Borean 2024-08-02 04:19:47 +10:00 committed by GitHub
parent 3d2e0f4d2f
commit c9bd109686
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 38 additions and 4 deletions

View File

@ -445,6 +445,37 @@ namespace Microsoft.PowerShell.Commands
FastSavingCritical,
}
#nullable enable
/// <summary>
/// Get the State property from Get-VM result.
/// </summary>
/// <param name="value">The raw PSObject as returned by Get-VM.</param>
/// <returns>The VMState value of the State property if present and parsable, otherwise null.</returns>
internal VMState? GetVMStateProperty(PSObject value)
{
object? rawState = value.Properties["State"].Value;
if (rawState is Enum enumState)
{
// If the Hyper-V module was directly importable we have the VMState enum
// value which we can just cast to our VMState type.
return (VMState)enumState;
}
else if (rawState is string stringState && Enum.TryParse(stringState, true, out VMState result))
{
// If the Hyper-V module was imported through implicit remoting on old
// Windows versions we get a string back which we will try and parse
// as the enum label.
return result;
}
// Unknown scenario, this should not happen.
string message = PSRemotingErrorInvariants.FormatResourceString(
RemotingErrorIdStrings.HyperVFailedToGetStateUnknownType,
rawState?.GetType()?.FullName ?? "null");
throw new InvalidOperationException(message);
}
#nullable disable
#endregion
#region Tracer
@ -1658,7 +1689,7 @@ namespace Microsoft.PowerShell.Commands
{
this.VMName[index] = (string)results[0].Properties["VMName"].Value;
if ((VMState)results[0].Properties["State"].Value == VMState.Running)
if (GetVMStateProperty(results[0]) == VMState.Running)
{
vmIsRunning[index] = true;
}
@ -1707,7 +1738,7 @@ namespace Microsoft.PowerShell.Commands
this.VMId[index] = (Guid)results[0].Properties["VMId"].Value;
this.VMName[index] = (string)results[0].Properties["VMName"].Value;
if ((VMState)results[0].Properties["State"].Value == VMState.Running)
if (GetVMStateProperty(results[0]) == VMState.Running)
{
vmIsRunning[index] = true;
}

View File

@ -1025,7 +1025,7 @@ namespace Microsoft.PowerShell.Commands
//
// VM should be in running state.
//
if ((VMState)results[0].Properties["State"].Value != VMState.Running)
if (GetVMStateProperty(results[0]) != VMState.Running)
{
WriteError(
new ErrorRecord(

View File

@ -932,7 +932,7 @@ namespace Microsoft.PowerShell.Commands
//
// VM should be in running state.
//
if ((VMState)results[0].Properties["State"].Value != VMState.Running)
if (GetVMStateProperty(results[0]) != VMState.Running)
{
WriteError(
new ErrorRecord(

View File

@ -1720,4 +1720,7 @@ SSH client process terminated before connection could be established.</value>
<data name="WDACGetPowerShellLogMessage" xml:space="preserve">
<value>Creating a PowerShell object from a script block may require evaluating some expressions within the script block. The expression evaluation will silently fail and return 'null' in Constrained Language mode, unless the expression represents a constant value.</value>
</data>
<data name="HyperVFailedToGetStateUnknownType" xml:space="preserve">
<value>Failed to get Hyper-V VM State. The value was of the type {0} but was expected to be Microsoft.HyperV.PowerShell.VMState or System.String.</value>
</data>
</root>