Skip to Content

IT nieuczesane.
category

Category: DevOps/Scripting

skrypty, programy, command line i inne

pedanteria niepożądana

prosty search po obiektach w AD, które mają włączoną flagę niewygasania hasła:

i okazuje się, ze na ekranie pustka… wyświetlają się tylko pola ‘sn’. WTF?

problemem jest pedanteria i używanie małych/wielkich znaków – okazuje się, że PS przyjmuje wyłącznie małe literki:

echo "[$($i.samaccountname)] , $($i.displayname) , $($i.sn), $($i.distinguishedname)"

pffff…

eN.

BCD i skrypty

Totalny w-file tym razem. Tyle, że rozwiązany :)

Problem – zautomatyzować operację dodawania wpisów w BCD, żeby skryptem dodawać Pingwina do boot menu w Windows 7.

Pierwszy krok prosty: dodajemy wpis dla grub4dos – http://grub4dos.sourceforge.net/wiki/index.php/Grub4dos_tutorial#Booting_GRUB_for_DOS_via_the_Windows_Vista_boot_manager

Teraz wypada by to przenieść na inną maszynę – chwilka przekopywania się przez dokumentację i okazuje się, że BCDEdit umożliwia import i export ustawień. piknie – robić backup i potem go odzyskać na innej maszynie. Niestety nie działa. Z tego prostego powodu, że wpis dla W7 nie ma GUID {current}, tylko jakiś dziwoląg – niestety GUIDy są generowane pseudolosowo. Efekt: pingwin się podnosi, Windows nie ^^

Rozwiązania są dwa:

1. Wykorzystać WMI i BCDProvider (http://msdn.microsoft.com/en-us/library/aa362675(v=VS.85).aspx) i można zrobić tak (wymaga wcześniejszego dodania wpisów):

2. wykręcić pętlę w CMD:

działa pięknie – po prostu pobiera trzecie słowo z outputu BCDEDIT – to ZAWSZE jest GUID :)

teraz można to wrzucić jako cmd /c “%scriptroot%bcd.cmd” do Task Sequence w MDT i mamy zautomatyzowane dodawanie pingwinów na W7 :D

PS. warto pamiętać, ze sysprep kasuje zawartość BCD :)

ping to file

taka mała piątkowa gimnastyka.

krótki kod, powalający sprawdzić czy host żyje i zapisać wyniki do pliq.

Get-Content .hostyerr.txt | %{ $out=ping $(($_).trim()) -n 1 ; if( ($out[5]).contains("0% loss")) {echo $_}} >hostsok

nie jest to rozwiązanie idealne, ale co fajnego:

  • dla zmiennej można przypisać wynik działania programu – używa sie tych ciapek w lewym-górnym rogu [jak się nazywają?]
  • znów wszystko można zrobić w jednej linijce.

zamiast ‘contains’ lepiej używać –match ale to kiedyś indziej bo…

czas na weekend.

eN.

wsh.run

prosty scenariusz: skrypt logowania, uruchamiający bginfo. podstawowy problem w vbs: obsługa katalogów ze spacją. niestety przekazanie “c:program filessysteinternalsbginfo.exe” z podobnie wyglądającymi parametrami jest upierdliwe – ile tych cholernych cudzysłowów jest potrzebne?

WShell.run """"&SUPPORT_DIR&"bginfo.exe"" """&SUPPORT_DIR&"wrkstations.bgi"" /accepteula /timer:0"

a cały skrypcik wygląda tak:

eN.

mapdrive script:automatyzacja mapowania dysków z serwera plików

prosta idea [nie zawsze wykonalna] – wedle podręcznikowego przydzielania uprawnień i zarządzania grupami polega na tym, że dla każdego udziału na FS tworzona jest grupa security-domain local – np. Share_FS01_RW_public. tej grupie nadawane są uprawnienia [w tym przypadq RW] a całe zarządzanie przydzielaniem uprawnień polega na dodaniu grupy funkcyjnej do grupy dostępowej. przykład w praktyce:

  1. zakładam w AD jednostkę organizacyjną OU=AccessGroups
  2. zakładam w AD jednostkę organizacyjną OU=Accounting
  3. zakładam grupę funkcyjną security-global ‘Accounting’ i dodaję odpowiednich userów). te 3 kroki oczywiście definiują miniaturkę podstawowego środowiska lab
  4. księgowość musi mieć swój prywatny katalog na FS więc:
  1. zakładam grupę Security-Domain Local o nazwie “AG_FS01_RW_Accounting” w OU-AccessGroups – to przykładowa notacja która pozwala w łatwy sposób odróżnić grupy dostępowe od innych, zawiera nazwę serwera, którego dotyczy, uprawnienia [dzięki temu można łatwo odróżniać grupy RW od R] oraz jakiego udziału dotyczą.
  2. zakładam katalog ‘Accounting’ na FS01 i publiqję go jako ‘\FS01Accouting’
  3. jedyne uprawnienia jakie zakładam na katalogu to “authenticated users:M” na poziomie udziału oraz “AG_FS01_RW_Accounting:RW” na poziomie NTFS
  4. teraz aby nadać uprawnienia do katalogu wystarczy, że dodam grupę ‘Accounting’ do ‘AG_FS01_RW_Accounting’

wadą takiego rozwiązania jest niezliczona ilość grup w złożonym środowisq – a więc czasem podręcznikowe rozwiązanie nie może być zastosowane. zalet jednak jest bardzo dużo:

  • wszystko zarządzane z jednego miejsca za pomocą ADUaC bez potrzeby logowania/sprawdzania na serwerach plików
  • ..czyli centralizacja zarządzania uprawnieniami
  • łatwość delegacji zarządzania uprawnieniami
  • utrzymywanie spójnej, prostej struktury: przejrzystość
  • prostota automatyzacji mapowania: ujednolicone/uniwersalne skrypty mapowania
  • automatyczne mapowanie dysków dla użytkowników zaraz po dodaniu do grupy funkcyjnej

poniżej zamieszczam przykładowy skrypt logowania mapujący dyski, który ma możliwość mapowania na podstawie przynależności do grupy. ponieważ użytkownicy nie należą bezpośrednio do grupy dostępowej, sprawdzany jest drugi poziom zagnieżdżenia – atrybut memberof. jest możliwość włączenia rekursywnego sprawdzania zagnieżdżenia ale ma to kilka mankamentów:

  • jest dość powolne w realnym środowisq, gdzie grup jest sporo
  • istnieje niebezpieczeństwo przypadkowego zmapowania katalogu z powodu powiązań pomiędzy grupami

jak się okazuje, czasem teoria przekłada się na praktykę – mówię tu o podręcznikowym projektowaniu grup (global/domain local i standardowe AGDLP).

eN.

Ciężkie życie programisty ….

Żart branżowy, na deszczową niedzielę {przynajmniej u mnie :-/}

Ciężkie życie programisty

Usuwanie starych kont komputerów z Active Directory

Kiedys do wywalania starych i nieużywanych kont komputerów z AD służył mi taki znaleziony w sieci skrypt:

 

dsquery computer -inactive 16 -limit 0 | dsrm -c -noprompt

 

ale coś przestał działać na Win2008.

Nie wnikając w szczegóły i chcąc iść  z duchem czasu przerobiłem go na PowerShella

 

Get-QADComputer -IncludedProperties pwdLastSet -SizeLimit 0 |where {$_.pwdLastSet -le (Get-Date).AddDays(-180) } | Remove-QADObject -DeleteTree  -Force

 

Może komuś się przyda przy porządkach w AD.

PS: jak usunąć elementy z listy oddzielanej średnikami

tak na prawdę to kolejna lekcja zabawy hashtablami i ciągami. scenariusz w moim przypadq był taki, żeby zweryfikować jakie konta należą do grupy lokalnych adminów na stacjach roboczych. skrypt logowania wrzucił zawartość grupy do bazy danych, potem pobrałem sobie dane do zmiennej $DataSet.Tables[0] . teraz trzeba wygenerować raport “wypisz wszystkie komputery, na których ktoś należy do adminów a nie powinien, z informacją jakie to konto”. rozwiązanie jest takie:

czego można się nauczyć z tego skryptu?

  • jak połączyć się z bazą
  • jak pobrać i operować na wynikach
  • jak radzić sobie z hashtablami
  • szczególnie ciekawy jest sposób sortowania – gdzie użyty jest getEnumerator. zwykłe $unsecure|Sort-Object nie zahula

sposób być może nie jest optymalny więc będę wdzięczny za sugestie i alternatywne rozwiązania (:

eN.

Dictionary object dla powershell czyli Hashtable

w PS zamiast obiektu słownikowego jest hashtable. Po przejrzeniu wielu wygooglanych przykładów oczywiście nie znalazłem odpowiedzi na moje pytania:

  • co jeśli wartością ma być zmienna tablicowa?
  • jak dostać się do takiej wartości?
  • jak zrobić enumerację z możliwością wykonania działań?

odpowiedzi są dość intuicyjne. nie ma problemu, żeby do hashtabla dodać tablicę jako wartość, a następnie robić jakieś operacje. enumeracja jest dokładnie taka sama jak w VBS:

póki co nie bawiłem się $hashtable.getEnumerator() – być może da się zoptymalizować to trochę.. ale działa wszystko bez problemu niemal tak samo jak VBSowy Dictionary (: listy są w .keys i .values, testy są metodami .containsKey i .containsValue, dodawanie .add, usuwanie .remove – różnice w wykorzystaniu są niewielkie (:

eN.

modyfikacja grup mailowych via powershell

q pamięci, odnośnie poprzedniego wpisu:




POWERSHELL RLZ! q:

*UPDATE

zostałem poproszony o małe wyjaśnienia niniejszym jakie ciekawostki można wyłapać dla początqjących. samych poleceń ADSI nie będę wyjaśniał, sqpię się na składni PS.

jednym z podstawowych problemów na początq sprawiają najprostsze rzeczy – np. wypisywanie na ekran. z punktu widzenia składni najciekawsze polecenie to “$grp.putex(2,"proxyAddresses",@("SMTP:$($grp.mailnickname)@domain.name"));”. postaram się wyjaśnić co tu się dzieje.

wypisanie zmiennej na ekran jest proste:

echo $zm

ale przy dwóch już robi się dziwnie, ponieważ:

echo $zm1 $zm2

wypisze obie.. ale w oddzielnych liniach. znakiem konkatenacji jest niby ‘+’ ale dodanie

echo $zm1 + $zm2

spowoduje wypisanie 3ech linii – gdzie ‘+’ jest normalnym znakiem. odpowiedz jest dość prosta: wystarczy zamknąć zmienne w cudzysłowach:

echo “$zm1 $zm2”

można też zastosować zapis znany z c++:

echo (“{0} {1}” –f $zm1,$zm2)

ciekawie się robi, kiedy wartość ma być  lub wartością atrybutu obiektu. PS po ‘$’ automatycznie kończy wyliczanie po pierwszym znaq specjalnym – np. kropka. w przedstawionym skrypcie wypisać należy wartość atrybutu ‘mailnickname’. wypisanie go w ten sposób:

echo “$grp.mailnickname”

wypisze $grp a na koniec doda ciąg “.mailnickname”. w związq z tym trzeba zadeklarować zmienną tymczasową, przyjmującą wartość wyliczaną:

echo “$($grp.mailnickname)”

trochę o ADSI musi być – ‘putex’ służy do ustawiania atrybutów wielowartościowych i przyjmuje 3 parametry. ten trzeci z nich to ostateczna wartość – zasady są dokładnie takie same jak przy wypisywaniu na ekran – przedstawione powyżej. dodatkowo, ponieważ atrybut jest wielowartościowy, musi to być tablica. stąd cała postać zmiennej przekazywanej do “putex” musi wyglądać tak:

@("SMTP:$($grp.mailnickname)@domain.name")

gdzie ‘@’ oznacza deklarację tablicy, potem jest ciąg, który zawiera jedną wartość wyliczaną: $($grp.mailnickname) . przykładowy output: [jednoelementowa tablica] “SMTP:nexor@domain.name”

eN.