-
Notifications
You must be signed in to change notification settings - Fork 207
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merged PR 7676063: Fix platform auto-detect issue on Linux drivers fo…
…r PTM Service 1. This change fixes issue with PTM Service on Linux drivers being unable to get platform details from the SUT using WMI (since .NET Core on Linux does not support WMI). Support for PS Remoting over SSH using public/private key authentication is added to allow Linux clients get the platform details over this channel. 2. This change also introduces a work around for an issue with peer dependencies in the build pipeline for PTM Service by adding _--legacy-peer-deps_ to the npm install command. The issue is described [here](https://stackoverflow.com/questions/69259024/how-to-handle-conflicting-peer-dependencies). ## Pull Request Checklist ### General - [ ] Are all regression test passed? - [ ] Are there any test cases that will expose unfixed TDIs or Windows bugs? ### New Test Case - [ ] Have Design Spec and User Guide been updated? - [ ] Can all the test cases be loaded and executed by PTM & PTMCli? - [ ] Can the related changes support multiple platform(Windows, Linux, MacOS)? ### SDK Changes - [ ] Are all related test suites Regression passed?
- Loading branch information
Bewaji Olumuyiwa
committed
Aug 11, 2022
1 parent
80b0387
commit 58dbc7c
Showing
4 changed files
with
152 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
127 changes: 127 additions & 0 deletions
127
TestSuites/FileServer/src/Plugin/FileServerPlugin/PSRemotingSession.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
// Copyright (c) Microsoft. All rights reserved. | ||
// Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Collections.ObjectModel; | ||
using System.Linq; | ||
using System.Management.Automation; | ||
using Sma = System.Management.Automation; | ||
using System.Management.Automation.Runspaces; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
using Newtonsoft.Json.Linq; | ||
|
||
namespace Microsoft.Protocols.Tools | ||
{ | ||
/// <summary> | ||
/// Driver class for hosting a PSRemoting session. | ||
/// </summary> | ||
public class PSRemotingSession | ||
{ | ||
private readonly string hostName; | ||
private readonly string userName; | ||
private readonly string keyFilePath; | ||
|
||
/// <summary> | ||
/// Creates an instance of <see cref="PSRemotingSession" /> | ||
/// </summary> | ||
/// <param name="hostName">The computer name or IP address of the remote host.</param> | ||
/// <param name="userName">The userName for running the session on the remote machine.</param> | ||
/// <param name="keyFilePath">Path to the private key file to use for authenticating. If this parameter is not specified, the sshd service will attempt to use one in the default location.</param> | ||
public PSRemotingSession(string hostName, string userName, string keyFilePath = null) | ||
{ | ||
this.hostName = hostName; | ||
this.userName = userName; | ||
this.keyFilePath = keyFilePath; | ||
} | ||
|
||
/// <summary> | ||
/// Runs a PowerShell script remotely and returns the result as a JSON array. | ||
/// </summary> | ||
/// <param name="script">The PowerShell script to run.</param> | ||
/// <returns>The result of the script execution.</returns> | ||
/// <exception cref="AggregateException">Thrown if there are any errors returned by the script execution.</exception> | ||
/// <exception cref="InvalidOperationException">Thrown if there is an error connecting to the remote host.</exception> | ||
public JArray Invoke(string script) | ||
{ | ||
using (Runspace runspace = RunspaceFactory.CreateRunspace()) | ||
{ | ||
using (Sma.PowerShell powershell = Sma.PowerShell.Create()) | ||
{ | ||
|
||
var command = new PSCommand(); | ||
command.AddCommand("New-PSSession"); | ||
command.AddParameter("HostName", this.hostName); | ||
command.AddParameter("Username", this.userName); | ||
|
||
if(!String.IsNullOrWhiteSpace(this.keyFilePath)) | ||
{ | ||
command.AddParameter("KeyFilePath", this.keyFilePath); | ||
} | ||
|
||
powershell.Commands = command; | ||
runspace.Open(); | ||
powershell.Runspace = runspace; | ||
Collection<PSSession> result = powershell.Invoke<PSSession>(); | ||
|
||
var exceptions = powershell.Streams.Error.Select(e => e.Exception).ToArray(); | ||
if(exceptions.Any()) | ||
{ | ||
throw new AggregateException(exceptions); | ||
} | ||
|
||
if (result.Count != 1) | ||
{ | ||
throw new InvalidOperationException("Unexpected number of Remote Runspace connections returned."); | ||
} | ||
|
||
command = new PSCommand(); | ||
command.AddCommand("Set-Variable"); | ||
command.AddParameter("Name", "session"); | ||
command.AddParameter("Value", result[0]); | ||
powershell.Commands = command; | ||
powershell.Runspace = runspace; | ||
powershell.Invoke(); | ||
|
||
command = new PSCommand(); | ||
command.AddScript("Enter-PSSession $session"); | ||
powershell.Commands = command; | ||
powershell.Runspace = runspace; | ||
powershell.Invoke(); | ||
|
||
command = new PSCommand(); | ||
var scriptBlock = @$"Invoke-Command $session -ScriptBlock {{ | ||
{script} | ||
}}"; | ||
command.AddScript(scriptBlock); | ||
powershell.Commands = command; | ||
powershell.Runspace = runspace; | ||
|
||
Collection<PSObject> results = new Collection<PSObject>(); | ||
results = powershell.Invoke(); | ||
|
||
var resultArray = new JArray(); | ||
foreach (PSObject psObject in results) | ||
{ | ||
var item = new JObject(); | ||
foreach (PSPropertyInfo prop in psObject.Properties) | ||
{ | ||
var name = prop.Name; | ||
var value = prop.Value; | ||
|
||
if (prop.Value != default(object)) | ||
{ | ||
item[prop.Name] = JToken.FromObject(prop.Value); | ||
} | ||
} | ||
|
||
resultArray.Add(item); | ||
} | ||
|
||
return resultArray; | ||
} | ||
} | ||
} | ||
} | ||
} |