0

Short description of what I`m trying to do:

I am working on a .Net WinForm application from where I am trying to run multiple PowerShell scripts on a remote server and display results on the form.

At this moment I`m executing the scripts synchronously and this is causing me problems with long running scripts.

Any idea on how I could make this function to be executed Asynchronously?

public string NewPsSession(string ServerName, string command)
    {
        Runspace runspace = RunspaceFactory.CreateRunspace();
        runspace.Open();
        PowerShell psSession = PowerShell.Create();

        psSession.Commands.AddScript("$sessions = New-PSSession -ComputerName " + ServerName + Environment.NewLine  
        + "Invoke-Command -session $sessions -ScriptBlock {" + command + "}" + Environment.NewLine                 
        + "Remove-PSSession -Session $sessions" + Environment.NewLine);

        psSession.Commands.AddCommand("Out-String");

        Collection<PSObject> results = new Collection<PSObject>();
        try
        {
            results = psSession.Invoke(); 
        }

        catch (Exception ex)
        {
            results.Add(new PSObject((object)ex.Message));
        }
        runspace.Close(); 

        StringBuilder stringBuilder = new StringBuilder();

        foreach (PSObject obj in results)
        {
            stringBuilder.AppendLine(obj.ToString());
        }

        return stringBuilder.ToString(); 
    }

Any suggestion would be much appreciated. Thanks!

0

1 Answer 1

3

Change your NewPsSesson method to async and return a Task<string>. Then move your code into a Task<string>.Run() block and await it. Then you can either await your NewPsSession() method or monitor it as a task as I have done in Main()

   class Program
    {
        public static void Main(string[] args)
        {
            Task<string> task = NewPsSession("", "");
            while (!task.IsCompleted)
            {
                Task.Delay(500).Wait();
                Console.WriteLine("Waiting...");
            }

            Console.WriteLine(task.Result);
            Console.WriteLine("Done");
        }

        public static async Task<string> NewPsSession(string ServerName, string command)
        {
            var result = await Task<string>.Run(() =>
            {
                Runspace runspace = RunspaceFactory.CreateRunspace();
                runspace.Open();
                PowerShell psSession = PowerShell.Create();

                psSession.Commands.AddScript("$sessions = New-PSSession -ComputerName " + ServerName + Environment.NewLine
                + "Invoke-Command -session $sessions -ScriptBlock {" + command + "}" + Environment.NewLine
                + "Remove-PSSession -Session $sessions" + Environment.NewLine);

                psSession.Commands.AddCommand("Out-String");

                Collection<PSObject> results = new Collection<PSObject>();
                try
                {
                    results = psSession.Invoke();
                }

                catch (Exception ex)
                {
                    results.Add(new PSObject((object)ex.Message));
                }
                runspace.Close();

                StringBuilder stringBuilder = new StringBuilder();

                foreach (PSObject obj in results)
                {
                    stringBuilder.AppendLine(obj.ToString());
                }
                return stringBuilder.ToString();
            });

            return result;

        }
}
Sign up to request clarification or add additional context in comments.

1 Comment

You're welcome. Just a note, you are creating a runspace but not actually using it. If you want to use the runspace you have to connect it to your psSession (psSession.Runspace = runspace;). The way it stands now when you execute psSession.Invoke() a new runspace is being created each time which is fine since you are only executing invoke once. You can remove the 3 lines dealing with runspace. If you were invoking the pssession more than once I would suggest connecting the psSession to a more persistent runspace.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.