Can I pass two parameters to pipeline?












2















I wrote a PowerShell cmdlet in C# which originally took several parameters, but only accepted one from pipeline input. I condensed the other parameters into a single, custom C# object, which I want to take as input from the pipeline. Here is the relevant code:



[Parameter(ValueFromPipeline = true, Mandatory = true)]
public DataObj Data {get; set;}

[Parameter(ValueFromPipeline = true, Mandatory = false)]
public DataSettings Settings {get; set;} = new DataSettings();

public class DataObj {
public string Name {get; set;}
public int Value {get; set;}
...
}

public class DataSettings {
public DataInfo Info {get; set;} = new DataInfo();
public string Description {get; set} = "";
}


I have been able to succesfully create the DataSettings object from a HashTable in PowerShell before modified it to be taken as pipeline input.



I have tried:



@{Data = $DataObj; Settings = $DataSettings;} | Add-Data


As well as:



$DataObj $DataSettings | Add-Data


With the thought that from what I have read on PowerShell parameter binding, the pipeline input would be bound to the parameter which it could be converted to. In my PowerShell script both $DataSettings and $DataObj are a HashTable containing the relevant properties.



When I run either of the above lines in my PowerShell script I get the "Input object cannot be bound to any parameters..." error.



Is it possible to take two inputs from the pipeline in this way? I had considered creating a single custom C# object to encapsulate both of the input objects, but I had been trying to keep the mandatory portion separate from the non-required portion.



Also, I tried running the Trace-Command, but after trying:



Trace-Command ParameterBinding {Add-Data $Input} -PSHost -InputObject @{Data = $DataObj; Settings = $DataSettings;}


I received an error that no parameter matched the name Data. I was trying to follow this tutorial, but evidently I am doing something wrong.










share|improve this question





























    2















    I wrote a PowerShell cmdlet in C# which originally took several parameters, but only accepted one from pipeline input. I condensed the other parameters into a single, custom C# object, which I want to take as input from the pipeline. Here is the relevant code:



    [Parameter(ValueFromPipeline = true, Mandatory = true)]
    public DataObj Data {get; set;}

    [Parameter(ValueFromPipeline = true, Mandatory = false)]
    public DataSettings Settings {get; set;} = new DataSettings();

    public class DataObj {
    public string Name {get; set;}
    public int Value {get; set;}
    ...
    }

    public class DataSettings {
    public DataInfo Info {get; set;} = new DataInfo();
    public string Description {get; set} = "";
    }


    I have been able to succesfully create the DataSettings object from a HashTable in PowerShell before modified it to be taken as pipeline input.



    I have tried:



    @{Data = $DataObj; Settings = $DataSettings;} | Add-Data


    As well as:



    $DataObj $DataSettings | Add-Data


    With the thought that from what I have read on PowerShell parameter binding, the pipeline input would be bound to the parameter which it could be converted to. In my PowerShell script both $DataSettings and $DataObj are a HashTable containing the relevant properties.



    When I run either of the above lines in my PowerShell script I get the "Input object cannot be bound to any parameters..." error.



    Is it possible to take two inputs from the pipeline in this way? I had considered creating a single custom C# object to encapsulate both of the input objects, but I had been trying to keep the mandatory portion separate from the non-required portion.



    Also, I tried running the Trace-Command, but after trying:



    Trace-Command ParameterBinding {Add-Data $Input} -PSHost -InputObject @{Data = $DataObj; Settings = $DataSettings;}


    I received an error that no parameter matched the name Data. I was trying to follow this tutorial, but evidently I am doing something wrong.










    share|improve this question



























      2












      2








      2








      I wrote a PowerShell cmdlet in C# which originally took several parameters, but only accepted one from pipeline input. I condensed the other parameters into a single, custom C# object, which I want to take as input from the pipeline. Here is the relevant code:



      [Parameter(ValueFromPipeline = true, Mandatory = true)]
      public DataObj Data {get; set;}

      [Parameter(ValueFromPipeline = true, Mandatory = false)]
      public DataSettings Settings {get; set;} = new DataSettings();

      public class DataObj {
      public string Name {get; set;}
      public int Value {get; set;}
      ...
      }

      public class DataSettings {
      public DataInfo Info {get; set;} = new DataInfo();
      public string Description {get; set} = "";
      }


      I have been able to succesfully create the DataSettings object from a HashTable in PowerShell before modified it to be taken as pipeline input.



      I have tried:



      @{Data = $DataObj; Settings = $DataSettings;} | Add-Data


      As well as:



      $DataObj $DataSettings | Add-Data


      With the thought that from what I have read on PowerShell parameter binding, the pipeline input would be bound to the parameter which it could be converted to. In my PowerShell script both $DataSettings and $DataObj are a HashTable containing the relevant properties.



      When I run either of the above lines in my PowerShell script I get the "Input object cannot be bound to any parameters..." error.



      Is it possible to take two inputs from the pipeline in this way? I had considered creating a single custom C# object to encapsulate both of the input objects, but I had been trying to keep the mandatory portion separate from the non-required portion.



      Also, I tried running the Trace-Command, but after trying:



      Trace-Command ParameterBinding {Add-Data $Input} -PSHost -InputObject @{Data = $DataObj; Settings = $DataSettings;}


      I received an error that no parameter matched the name Data. I was trying to follow this tutorial, but evidently I am doing something wrong.










      share|improve this question
















      I wrote a PowerShell cmdlet in C# which originally took several parameters, but only accepted one from pipeline input. I condensed the other parameters into a single, custom C# object, which I want to take as input from the pipeline. Here is the relevant code:



      [Parameter(ValueFromPipeline = true, Mandatory = true)]
      public DataObj Data {get; set;}

      [Parameter(ValueFromPipeline = true, Mandatory = false)]
      public DataSettings Settings {get; set;} = new DataSettings();

      public class DataObj {
      public string Name {get; set;}
      public int Value {get; set;}
      ...
      }

      public class DataSettings {
      public DataInfo Info {get; set;} = new DataInfo();
      public string Description {get; set} = "";
      }


      I have been able to succesfully create the DataSettings object from a HashTable in PowerShell before modified it to be taken as pipeline input.



      I have tried:



      @{Data = $DataObj; Settings = $DataSettings;} | Add-Data


      As well as:



      $DataObj $DataSettings | Add-Data


      With the thought that from what I have read on PowerShell parameter binding, the pipeline input would be bound to the parameter which it could be converted to. In my PowerShell script both $DataSettings and $DataObj are a HashTable containing the relevant properties.



      When I run either of the above lines in my PowerShell script I get the "Input object cannot be bound to any parameters..." error.



      Is it possible to take two inputs from the pipeline in this way? I had considered creating a single custom C# object to encapsulate both of the input objects, but I had been trying to keep the mandatory portion separate from the non-required portion.



      Also, I tried running the Trace-Command, but after trying:



      Trace-Command ParameterBinding {Add-Data $Input} -PSHost -InputObject @{Data = $DataObj; Settings = $DataSettings;}


      I received an error that no parameter matched the name Data. I was trying to follow this tutorial, but evidently I am doing something wrong.







      powershell






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 28 '18 at 18:27









      Ansgar Wiechers

      145k13132190




      145k13132190










      asked Nov 28 '18 at 14:58









      pavuxunpavuxun

      1167




      1167
























          1 Answer
          1






          active

          oldest

          votes


















          1














          When you use the pipeline, wrapping your input objects into a single object is the only way to bind them each to a distinct parameter, and to do so you can use delay-bind script blocks:



          @{ Data = $DataObj; Settings = $DataSettings } |
          Add-Data -Data { $_.Data } -Settings { $_.Settings }


          Independently of the pipeline, you can use splatting to achieve the same effect more elegantly:



          # Construct the arguments to pass as a hashtable.
          $htArgs = @{ Data = $DataObj; Settings = $DataSettings }

          # Pass the arguments via splatting (note the '@')
          Add-Data @htArgs


          You can combine the two techniques via ForEach-Object, but note that this will be less efficient with multiple inputs, because a separate call to Add-Data is then made in each iteration:



          @{ Data = $DataObj; Settings = $DataSettings } | ForEach-Object {
          Add-Data @_
          }





          share|improve this answer

























            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53522310%2fcan-i-pass-two-parameters-to-pipeline%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            1














            When you use the pipeline, wrapping your input objects into a single object is the only way to bind them each to a distinct parameter, and to do so you can use delay-bind script blocks:



            @{ Data = $DataObj; Settings = $DataSettings } |
            Add-Data -Data { $_.Data } -Settings { $_.Settings }


            Independently of the pipeline, you can use splatting to achieve the same effect more elegantly:



            # Construct the arguments to pass as a hashtable.
            $htArgs = @{ Data = $DataObj; Settings = $DataSettings }

            # Pass the arguments via splatting (note the '@')
            Add-Data @htArgs


            You can combine the two techniques via ForEach-Object, but note that this will be less efficient with multiple inputs, because a separate call to Add-Data is then made in each iteration:



            @{ Data = $DataObj; Settings = $DataSettings } | ForEach-Object {
            Add-Data @_
            }





            share|improve this answer






























              1














              When you use the pipeline, wrapping your input objects into a single object is the only way to bind them each to a distinct parameter, and to do so you can use delay-bind script blocks:



              @{ Data = $DataObj; Settings = $DataSettings } |
              Add-Data -Data { $_.Data } -Settings { $_.Settings }


              Independently of the pipeline, you can use splatting to achieve the same effect more elegantly:



              # Construct the arguments to pass as a hashtable.
              $htArgs = @{ Data = $DataObj; Settings = $DataSettings }

              # Pass the arguments via splatting (note the '@')
              Add-Data @htArgs


              You can combine the two techniques via ForEach-Object, but note that this will be less efficient with multiple inputs, because a separate call to Add-Data is then made in each iteration:



              @{ Data = $DataObj; Settings = $DataSettings } | ForEach-Object {
              Add-Data @_
              }





              share|improve this answer




























                1












                1








                1







                When you use the pipeline, wrapping your input objects into a single object is the only way to bind them each to a distinct parameter, and to do so you can use delay-bind script blocks:



                @{ Data = $DataObj; Settings = $DataSettings } |
                Add-Data -Data { $_.Data } -Settings { $_.Settings }


                Independently of the pipeline, you can use splatting to achieve the same effect more elegantly:



                # Construct the arguments to pass as a hashtable.
                $htArgs = @{ Data = $DataObj; Settings = $DataSettings }

                # Pass the arguments via splatting (note the '@')
                Add-Data @htArgs


                You can combine the two techniques via ForEach-Object, but note that this will be less efficient with multiple inputs, because a separate call to Add-Data is then made in each iteration:



                @{ Data = $DataObj; Settings = $DataSettings } | ForEach-Object {
                Add-Data @_
                }





                share|improve this answer















                When you use the pipeline, wrapping your input objects into a single object is the only way to bind them each to a distinct parameter, and to do so you can use delay-bind script blocks:



                @{ Data = $DataObj; Settings = $DataSettings } |
                Add-Data -Data { $_.Data } -Settings { $_.Settings }


                Independently of the pipeline, you can use splatting to achieve the same effect more elegantly:



                # Construct the arguments to pass as a hashtable.
                $htArgs = @{ Data = $DataObj; Settings = $DataSettings }

                # Pass the arguments via splatting (note the '@')
                Add-Data @htArgs


                You can combine the two techniques via ForEach-Object, but note that this will be less efficient with multiple inputs, because a separate call to Add-Data is then made in each iteration:



                @{ Data = $DataObj; Settings = $DataSettings } | ForEach-Object {
                Add-Data @_
                }






                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Nov 28 '18 at 16:24

























                answered Nov 28 '18 at 16:19









                mklement0mklement0

                137k22255291




                137k22255291
































                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53522310%2fcan-i-pass-two-parameters-to-pipeline%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown