[英]Create PowerShell Cmdlets in C# - Pipeline chaining
我在 C# 中有一些類,我想在管道中使用它們,我已經看過有關它的文章,但我還沒有做到。
這是我現在使用它的方式:
$suite = [MyProject.SuiteBuilder]::CreateSuite('my house')
$houseSet = $suite.AddSet('doors', 'These represents doors')
$houseSet.AddOption('blue', 'kitchen')
$houseSet.AddOption('black', 'bedreoom')
$houseSet.AddOption('white', 'toilet')
我希望能夠像這樣將它與管道一起使用:
$suite = [MyProject.SuiteBuilder]::CreateSuite('my house')
$suite | AddSet('doors', 'These represents doors') `
| AddOption('blue', 'kitchen') `
| AddOption('black', 'bedreoom') `
| AddOption('white', 'toilet')
這是我的 C# 類:
//SuiteBuilder.cs
public static class SuiteBuilder
{
public static Suite CreateTestSuite(string name)
{
return new Suite(name);
}
}
//Suite.cs
public class Suite : PSCmdlet
{
public string Name { get; set; }
public IEnumerable<Set> Sets { get; set; }
public Suite(string name)
{
Name = name;
Sets = new List<Set>();
}
// call this method in pipeline
public Set AddSet(string type, string description)
{
Sets.Add(new Set(type, description));
return Sets.Last();
}
}
//Set.cs
public class Set : PSCmdlet
{
public string Type { get; set; }
public string Description { get; set; }
public IEnumerable<Option> Options { get; set; }
public Set(string type, string description)
{
Type = type;
Description = description;
Options = new List<Option>();
}
// call this method from pipeline
public Set AddOption(string color, string place)
{
Options.Add(new Option(color, place));
return this;
}
}
//option.cs
public class Option : PSCmdlet
{
public string Color { get; set; }
public string Place { get; set; }
public Option(string color, string place)
{
Color = color;
Place = place;
}
}
我正在努力使這些 function 可以以管道形式調用。
我還在需要調用的每個注釋之前添加了一條注釋,例如call this method in pipeline
。
簡而言之,您需要:
[Parameter(ValueFromPipeline =true)]
接受來自管道的參數WriteObject
方法將 output 提供給管道在這篇文章中,我將對您的代碼進行一些重構,並將向您展示如何在 C# 中創建Powershell Cmdlet以及如何定義參數、接受來自管道的參數並將Z78E6221F6393D1356681DB.D 管道提供給管道。 然后你可以很容易地寫出類似的東西:
$suite = [MyCmdLets.Suite]::New("suite1")
$suite | Add-Set "type1" "desc1"`
| Add-Option "color1" "place1"`
| Add-Option "color2" "place2" | Out-Null
為此,請按照下列步驟操作:
MyCmdlets
)Microsoft.PowerShell.5.ReferenceAssemblies
考慮以下注意事項創建 cmdlet:(請參閱帖子底部的代碼)
Cmdlet
class 派生CmdletAttribute
屬性來裝飾 class,指定動詞和動詞后的名稱,例如,如果您想要Add-Set
,請使用[Cmdlet(VerbsCommon.Add, "Set")]
。OutputTypeAttribute
attribute specifying the type of output, for example if you want to have an output of type Set
for the pipeline, use [OutputType(typeof(Set))]
.Parameter
屬性裝飾每個參數屬性。ParameterAttribute
屬性進行裝飾時,將ValueFromPipeline
設置為 true,例如[Parameter(ValueFromPipeline =true)
ProcessRecord
等管道處理方法並使用WriteObject
將其寫入 output。構建項目。
打開 PowerShell ISE 並運行以下代碼:
Import-Module "PATH TO YOUR BIN DEBUG FOLDER\MyCmdlets.dll" $suite = [MyCmdLets.Suite]::New("suite1") $suite | Add-Set "type1" "desc1"` | Add-Option "color1" "place1"` | Add-Option "color2" "place2" | Out-Null
它將創建一個這樣的結構:
Name Sets ---- ---- suite1 {MyCmdlets.Set} Type Description Options ---- ----------- ------- type1 desc1 {MyCmdlets.Option, MyCmdlets.Option} Color Place ----- ----- color1 place1 color2 place2
Model 類
如上所述,設計獨立於 PowerShell 的 model 類,如下所示:
using System.Collections.Generic;
namespace MyCmdlets
{
public class Suite
{
public string Name { get; set; }
public List<Set> Sets { get; } = new List<Set>();
public Suite(string name) {
Name = name;
}
}
public class Set
{
public string Type { get; set; }
public string Description { get; set; }
public List<Option> Options { get; } = new List<Option>();
public Set(string type, string description) {
Type = type;
Description = description;
}
}
public class Option
{
public string Color { get; set; }
public string Place { get; set; }
public Option(string color, string place) {
Color = color;
Place = place;
}
}
}
CmdLet 類
還要根據我上面描述的注釋設計 cmdlet 類:
using System.Management.Automation;
namespace MyCmdlets
{
[Cmdlet(VerbsCommon.Add, "Set"), OutputType(typeof(Set))]
public class AddSetCmdlet : Cmdlet
{
[Parameter(ValueFromPipeline = true, Mandatory = true)]
public Suite Suite { get; set; }
[Parameter(Position = 0, Mandatory = true)]
public string Type { get; set; }
[Parameter(Position = 1, Mandatory = true)]
public string Description { get; set; }
protected override void ProcessRecord() {
var set = new Set(Type, Description);
Suite.Sets.Add(set);
WriteObject(set);
}
}
[Cmdlet(VerbsCommon.Add, "Option"), OutputType(typeof(Option))]
public class AddOptionCmdlet : Cmdlet
{
[Parameter(ValueFromPipeline = true, Mandatory = true)]
public Set Set { get; set; }
[Parameter(Position = 0, Mandatory = true)]
public string Color { get; set; }
[Parameter(Position = 1, Mandatory = true)]
public string Place { get; set; }
protected override void ProcessRecord() {
var option = new Option(Color, Place);
Set.Options.Add(option);
WriteObject(Set);
}
}
}
您可以使用 ValueFromPipeline = $true。 但是,如果要繼續流水線,則必須引用類型變量並返回項目。 我不知道解決這個問題的方法。 由於它會返回,因此您必須在末尾添加一個Out-Null
以防止它擊中控制台。
function Add-Option {
param(
[Parameter(Mandatory = $true, ValueFromPipeline = $true)]
[ref]$Item,
[Parameter(Mandatory = $true, Position = 0)]
[String]$Color
[Parameter(Mandatory = $true, Position = 1)]
[String]$Room
)
$Item.Value.AddOption($Color,$Room)
return $Item
}
$suite = [MyProject.SuiteBuilder]::CreateSuite('my house')
[ref]$suite | Add-Option 'blue' 'kitchen' `
| Add-Option 'black' 'bedroom' `
| Out-Null
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.