Sto provando a connettermi a PowerShell remoto dall'app C# .NET WinForms. Il mio obiettivo è creare la mia versione di Microsoft PowerShell ISE. Quindi ho bisogno di un modo per eseguire gli script PowerShell dalla mia app su macchine remote. Ho creato un paio di metodi e l'ho provato sulla macchina locale dalla mia app. Se io non uso WSManConnectionInfo e utilizzare usando (spazio di esecuzione remoteRunspace = RunspaceFactory.CreateRunspace()) posso eseguire script a livello locale come se fosse vero PowerShell (piccolo script, l'utilizzo di variabili, dati di output utilizzando ft, fl, faccio un sacco di altre cose che uso solitamente con powershell.Il problema inizia quando aggiungo WSManConnectionInfo e lo indirizza al mio Exchange Server invece di utilizzare la connessione locale. Sembra che sia in grado di eseguire elementi di base come "get-mailbox "ma non appena provo a collegare le cose, usa alcune funzionalità di scripting come $ variabili che si rompono dicendo che non è supportatoConnessione a Microsoft Exchange PowerShell in C#
Allo stesso modo devo disabilitare powershell.AddCommand ("out-string"); quando non lo si usa localmente.
Un'eccezione non gestita di tipo "System.Management.Automation.RemoteException" si è verificata in System.Management.Automation.dll.
Ulteriori informazioni: Il termine "Out-String" non è riconosciuto come nome di un cmdlet, funzione, file di script o programma eseguibile. Controlla l'ortografia del nome o se è stato incluso un percorso, verifica che il percorso sia corretto e riprova.
Lo stesso errore non viene visualizzato se non forzare la connessione remota, ma semplicemente farlo localmente. Sembra che lo SchemaUri stia rendendo molto rigido l'esecuzione solo dei comandi di base. Ho visto altri esempi in cui le persone in cui utilizzando le informazioni molto diretto come noi:
powershell.AddCommand("Get-Users");
powershell.AddParameter("ResultSize", count);
Ma con questo approccio avrei dovuto definire un sacco di opzioni possibili e non vogliono passare attraverso definiscono i parametri e altre cose. Mi piacerebbe semplicemente caricare "script" ed eseguirlo proprio come nella finestra di PowerShell. Ecco un esempio di ciò che uso ora.
public static WSManConnectionInfo PowerShellConnectionInformation(string serverUrl, PSCredential psCredentials)
{
var connectionInfo = new WSManConnectionInfo(new Uri(serverUrl), "http://schemas.microsoft.com/powershell/Microsoft.Exchange", psCredentials);
//var connectionInfo = new WSManConnectionInfo(new Uri(serverUrl), "http://schemas.microsoft.com/powershell", psCredentials);
connectionInfo.AuthenticationMechanism = AuthenticationMechanism.Basic;
connectionInfo.SkipCACheck = true;
connectionInfo.SkipCNCheck = true;
connectionInfo.SkipRevocationCheck = true;
connectionInfo.MaximumConnectionRedirectionCount = 5;
connectionInfo.OperationTimeout = 150000;
return connectionInfo;
}
public static PSCredential SecurePassword(string login, string password)
{
SecureString ssLoginPassword = new SecureString();
foreach (char x in password) { ssLoginPassword.AppendChar(x); }
return new PSCredential(login, ssLoginPassword);
}
public static string RunScriptPs(WSManConnectionInfo connectionInfo, string scriptText)
{
StringBuilder stringBuilder = new StringBuilder();
// Create a remote runspace using the connection information.
//using (Runspace remoteRunspace = RunspaceFactory.CreateRunspace())
using (Runspace remoteRunspace = RunspaceFactory.CreateRunspace(connectionInfo))
{
// Establish the connection by calling the Open() method to open the runspace.
// The OpenTimeout value set previously will be applied while establishing
// the connection. Establishing a remote connection involves sending and
// receiving some data, so the OperationTimeout will also play a role in this process.
remoteRunspace.Open();
// Create a PowerShell object to run commands in the remote runspace.
using (PowerShell powershell = PowerShell.Create())
{
powershell.Runspace = remoteRunspace;
powershell.AddScript(scriptText);
//powershell.AddCommand("out-string");
powershell.Commands.Commands[0].MergeMyResults(PipelineResultTypes.Error, PipelineResultTypes.Output);
Collection<PSObject> results = powershell.Invoke();
foreach (PSObject result in results) {
stringBuilder.AppendLine(result.ToString());
}
}
// Close the connection. Call the Close() method to close the remote
// runspace. The Dispose() method (called by using primitive) will call
// the Close() method if it is not already called.
remoteRunspace.Close();
}
// convert the script result into a single string
return stringBuilder.ToString();
}
Qualche consiglio sul perché questo sta accadendo e sul modo di aggirarlo come comportarsi allo stesso modo? Ho visto un sacco di blog come this ma definire ogni comando semplice non ha senso per me. Ho anche visto un'opzione per creare una connessione locale e quindi eseguire remote connection within that ma questa deve essere l'ultima risorsa poiché si basa su molti altri fattori.
cosa fa il tuo 'serverUrl' assomigliare? –
https: //mail1.domain.local/PowerShell di solito – MadBoy