2013-02-03 14 views
27

Regularnie używam [cmdletbinding()] w moich funkcjach lub skryptach, ale zawsze znajduję te rzeczy ezoteryczne, może niektórzy z was mogą udostępniać swoje światła.
Według get-help about_Functions_CmdletBindingAttributeco to jest [cmdletbinding()] i jak to działa?

atrybutu CmdletBinding jest atrybutem funkcji, które sprawia, że ​​ im działać jak zestawionych cmdlets

ale możemy użyć go na szczycie naszych skryptach, co jest funkcją w tym walizka ? wewnętrzna niejawna "główna" funkcja wywoływana przez silnik ps dla wszystkich jej wejść?

o składni obecnie:

[CmdletBinding(ConfirmImpact=<String>, 
        DefaultParameterSetName=<String>, 
        HelpURI=<URI>, 
        SupportsPaging=<Boolean>, 
        SupportsShouldProcess=<Boolean>, 
        PositionalBinding=<Boolean>)] 

Co robimy? utworzyć instancję obiektu cmdlbinding i podać listę argumentów do swojego konstruktora? tę składnię można znaleźć w param(), na przykład [Parameter(ValueFromPipeline=$true)] czy ta składnia ma określoną nazwę i czy można ją znaleźć gdzie indziej?

w końcu, czy jesteśmy w stanie, jako proste powershellery, naśladować tę funkcjonalność i modyfikować zachowanie skryptów poprzez ustawienie atrybutu?

+4

Chyba docs są nieco mylące tutaj: to wszystko jest związane z każdym rodzajem bloku skryptu : as Shay mentioned - nazwany przez nazwę funkcji, przez ścieżkę (skrypt), ale * także * bez nazwy, np '& {[CmdletBinding()] param() Write-Verbose 'Foo'} -Verbose' działa jak mistrz. – BartekB

+0

@BartekB dzięki ok za pierwszą część pytania. –

Odpowiedz

11

CmdletBinding, Parameter itp. To specjalne klasy atrybutów, które skrypty mogą używać do definiowania zachowania PowerShell, np. spraw, aby funkcja była funkcją zaawansowaną z możliwościami Cmdlet.

Po wywołaniu ich za pośrednictwem np. [CmdletBinding()] zainicjujesz nową instancję klasy.

Czytaj więcej o klasie CmdletBindingAttribute w: MSDN

Czytaj więcej o klasie ParameterAttribute w: MSDN

Więcej informacji na temat klas atrybutów here i here

+0

OK. Więc kiedy używamy pełnej składni, przekazujemy do konstruktora tablicę, która będzie używana do ustawiania wartości publicznych członków? –

+0

w pewien sposób. hashtables są oddzielone przez ';'. Myślę, że jest to szczególny typ klasy i sposób konstruowania, z którego może korzystać proces PowerShell.Możesz myśleć o tym jako np. 'new Question {Text =" Some question "};' in C# Chyba. Jeśli chcesz wiedzieć, jak to działa, możesz spróbować dekompilować bibliotekę określoną w moim łączu MSDN i sprawdzić, czy jest ona czytelna. –

+0

yeah rodzaj hashtable :). –

5

Ogólnie mówiąc, funkcja CmdletBinding tworzy funkcję z funkcji zaawansowanej. Umieszczenie go na początku skryptu powoduje, że skrypt jest "zaawansowanym" skryptem. Funkcje i skrypty są bardzo podobne, gdzie nazwa pliku skryptu jest odpowiednikiem nazwy funkcji, a zawartość skryptu jest równoważna sekcji scripblock funkcji.

Atrybuty CmdletBinding dają kontrolę nad funkcjami, takimi jak dodanie obsługi Potwierdź i WhatIf (za pośrednictwem SupportsShouldProcess), Wyłącz powiązanie pozycji parametrów i tak dalej.

+0

Cześć Shay, zastanawiam się nad wewnętrznymi sposobami działania ... –

2

Odnosząc się do zagadnienia składni, format zbliżony jak zastosować klasę atrybutu .NET do elementu używającego nazwanych parametrów w języku C#.

Porównaj (-i) gramatyki cechy z części B.2.4 z The PowerShell Language Specification z tym z sekcji C.2.13 z C# Language Specification:

B.2.4 Właściwości   (PowerShell)

atrybutów:
  [atrybutu nazwy(atrybut argumenty) ]

atrybut argumenty
  atrybut argumentów
  atrybut argumentu
,argumenty atrybutów

atrybut argumentu:
  prosty nazwa
=ekspresji


C.2.13 Atrybuty   (C#)

atrybutów:
  [attr ibute-name(nazwanego Argument lista-) ]

nazwanego argumentu-lista:
  nazwanego argumentem
  nazwanego Argument lista-
,nazwanego argumentem

named- argument:
  identyfikator
=atrybut-argument-wyrażenie



Zgadzam może to być miły z poczuciem koncepcyjnego zwięzłości na przykład ponownie użyć składni inicjalizacji hashtable do inicjowania atrybutów. Mogę sobie jednak wyobrazić obsługę wszystkich opcji z hashtables (takich jak [A(P=v)] i [A('P'=v)] i $n = 'P'; [A($n=v)] i takich, lub niektórych ich podzbiorów) tylko po to, aby użyć ;, ponieważ znak separatora byłby większym kłopotem, niż byłby wart.

Z drugiej strony, jeśli chcesz korzystać z zaawansowanych funkcji, to może ma to sens, aby dowiedzieć się zaawansowaną składnię :)

+0

Atrybuty nie obsługują składnię hashtable, ponieważ nie mają do czynienia z normalnymi kluczami i wartościami. Klucze odpowiadają dobrze zdefiniowanym właściwościom w klasach rozszerzających "System.Attribute". – Zenexer

+0

@Zenexer: To jest argument na poparcie składni podobnej do C#, ale to nie nakłada ograniczenia na język. Podobnie, mogę zdefiniować hashtable '$ h = @ {foo = 2}' i uzyskać dostęp do elementu za pomocą składni właściwości '$ h.foo', mimo że hashtable w rzeczywistości nie ma właściwości" foo ". W jednym przypadku projektanci języka wybrali elastyczną składnię, a w drugiej zdecydowali się na prostszą składnię. –

+0

Z pewnością istnieje pewien stopień projektowania języka, ale należy pamiętać, że PowerShell jest na szczycie .NET. Atrybuty PowerShell są atrybutami .NET, więc muszą przestrzegać reguł atrybutów .NET. Z pewnością możliwe byłoby rozszerzenie atrybutów .NET i dostarczenie wersji specyficznej dla PowerShella, ale musi istnieć sposób definiowania atrybutów .NET ze względu na naturę PowerShell. – Zenexer