LdapFilter kontra Filter

filtry-hydrauliczneWitajcie! Wieki całe minęły od ostatniego posta, mam nadzieję, że na następny nie trzeba będzie czekać równie długo. Aby tego uniknąć postanowiłem, że skupię się po prostu na treści, nie na oprawie.

Post ten stanowić będzie swoisty początek cyklu/ kategorii postów. Krótko, zwięźle, na temat – w oparciu o doświadczenia z pracy, by nie było zbyt abstrakcyjnie. „Notatki z pola walki”. Winking smile

Dziś chciałem napisać o dwóch parametrach, które odnajdziecie na poleceniach z modułu ActiveDirectory, które pobierają obiekty. Jeden z nich to Filter, który udaje, że rozumie bloki skryptu. Drugi to LdapFilter, który nie pozostawia nam w tej materii złudzeń i po prostu oczekuje od nas znajomości odpowiedniej składni.

Paradoksalnie jednak (przynajmniej moim zdaniem) o wiele łatwiej korzystać jest z tego ostatniego. Ostatnio przekonałem się o tym w pracy dwukrotnie.

Pierwsza sytuacja dotyczyła dziwnych rezultatów (a raczej błędów), które panoszyły się po konsoli mojego kolegi z pracy. Kolega próbował korzystać z parametru Filter wykorzystując tam tablicę skrótów. Nasz kod:

$hash = @{
Imię = 'Bartek'
}
Get-ADUser -Filter { givenName -eq $hash.Imię }

Efekt? Porażający:

Wynik-Polecenia-Z-Uzyciem-Filter

Co się stało? Wykorzystując parametr Filter musimy pamiętać, że jego działanie opiera się w gruncie rzeczy na analizie przekazanego ciągu znaków. Nie bloku skryptu (jak by się mogło wydawać), ale właśnie ciągu znaków. Polecenie analizuje poszczególne elementy i tłumaczy je na jedyny słuszny rodzaj filtru przy komunikacji z Active Directory: filtry LDAP. Wszystko to działa nie najgorzej w przypadku prostych wyrażeń. Ale wyrażenie $zmienna.właściwość sprawę nieco komplikuje. Twórcy polecenia postanowili więc sprawdzić, jakiej klasy jest zawartość zmiennej i upewnić się najpierw, czy właściwość podana jest przypisana do tej klasy. Nie do obiektu – do klasy. Ponieważ tablica skrótów właściwości ‚Imię’ nie posiada nasz kod nie działa. Ten sam filtr możemy oczywiście przekazać inaczej:

$hash = @{
Nazwisko = 'Bielawski'
}
Get-ADUser -LdapFilter "(sn=$($hash.Nazwisko))"

Tym razem wynik bliższy oczekiwanemu:

Wynik-Polecenia-Z-Uzyciem-LdapFilter

Oczywiście, składnia filtrów LDAP nie jest ani troszkę intuicyjna, szczególnie gdy zaczniemy łączyć kilka wyrażeń. Korzyść jest taka, że umiejętność ich konstruowania przyda nam się w bardzo wielu miejscach. Konfiguracja aplikacji Web (również takich jak Confluence), ustawienia regułek w ADFS, czy bardzo przyziemne: wyszukiwania w ADUC. Czas poświęcony na opanowanie składni tych filtrów nie będzie więc czasem straconym. Czas poświęcony na obejście problemów z „naturalnym”, „niemal PowerShellowym” filtrem oferowanym przez parametr Filter przyda nam się jedynie przy pracy z modułem ActiveDirectory i dodatkowo w najmniej spodziewanym momencie może po prostu przestać działać. Wam zostawiam decyzję, czy gra jest warta przysłowiowej świeczki… Winking smile

~ - autor: Bartek Bielawski w dniu 5 kwietnia, 2019.

Komentarze 4 to “LdapFilter kontra Filter”

  1. Cześć, już myślałem że blog umarł (prawie 2 lata minęły od ostatniego twojego wpisu). Popraw link do swojej książki na głównej, bo wskazuje na starą wersję 5.0, której nakład już jest wyczerpany. Przecież wydałeś nową wersję 5.1 🙂 Mam właśnie przed sobą 2 wersje książki (moja i kolegi) i właśnie siedzę i szukam tych 100 stron różnic 😀

  2. Cześć … Dzięki za wpis – aż sprawdziłem z ciekawości 😉 zwykle albo raczej zawsze używałem -Filter „” a nie –Filter {} i opisany problem powyżej się nie pojawiał ( chyba bo w sumie jakiś skomplikowanych zapytań nie używam ) – Get-ADUser -Filter „givenName -eq ‚$($hash.Imię)’” i teraz w sumie pytanie albo pytania 😉 – różnica albo może jakie konsekwencje niesie używanie w filtrze bloku {} zamiast stringa.

    • I tu jest przysłowiowy pies pogrzebany.. Korzystając ze zwykłego stringa (a w nim z subexpression) przekazujesz do polecenia właściwą wartość (czyli zawartość pola Imię w tablicy skrótów). W przypadku przekazania bloku skryptu polecenie analizuje zawartość i czasem udaje się to śpiewająco, a czasem kończy się porażką. Różnica najłatwiej unaocznić korzystając z polecenia Trace-Command:


      $hash = @{
      Imię = 'Bartek'
      }
      Trace-Command PSHost Name ParameterBinding Expression { Get-ADUser Filter "givenName -eq '$($hash.Imię)'" }
      # BIND arg [givenName -eq 'Bartek'] to param [Filter] SUCCESSFUL
      Trace-Command PSHost Name ParameterBinding Expression { Get-ADUser Filter { givenName -eq $hash.Imię }}
      # BIND arg [ givenName -eq $hash.Imię ] to param [Filter] SUCCESSFUL

      view raw

      FilterTrace.ps1

      hosted with ❤ by GitHub

Skomentuj

Wprowadź swoje dane lub kliknij jedną z tych ikon, aby się zalogować:

Logo WordPress.com

Komentujesz korzystając z konta WordPress.com. Wyloguj /  Zmień )

Zdjęcie z Twittera

Komentujesz korzystając z konta Twitter. Wyloguj /  Zmień )

Zdjęcie na Facebooku

Komentujesz korzystając z konta Facebook. Wyloguj /  Zmień )

Połączenie z %s

 
%d blogerów lubi to: