Getting Started with Adobe After Effects - Part 6: Motion Blur
First Time? You can support us by signing up. It takes only 5 seconds. Click here to sign up. If you already have an account, click here to login.
Loading

1st Prize - Apple iPad


DOTNET Quiz 2011 - How do you invoke PowerShell scripts with WCF?

  • How do you invoke PowerShell scripts with WCF?

    Posted on 01-30-2011 00:00 |
    Robert Dennyson
    11 · 14% · 4419

3  Answers  

Subscribe to Notifications
  • Score
    6

    PowerShell itself does not provide a WCF endpoint. So the easiest way is to create a WCF service in C# (or VB.NET, if you like) that consumes a powershell script and returns the result of the powershell execution.
    To call PowerShell from inside a .net application, you have to include the System.Automation namespace and provide code like this:

    public object RunPowershell(string script)
    {
        // create and open Powershell runspace
        Runspace runspace = RunspaceFactory.CreateRunspace();
        runspace.Open();
    
        // create a pipeline for the script
        Pipeline pipeline = runspace.CreatePipeline();
        pipeline.Commands.AddScript(scriptText);
    
        // execute the script
        Collection<psobject> results = pipeline.Invoke();
    
        return results;
    }
    

    The problem with this approach is that the result can be arbitrary objects, and these possibly cannot be serialized for traversal of WCF channels. So the execution of PS script should be limited to string output.
    This can be achieved by using an out-string as a last PS command, or by forcing a string conversion on exit of the RunPowershell function, like this:

        // convert the script result into a single string
        StringBuilder sb = new StringBuilder();
        foreach (PSObject result in results)
        {
            sb.AppendLine(result.ToString());
        }
        return sb.ToString();
    

    Another problem is that of impersonation. The WCF service must run as on an account that has the appropriate rights to perform the PS functions. If you run the WCF service under the Network service account, it won't be able to do anything at all, so a priviledged user should be used to host the WCF PS host.

    Replied on Jan 31 2011 2:02AM  . 
    Guenter
    28 · 6% · 1822
  • Score
    5

    1.Create the proxy code through the SDK's svcutil command

    2.Compile the code referencing the ServiceModel.dll

    3.Use reflection to load the compiled dll referencing System.ServiceModel

    4.Create the binding...In this case I used TCP

    5.Setup an SecurityMode...In this case there is 'None'

    6.Assign it to the binding

    7.Create the new service call 8.Call method on the service

    The following is powershell script to be used with .pst

    svcutil.exe http://localhost:8731/Vam/Connect/
    csc /t:library BusConnect.cs /r:"C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\System.ServiceModel.dll"
    [Reflection.Assembly]::LoadWithPartialName("System.ServiceModel")
    [Reflection.Assembly]::LoadFrom("$pwd\BusConnect.dll")
    $NetTcpBinding = new-object System.ServiceModel.NetTcpBinding
    $endpoint = new-object System.ServiceModel.EndpointAddress("net.tcp://localhost:8085/DAX/BusConnect")
    $secMode = new-object System.ServiceModel.SecurityMode
    $NetTcpBinding.Security.Mode = $secMode;
    $NudgeService = new-object BusConnectorClient($NetTcpBinding, $endpoint)
    $NudgeService.DAXNudge()
    

    Now to make sure your script knows about SvcUtil and where to find System.ServiceModel, you want to find where they are located on the system and added to the Environment Variables, "Path". You can do this easily by left clicking on Computer and going to properties then Advanced System Settings and clicking on the Advanced tab.

    Now that the paths are added to the Environment Variables, you need to setup PowerShell to run scripts.. Once setup, run the scripts by starting up powershell

    Replied on Feb 14 2011 5:01AM  . 
    Vamshi
    131 · 1% · 376
  • Score
    8

    I believe PowerShell does not expose any WCF endpoints. So, if you need to access PowerShell functionality via WCF you can implement your own WCF service. There are easy ways to access PowerShell functionality using .NET. So here are couple examples.

    First using System.Management.Automation - root namespace for Windows PowerShell. Here is an example based on How to run PowerShell scripts from C# article:

    string RunScript(string scriptText) 
    { 
    // create Powershell runspace 
    Runspace runspace = RunspaceFactory.CreateRunspace(); 
    
    // open it 
    runspace.Open(); 
    
    // create a pipeline and feed it the script text 
    Pipeline pipeline = runspace.CreatePipeline(); 
    pipeline.Commands.AddScript(scriptText); 
    
    // add an extra command to transform the script 
    // output objects into nicely formatted strings 
    
    // remove this line to get the actual objects 
    // that the script returns. For example, the script 
    
    // "Get-Process" returns a collection 
    // of System.Diagnostics.Process instances. 
    pipeline.Commands.Add("Out-String"); 
    
    // execute the script 
    Collection results = pipeline.Invoke(); 
    
    // close the runspace 
    runspace.Close(); 
    
    // convert the script result into a single string 
    StringBuilder stringBuilder = new StringBuilder(); 
    foreach (PSObject obj in results) 
    { 
    stringBuilder.AppendLine(obj.ToString()); 
    } 
    
    return stringBuilder.ToString(); 
    }
    

    Another option is to open a process powershell.exe and invoke parameter there. Here is an example based on Executing PowerShell Scripts via C# article.

    string RunScript(string scriptText)
    {
        var process = new Process();
    
        process.StartInfo.UseShellExecute = false;
        process.StartInfo.FileName = "powershell.exe";
        process.StartInfo.Arguments = " -Command \"& {" + scriptText + "}";
        process.StartInfo.RedirectStandardError = true;
        process.StartInfo.RedirectStandardOutput = true;
    
        process.Start();
    
        var output = process.StandardOutput;
        var error = process.StandardError;
    
        string result = output.ReadToEnd();
        process.WaitForExit();
        return result;
    }
    

    Calling PowerShell scripts that use WCF is not to difficult too. You can find detailed explanation on how to do so in Bayer White article Calling Up WCF From Powershell. Here I'll just quote list of actions he did to accomplish this:

    svcutil.exe http://localhost:8731/DAX/BusConnect/
    csc /t:library BusConnect.cs /r:"C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\System.ServiceModel.dll"
    [Reflection.Assembly]::LoadWithPartialName("System.ServiceModel")
    [Reflection.Assembly]::LoadFrom("$pwd\BusConnect.dll")
    $NetTcpBinding = new-object System.ServiceModel.NetTcpBinding
    $endpoint = new-object System.ServiceModel.EndpointAddress("net.tcp://localhost:8085/DAX/BusConnect")
    $secMode = new-object System.ServiceModel.SecurityMode
    $NetTcpBinding.Security.Mode = $secMode;
    $NudgeService = new-object BusConnectorClient($NetTcpBinding, $endpoint)
    $NudgeService.DAXNudge()
    
    Replied on Mar 30 2011 1:52PM  . 
    Dmitry Kharlap (aka Docker)
    148 · 1% · 325

Your Answer


Sign Up or Login to post an answer.
Please note that your answer will not be considered as part of the contest because the competition is over. You can still post an answer to share your knowledge with the community.

Copyright © Rivera Informatic Private Ltd.