كتابة PowerShell Cmdlet لقبول ScriptBlock كمعلمة
-
21-09-2019 - |
سؤال
يقبل إعادة تسمية العنوان ScriptBlock (على ما أظن ...) كمعلمة حتى أتمكن من فعل شيء كهذا إذا أردت إعادة تسمية مجموعة من الملفات (على سبيل المثال):
Dir *.ps1 | Rename-item -NewName {$_.Name -replace ".ps1" ".txt" }
أنا أكتب cmdlet لإعادة تسمية بعض العناصر وأرغب في استخدام بناء الجملة مثل هذا للاسم الجديد ، ولكن كيفية إعلان المعلمة لقبول كتلة نصية مثل هذا أو سلسلة بسيطة؟
المحلول
إذا كنت تكتب cmdlet المستندة إلى .NET (C#/VB) ، فضع في اعتبارك أن أي معلمة عبارة عن خط أنابيب ستدعم ScriptBlocks تلقائيًا. هذه مجرد ميزة على PowerShell. ومع ذلك ، إذا لم تكن المعلمة التي تريد استخدامها غير ملزمة ، فيمكنك القيام بذلك:
[Parameter]
public ScriptBlock NewName { get; set; }
[Parameter(ValueFromPipeline = true)]
public string OldName { get; set; }
protected override void ProcessRecord()
{
Collection<PSObject> results = NewName.Invoke(this.OldName);
this.Host.UI.WriteLine("New name is " + results[0]);
}
الشيء الوحيد الذي لا يعجبني في هذا النهج هو أنه لا يمكنك استخدام $ _ في scriptblock ، عليك استخدام $ args [0] في هذه الحالة. ربما هناك طريقة أفضل للقيام بذلك وسوف يتناغم ذلك.
OTOH ، RENAME-ITEM يحدد المعلمة NewName كخط أنابيب ملزمة باسم الخاصية. في هذه الحالة ، يمكنك فقط جعل معلمة NewName هي النوع الذي تريده (سلسلة) ودع PowerShell يقوم بسحر ScriptBlock. أفضل من ذلك كله ، في هذه الحالة $ _ يعمل في scriptblock على سبيل المثال:
[Parameter(ValueFromPipelineByPropertyName = true)]
public string NewName { get; set; }
[Parameter(ValueFromPipeline = true)]
public string OldName { get; set; }
protected override void ProcessRecord()
{
this.Host.UI.WriteLine("New name is " + this.NewName);
}
نصائح أخرى
نعم. -النام يأخذ كتلة نصية. جرب هذا:
Function Do-MyRename {
param([ScriptBlock]$sb)
dir *.ps1| Rename-Item -NewName $sb
}