Tabulator kontra klasa
O potędze tabulacji w PowerShellu pisałem na tym blogu kilkakrotnie. Dziś chciałem wspomnieć o możliwości, którą przyjąłem uważać za oczywistą, a która oczywista chyba wcale nie jest – do tego stopnia, że kolega z pracy (nota bene w znacznej mierze równie biegły w PowerShellu co ja) do niedawna o możliwości tej nie wiedział. Będzie też nieco o pracy z klasami/ obiektami nieco ogólniej. Przede wszystkim o tworzeniu obiektów w oparciu o klasy czy to “wbudowane” w .NET, czy to dystrybuowane wraz z modułami w PowerShellu. Wszystko to na przykładzie pracy z AWS, przy którym ostatnio zdarza mi się nieco częściej “dłubać”.
Tworzymy obiekty
W PowerShellu istnieje cała masa tworzenia obiektów w oparciu o istniejące klasy. W każdym z przypadków jednak pierwszą rzeczą będzie konstruktor. W nowszych wersjach PowerShella najłatwiej informacje o konstruktorach uzyskać korzystając z wirtualnej metody new:
[adsi]::new | |
<# na wyjściu: | |
OverloadDefinitions | |
------------------- | |
adsi new() | |
adsi new(string path) | |
adsi new(string path, string username, string password) | |
adsi new(string path, string username, string password, System.DirectoryServices.AuthenticationTypes authenticationType) | |
adsi new(System.Object adsObject) | |
#> |
Konstruktory z grubsza podzielić można na konstruktory domyślne (bezparametrowe) i konstruktory wieloargumentowe. W przypadku tych drugich możemy, przekazując odpowiednie wartości do poszczególnych argumentów konstruktora, od razu utworzyć obiekt z wymaganymi przez nas właściwościami. W niektórych przypadkach może być to jedyny sposób na zmianę pewnej właściwości obiektu: dla przykładu niektóre właściwości mogą być dostępne tylko do odczytu i przekazanie odpowiedniej wartości w konstruktorze to jedyny sposób, by uzyskać wartość inną niż domyślna:
$szukajka = [adsisearcher]::new() | |
$szukajka.PropertiesToLoad = 'samAccountName', 'distinguishedName' | |
<# Na wyjściu: błąd | |
'PropertiesToLoad' is a ReadOnly property. | |
#> | |
$drugaSzukajka = [adsisearcher]::new( | |
'(name=bartosz*)', # string filter | |
('samAccountName', 'distinguishedName') # string[] propertiesToLoad | |
) | |
$drugaSzukajka.PropertiesToLoad | |
<# Na wyjściu: oczekiwana lista właściwości: | |
samAccountName | |
distinguishedName | |
#> |
Najczęściej jednak w PowerShellu korzystać będziemy z konstruktorów bezparametrowych. Wiele osób tak właśnie (w połączeniu z tabulatorem) sprawdza, jakie właściwości ma dany obiekt. Tak właśnie obiekt w czasie pracy z AWS tworzył i analizował mój kolega:
W kolejnych krokach przypisał wartości obu właściwościom i mógł kontynuować ze skryptem do tworzenia i konfigurowania nowych kont w ramach organizacji w AWS.
Tablice skrótów i magia tabulatora
I tu przechodzimy do meritum: w PowerShellu wcale nie musimy najpierw utworzyć obiektu, by następnie tabulator “podpowiedział nam”, co dana klasa oferuje/ wymaga. Jeśli dowolna klasa posiada konstruktor bezparametrowy to będziemy mogli skorzystać z następującej składni przy tworzeniu obiektów tej klasy:
[Amazon.IdentityStore.Model.Filter]@{ | |
AttributePath = 'DisplayName' | |
AttributeValue = 'AWSAccount_Admin' | |
} |
I tu docieramy do sedna: tabulator w PowerShellu bowiem doskonale radzi sobie z dopełnianiem nazw właściwości już na tym etapie. Zamiast więc najpierw tworzyć obiekt, a potem “tabować” właściwości, możemy je “tabować” już na etapie tworzenia:
Mała rzecz, a cieszy.