So how do take input (which is usually an array of objects) that is passed to your module?
You just add an attribute to the parameter.
function show-data {
param(
[Parameter(ValueFromPipeline=$true)]
$InputObject
)
begin {
$objects = @()
}
process {
$objects += $InputObject
}
end {
foreach($obj in $objects)
{
$obj
#$obj is written to the pipeline on each iteration of the loop
}
}
}
Get-ChildItem | show-data
Note that process
is called for each item in the array being piped in. In the code snippet, we collected all the items to be processed during end
In C# code, this is what it looks like:
using System.Management.Automation; //get this from nuget package manager - use PowerShellStandard.Library
[Cmdlet(VerbsDiagnostic.Test, "PipelineObjDyn")]
public class TestPipelineDynamic : Cmdlet
{
[Parameter(ValueFromPipeline = true)]
public dynamic ObjectFromPipeline { get; set; } //using dynamic because we don't know what type is going to be returned; using PSObject would be better.
private List<dynamic> objects;
protected override void BeginProcessing()
{
objects = new List<dynamic>();
}
protected override void ProcessRecord()
{
objects.Add(ObjectFromPipeline);
}
protected override void EndProcessing()
{
foreach (var obj in objects)
{
WriteObject(obj); //writes object to the pipeline
}
}
}
I strongly recommend using Visual Studio to set breakpoints and see what the underlying object (ObjectFromPipeline
) looks like. You’ll get a much better understanding of what’s going on.
When developing cmdlets (binary PS modules), you will want to convert PSObject
to/from Dictionary<string,object>
(or ExpandoObject
)
public static class HelperExtensions
{
public static PSObject AsPSObject(this ExpandoObject eo)
{
//makes it so that your C# objects can be filtered/manipulated with powershell syntax
var newpso = new PSObject();
var expandoAsDict = ((IDictionary<string, object>)eo);
foreach (var k in expandoAsDict.Keys)
{
newpso.Members.Add(new PSNoteProperty(k, expandoAsDict[k]));
}
return newpso;
}
public static IDictionary<string,object> AsDictionary(this PSObject pso)
{
//makes stuff coming in from the pipeline easier to handle
var newDict = new Dictionary<string, object>();
foreach (var prop in pso.Properties)
{
newDict[prop.Name] = prop.Value;
}
return newDict;
}
}
Example cmdlet that reads a csv file and outputs results as an array of PSObjects
[Cmdlet(VerbsDiagnostic.Test, "WriteObject")]
public class TestBinaryModuleCmdlet1Command : Cmdlet
{
protected override void BeginProcessing()
{
using (var reader = new StreamReader(@"D:\temp\test.csv"))
{
using (var csv = new CsvReader(reader))
{
var records = csv.GetRecords<dynamic>();
foreach(var rec in records)
{
WriteObject(((ExpandoObject)rec).AsPSObject());
}
}
}
}
}
CsvReader is part of the CsvHelper nuget package
get yourself on the email list
comments powered by Disqus