laboratoria – czyli skrypty, skrypciki i inne takie
Wile osób woli uczyć się czytając przykłady. Ponieżej zamieszczam kilkanaście małych skrypcików, które urodziły się podczas gdy uczyłem się pewnych mechanizmów – czy to pewnych cech VBasic’a czy zachowania się interface’u LDAP. Każdy przykład jest krótko opisany – po co został napisany i co testuje. Na podstawie tych skryptów myślę, że spokojnie można będzie spłodzić jakiś własny wynalazek…
Poszczególne rzeczy opisane są jednokrotnie – czyli jeśli w którymś skrypciku jest jakiś mechanizm nieopisany, najprawdopodobniej wyjaśnienie znajduje się gdzieś powyżej, w opisie wcześniejszego kodu.
-
Skrypcik został napisany w celu sprawdzenia jak w VBS’ie obsługuje się argumenty z linii poleceń.
+———— testArgs.vbs
01. ON ERROR RESUME NEXT 02. Dim a 03. a = WScript.Arguments.Item(0) 04. wscript.echo wscript.arguments.count 05. IF len(a)>0 Then 06. WScript.echo "jest argument" 07. Else 08. WScript.echo "nie ma arg" 09. End iF
—–( źródło )—–
opis:- [1.] wyłączone zostaje wstrzymywanie programu w razie wystąpienia błędu. Jeśli w programie zamieszczone są jakieś funkcje, ten blok powinien znajdować się w każdej funkcji – inaczej błąd, który wystąpi, spowoduje przerwanie wykonywania bloku finkcji [patrz kolejny przykład].
- [2.] deklaracja zmiennej 'a’. W VB nie predefiniuje się typów zmiennych [podobnie jak w JScipcie]. Type zmiennej jest automatycznie określany kontextowo.
- [3.]
WScript.Arguments
jest tablicą argumentów skryptu.Item(0)
to pierwszy element tej tablicy. Jest to wyra�ne niedpatrzenie ze strony twórców VBScriptu, ponieważ powinien od zwracać nazwę samego skryptu [testArgs.vbs], tak jak jest to np. w C, C++ czy Javie.zmiennej ’
a
’ przyjmuje wartość stringową, występującą jako pierwszy parametr. - [4.] na ekran wyświetlona zostaje [
wscript.echo
] informacja o ilości wszystkich argumentów [wscript.arguments.count
] - dalej w zalezności od tego czy długość argumentu jest większa od zera [czyli jest jakiś argument][
if len(a)>0 then
] wyświetlana jest odpowiednia informacja.
-
Jest to w zasadzie to samo co powyżej, z kilkoma dodatkami. +———— testArgs2.vbs
01. OPTION EXPLICIT 02. ON ERROR RESUME NEXT 03. 04. Dim a 05. show 06. 07. Sub show 08. ON ERROR RESUME NEXT 09. a = WScript.Arguments.count 10. IF a<>0 Then 11. WScript.echo "jest argument "&WScript.Arguments.item(0) 12. Else 13. WScript.echo "nie ma arg" 14. End iF 15. end sub
—–( źródło )—–
opis:- [1.] o ile ’
ON ERROR...
’ może pojawić się w każdym miejscu, o tyle ’OPTION EXPLICIT
’ musi być pierwszą linijką skryptu. Generalnie w VBS’ie nie ma obowiązku deklaracji zmiennych [Dim a
]. Zostaną one automatycznie zadeklarowane w razie potrzeby. Czyli w poprzednim przykładzie linijkę 2 można było pominąć. ’OPTION EXPLICIT
’ powoduje, że brak zadeklarowania zmiennej będzie błędem. Jest to przydatne [wręcz zalecane] w dużych skryptach w celu uniknięcia literówek, z czego mogą wyniknąć trudne do odnalezienia błędy. - [4.] wywołanie procedury 'show’ zdefiniowanej w liniach 6-13. W VBS’ie są procedury [SUB] i funkcje [function]. Funkcje to procedury przyjmujące wartość.
- we wnętrzu procedury został zmieniony kod względem poprzedniego przykładu, na bardziej poprawny – najpierw sprawdzana jest ilość parametrów, żeby uniknąć operacji na null’ach.
- [1.] o ile ’
-
Testowanie obsługi tablic. +———— testArray.vbs
01. Dim arr 02. arr=Split( trim(" jakis tam sobie text ") ) 03. wscript.echo "----" 04. wscript.echo ubound(arr) 05. wscript.echo "----" 06. redim arr(0) 07. wscript.echo ubound(arr) 08. arr(0)="ala" 09. wscript.echo arr(0) 10. redim preserve arr(ubound(arr)+1) 11. arr(ubound(arr))="kot" 12. wscript.echo arr(1) 13. 14. dim arr2 15. redim arr2(1,0) 16. arr2(0,0)="ala" 17. arr2(1,0)="kot" 18. wscript.echo arr2(0,0)&" "&arr2(1,0) 19. wscript.echo ubound(arr2,2) 20. 'u can preserve only resizing last dimention 21. redim preserve arr2(1,1)
—–( źródło )—–
opis:- linie 1-5 to test funkcji
split()
, która dzieli podany string na kawałki i tworzy z tego tablicę. Warto zwrócić uwagę, że również w tym przypadku typ zmiennej został automatycznie zkonwertowany na macierzowy – ’arr
’ stało się tablicą. Pojawia się również funkcjatrim()
, która obcina puste znaki na końcu i początku stringa.ubound()
zwraca ilość elementów w tablicy [tutaj 4]; - [6.] zmiana wielkościd tablicy na 0;
- [10.] zwiększenie wielkości tablicy [
redim
] z zachowaniem znajdujących się w niej elementów [preserve
] o jeden, w stosunku do obecnej wielkości tablicy. - linie 14-21 to trochę zabawy z tablicami dwuwymiarowymi. To co jest najważniejsze to to, że powiększać z zachowaniem poprzedniego stanu [
redim preserve
] można tylko ostatni element macierzy.
- linie 1-5 to test funkcji
-
Przykład obrazujący sposób bindowania się do domeny z autoryzacją czyli podaniem usera i hasła. Taki sposób jest potrzebny jeśli bind’ujesz się z systemu poza domeną. +———— testAuthorization.vbs
01. Dim oADsObject,oADsNamespace 02. Dim strADsNamespace, strADsPath 03. 04. strADsPath="LDAP://CN=userName,OU=studenci,DC=pjwstk,DC=edu,DC=pl" 05. 'strADsPath="WinNT://pjwstk/userName,user" 06. strUserName="pjwstkuserName" 07. strUserPassword="userPassword" 08. 09. strADsNamespace = left(strADsPath, instr(strADsPath, ":")) 10. set oADsNamespace = GetObject(strADsNamespace) 11. 12. on error resume next 13. Set oADsObject = oADsNamespace.OpenDSObject(strADsPath, strUserName, strUserPassword, 1) 14. ' we've only managed to bind if err.number = 0 15. if not (Err.number = 0) then 16. WScript.echo "Failed to bind to object " & strADsPath 17. WScript.echo err.description 18. WScript.echo "Error number is " & cstr(hex(err.number)) 19. else 20. WScript.echo "USER AUTHENTICATED!" 21. WScript.echo "Currently viewing object at " & oADsObject.ADsPath 22. WScript.echo "Class is " & oADsObject.Class 23. end if
—–( źródło )—–
opis:- przykład będzie działał tak samo dla providera LDAP jak i WinNT – obecnie wyremowana jest linijka 5, ale można zamiast niej wyremować 4.
- użytkownik i hasło nie powinny oczywiście być w pliku – jeśli chciałoby się to wykorzystać w rzeczywistości powinno się zczytać jako argumenty.
- [13.] to własciwe bind’owanie
- [17.] pojawia się tu
err.desciption
– teoretycznie coś takiego istnieje i jest opisane w dokumentacji. W rzeczywistości to jakiś fake – nigdy mi jeszcze nie zadziałało. Panuje tu typowa regóła – chcesz mieć coś zrobione – zrób to sam. - [20-22]: jeśli autentykacja przebiegnie właściwie, zostają wyświetlone dwa atrybuty obiektu 'user’ – pełna ścieżka i klasa obiektu [czyli 'user’]
- należy zwrócić uwagę, że w poprzednich przykładach nie pojawiało się 'set’ – ponieważ przypisując zmiennej wartość nie korzysta się z tej funkcji. Tutaj pewne zmienne stają się referencjami do obiektów – stąd 'set’ w momencie ustalania referencji.
-
Tworzenie usera za pomocą providera LDAP z kilkoma parametrami. +———— testCreateUser.vbs
01. Dim ADPath 02. 03. ADPath="LDAP://pjwstk.edu.pl/DC=pjwstk,DC=edu,DC=pl" 04. CreateUser ADPath, "testowy", "abc123def", "Imie Nazwisko", "" 05. 06. sub CreateUser(ServerName, name, password, fullname, logonscript) 07. on error resume next 08. err.clear 09. 10. 'set objProvider = LDAP: 11. set objDomain = GetObject(ADPath) 12. If Err.Number then 13. If CStr(Hex(Err.Number)) = "80070035" Then 14. Print "Object " & strDomain & " is not found." 15. Else 16. Print "Error 0x" & CStr(Hex(Err.Number)) & " occurred in getting object " & strDomain & "." 17. If Err.Description <> "" Then 18. Print "Error description: " & Err.Description & "." 19. End If 20. End If 21. Err.Clear 22. Exit Sub 23. Else WScript.echo "ok1" 24. End If 25. 26. set objUser = objDomain.Create("user", "cn=" & name) 27. If Err.Number Then 28. Print "Error " & CStr(Hex(Err.Number)) & " occurred in creating user account " & strUser & "." 29. Print "Failed to create user " & strUser & "." 30. Err.Clear 31. WScript.Quit 32. Else 33. WScript.echo "ok2" 34. End if 35. 36. objUser.sAMAccountName = name 37. If Err.Number Then 38. Wscript.echo CStr(Hex(Err.Number)) & " name" 39. Err.Clear 40. End If 41. 42. objUser.Fullname = fullname 43. If Err.Number Then 44. Wscript.echo CStr(Hex(Err.Number)) & " fulln" 45. Err.Clear 46. End If 47. 48. if not isNull(logonscript) then 49. objUser.loginscript = logonscript 50. If Err.Number Then 51. Wscript.echo CStr(Hex(Err.Number)) & " loginscr" 52. Err.Clear 53. End If 54. end if 55. 56. objUser.SetInfo 57. 58. 'password must be set after account is created 59. objUser.setPassword password 60. If Err.Number Then 61. Wscript.echo CStr(Hex(Err.Number)) & " pass" 62. Err.Clear 63. End If 64. objUser.SetInfo 65. 66. If Err.Number Then 67. Wscript.echo CStr(Hex(Err.Number)) & " finish" 68. Err.Clear 69. End If 70. 71. Wscript.Echo "Finished creating user: " & name 72. end sub
—–( źródło )—–
opis:- Jest to przykład znaleziony gdzieś w MSDN’ie w nieco zmienionej formie.
- [4.] wywołanie procedury tworzącej urzytkownika z kilkoma parametrami. Deklaracja procedury poniżej.
- [6-72] definicja procedury tworzącej urzytkownika. To na co warto zwrócić szczególną uwagę to:
- [13.] obsługa błędu i pojawia się dziwny numerek. Numerów błędów trzeba szukać w MSDN’ie. Są trzy standardowe rodzaje błędów: błędy ADSI, Win32 i niewiadomo-jakie. W zależności od tego na jakim poziomie wygenerowany błąd [jaki rodzaj operacji] opisu błedu należy szukać w jednym lub drugim [search key: „Win32 error codes” oraz „error codes for ADSI”] lub być domyślnym. Najczęściej chodzi o ten trzeci rodzaj (; . Błąd zapisany jest w hexach z niewiadomo-poco-umieszczoną-literką 'L’ na końcu. Czyli jeśli w przykładzie jest rekacja na błąd „80070035” to byłoby to zapisane „0x80070035L”. Byłoby ale nie ma, bo jest to jeden z wielu nieopisanych błędów. Czsami dobre efekty daje wpisanie błedu w googlu w postaci „80070055”. Czasami nie skutkuje nic i jest się wtedy zdanym na siebie.
- Może kiedyś odważę się napisać jakieś memo o błędach – mam kolekcję własnych odkrytych i nieopisanych błędów :P . Generalnie jest to tragedia.
- [17-19] to imho strata czasu. Jest tu wstawiona cała 3-linijkowa obsługa err.description, który i tak prawie zawsze jest pusty. Domyślam się, że nawet jeśli kiedyś coś zwróci [co mi się nie zdarzyło] to będzie to tak przydatne jak kalosze na sacharze.
- kolejną sprawą jest korzystanie z polecenia print – polecenie to powinno wypisywać komunikaty na STDIO czyli zazwyczaj ekran. Mi się tego nie udało uzyskać [nie próbowałem zbyt mocno] i polecam używać 'wscript.echo’ lub napisać własną procedurkę do obsługi.
- Dalej już są standardowe rzeczy – err.clear po każdym miejscu, gdzie może wystąpić błąd, wypisanie błędu w razie niepowodzenia i takie tam.
- W przykładzie MSDN’owym były 2 poważne błędy. Tu są poprawione:
– ustawienie hasła dla stworzonego obiektu było przed komendą 'setinfo’ – czyli próbowano zmienić hasło nieistniejącemu jeszcze obiektowi. Przeniesione na koniec kodu.
– jeśli nazwa skryptu była pusta, program wywala się. Dodana jest linijka 'isNull’ sprawdzająca czy ustawiona jest jakaś wartość. Tak swoją drogą aby to funkcjonowało poprawnie powinno być parsowanie i przetestowanie argumentów wejściowych…
-
Wyświetlenie wartości różnych atrybutów obiektu domeny. +———— testCurrentDomain.vbs
01. set odomain = getobject("LDAP://RootDSE") 02. 03. wscript.echo odomain.dnshostname 04. wscript.echo odomain.dsservicename 05. wscript.echo odomain.currenttime 06. wscript.echo odomain.subschemasubentry 07. for each v in odomain.namingcontexts 08. wscript.echo "naming context-> "&v 09. next 10. wscript.echo odomain.defaultNamingContext 11. wscript.echo odomain.schemaNamingContext 12. wscript.echo odomain.configurationNamingContext 13. wscript.echo odomain.RootDomainNamingContext 14. for each v in odomain.SupportedControl 15. wscript.echo "supported control-> "&v 16. next 17. for each v in odomain.SupportedLDAPVersion 18. wscript.echo "supported LDAP version-> "&v 19. next 20. wscript.echo odomain.HighestCommittedUSN 21. for each v in odomain.SupportedSASLMechanisms 22. wscript.echo "supported saslm mech-> "&v 23. next 24. wscript.echo odomain.LdapServiceName 25. wscript.echo odomain.ServerName 26. wscript.echo odomain.rootDomainNamingContext
—–( źródło )—–
opis:- jeśli komputer jest w domenie, nie musimy wypiswać całej ścieżki przy próbie bindowania się do domeny. Obiekt RootDSE załatwia to za nas – co można sprawdzić uruchamiając ten skrypt.
- część parametrów jest opatrzona pętlą ’
for each v in NAME [...] next
’. Niektóre parametry są typu tablicowego [tu nazywa się to 'multivalue’]. Trzeba wtedy wyświetlić pojedyńcze wartości poprzez skorzystanie z takiej właśnie pętli. Próba wyświetlenia takiego parametru w zwykły sposób zwróci błąd 'Type mismatched’. - Parametry wziołem z MSDN’a [search key: „Serverless binding RootDSE”]
-
Bindowanie WinNT bez autoryzacji. Wyłączanie konta.
+———— testDisableAccount.vbs
01. Dim wnt_oUser 02. 03. set wnt_oUser = getObject("WinNT://pjwstk/s0352,user") 04. Wscript.echo "." 05. wnt_oUser.Put "PasswordExpired", CLng(0) 06. Wscript.echo "." 07. wnt_oUser.AccountDisabled = True 08. Wscript.echo "." 09. wnt_oUser.sEtiNfo 10. WScript.echo "ok."
—–( źródło )—–
opis:- To na co warto zwrócić uwagę – w tym przykładzie wykorzystany jest provider WinNT [co się wiąże z innym zapisem], i podczas bindowania do domeny nie podawana jest nazwa użytkownika ani hasło – w takim wypadku użyte zostaną dane [credentials] o obecnie zalogowanym userze.
- brak jest obslugi błędów. Dodane jedynie wypisywanie kropki po karzedej wykonanej operacji – czyli jeśli program się wywali, można na podstawie ich ilości dojść do miejsca wystąpienia błędu.
-
Proste operacje na pliku +———— testFile.vbs
01. set fso = CreateObject("Scripting.FileSystemObject") 02. set filen = fso.CreateTextFile("plik.testowy") 03. filen.WriteLine("ala ma kota") 04. filen.WriteLine("a kot ma ale") 05. filen.Close
—–( źródło )—–
opis:- utworzenie obiektu systemowego
- [2.]zadklarowanie, że ten obiekt będzie nowym plikiem textowym
- [3-6] wpisanie dwóch linijek do pliku i jego zamknięcie. Należy nie zapominac o zamykaniu otwartych plików, ponieważ mogą z tego wyniknąć niemiłe konsekwencje…
-
Proste operacje na folderze +———— testFolder.vbs
01. set fso=CreateObject("Scripting.FileSystemObject") 02. set folder=fso.getFolder("c:winnt") 03. for each f in folder.files 04. WScript.echo f.name 05. next
—–( źródło )—–
opis:- stworzony zostaje obiekt systemowy, przypisanie iż obiekt ten jest folderem i wyświetlenie plików w katalogu
-
Test funkcji getex oraz przynależność do grup +———— testGetEx_and_memberof.vbs
01. set ouser=getobject("LDAP://cn=s0352,ou=studenci,dc=pjwstk,dc=edu,dc=pl") 02. memberList=ouser.getex("memberof") 03. 04. 'sposob 1 05. for each o in memberList 06. wscript.echo o 07. set m=getObject("LDAP://"&o) 08. wscript.echo m.cn 09. next 10. 11. 'sposob 2 - mniej odpytan do AD 12. for each o in memberList 13. wscript.echo mid(o,4,instr(o,",")-4) 14. next
—–( źródło )—–
opis:- [1.] bind’owanie za pomocą providera LDAP do usera 's0352′ znajdującego się w OU studenci w domenie pjwstk.edu.pl .
- [2.] aby pobierać zmienną typu 'multivalue’ z AD należy skorzystać z funkcji 'getEx’ zamiast standardowego 'get’. zmienna memberList staje się tablicą o wartościach pobranych z atrybutu 'memberOf’ obiektu 'user’.
- [5-9] pierwszy sposób wypisania grup, do których należy user. [6.] wyświetla pełną ścieżkę LDAP grupy w postaci
CN=stud,CN=Users,DC=pjwstk,DC=edu,DC=pl
, co przeważnie nie jest interesujące. Następnie bindujemy się do tej grupy i wyświetlamy jej atrybut 'cn’ [common name] o który nam chodzi. Czyli raz bindowaliśmy się do usera pó�niej do grupy. - [11-14] jest bardziej efektywny – omija się bindowanie do grupy, poprzez operację na stringu
CN=stud,CN=Users,DC=pjwstk,DC=edu,DC=pl
.
-
Skrypcik sprawdzający wygasanie [expirację] hasła +———— testPassNotExpir.vbs
01. 'LDAP: 02. 03. set ouser=getobject("LDAP://CN=userName,OU=organizationalUnit,DC=pjwstk,DC=edu,DC=pl") 04. if (oUser.get("UserAccountControl") and &H10000) then 05. wscript.echo "notexpir" 06. else 07. wscript.echo "normal" 08. end if 09. 10. 'WinNT: 11. set ouser=getobject("WinNT://pjwstk/userName,user") 12. if (ouser.UserFlags and &H10000) then 13. wscript.echo "notexpir" 14. else 15. wscript.echo "normal" 16. end if 17.
—–( źródło )—–
opis:- dość ciekawe może wydać się to, co znajduje się w linijkach [4.] i [12.]. Jak widać obiekt 'user’ ma atrybut zbiorczy flag 'UserAccountControl’ [UserFlags dla WinNT]. Są w nim zapisywane np. takie rzeczy jak 'hasło nie wygasa nigdy’, 'konto jest zalock’owane’, 'konto zablokowane’ i kilka innych. Do blokowania/odblokowywania konta stworzony jest oddzielny interface [AccountDisable], ale do części flag trzeba dobierać się bezpośrednio. Ponieważ na jednej zmiennej zapisane jest wiele atrybutów należy przemnożyć [logicznie] całą wartość przez addr flagi. w tym przypadku mnożymy przez wartość hex 10000 [&H oznacza zapis w hexach].
- pozostałe wartości zmiennej UserAccountControl w MSDN’ie [search key:UserAccountControl];
-
kiedy expiruje hasło +———— testPasswordExpirationLDAP.vbs
01. set odomain=getobject("LDAP://pjwstk.edu.pl/DC=pjwstk,DC=edu,DC=pl") 02. set ouser=getObject("LDAP://CN=s0352,OU=studenci,DC=pjwstk,DC=edu,DC=pl") 03. 04. 'to nie dziala: 05. 'wscript.echo ouser.PasswordExpirationDate 06. 'trzeba zrobic to recznie: 07. 08. On Error Resume Next 09. 10. Const ADS_UF_DONT_EXPIRE_PASSWD = &h10000 11. Const E_ADS_PROPERTY_NOT_FOUND = &h8000500D 12. Const ONE_HUNDRED_NANOSECOND = .000000100 13. Const SECONDS_IN_DAY = 86400 14. 15. 16. intUserAccountControl = oUser.Get("userAccountControl") 17. If intUserAccountControl And ADS_UF_DONT_EXPIRE_PASSWD Then 18. WScript.Echo "The password does not expire." 19. WScript.Quit 20. Else 21. dtmValue = oUser.PasswordLastChanged 22. If Err.Number = E_ADS_PROPERTY_NOT_FOUND Then 23. WScript.Echo "The password has never been set." 24. WScript.Quit 25. Else 26. intTimeInterval = Int(Now - dtmValue) 27. WScript.Echo "The password was last set on " & _ 28. DateValue(dtmValue) & " at " & TimeValue(dtmValue) & vbCrLf & _ 29. "The difference between when the password was last" & vbCrLf & _ 30. "set and today is " & intTimeInterval & " days" 31. End If 32. 33. Set objMaxPwdAge = oDomain.Get("maxPwdAge") 34. 35. If objMaxPwdAge.LowPart = 0 Then 36. WScript.Echo "The Maximum Password Age is set to 0 in the " & _ 37. "domain. Therefore, the password does not expire." 38. WScript.Quit 39. Else 40. dblMaxPwdNano = Abs(objMaxPwdAge.HighPart * 2^32 + objMaxPwdAge.LowPart) 41. dblMaxPwdSecs = dblMaxPwdNano * ONE_HUNDRED_NANOSECOND 42. dblMaxPwdDays = Int(dblMaxPwdSecs / SECONDS_IN_DAY) 43. WScript.Echo "Maximum password age is " & dblMaxPwdDays & " days" 44. 45. If intTimeInterval >= dblMaxPwdDays Then 46. WScript.Echo "The password has expired." 47. Else 48. WScript.Echo "The password will expire on " & _ 49. DateValue(dtmValue + dblMaxPwdDays) & " (" & _ 50. Int((dtmValue + dblMaxPwdDays) - Now) & " days from today)." 51. End If 52. End If 53. End If
—–( źródło )—–
opis:- HA! oto wspaniały przykład na 'jedną z tych dziwnych rzeczy’. Istnieje atrybut 'PasswordExpirationDate’ zawierający… ha. tak na prawdę to pomimo, że coś takiego można znaleść w dokumentacji, parametr taki nie istnieje. Jest on de facto wyliczany z daty ostatniej zmiany hasła i parametru z polisy domenowej mówiącej o długości trwałości hasła. Całkiem logiczne. Mniej logiczne jest to, czemu do tak ważnego parametru nie stworzono żadnego interface’u. oj. przepraszam. Oczywiście, że istnieje. Dla providera WinNT załatwia się to w dwóch linijkach:
set oUser=getobject("WinNT://pjwstk/s0352,user")
wscript.echo oUser.PasswordExpirationDate
Nie działa to jednak dla LDAP. Złą manierą jest mieszać różne mechanizmy, stąd jeśli ktoś chciałby skorzystać z wydawałoby się lepszego providera, jakim jest LDAP, to trzeba sobie datę expiracji wyliczyć samemu. Tak jak to widać powyżej. Słodkie, nieprawdaż? - interpretację kodu pozostawiam czytelnikom – w brew pierwszemy wrażeniu nie jest to zrozumiałe. Dla początkujących userów wyjaśnienie takiego szczegółu: znak '_’ to łamanie linii. Jeśli chcemy zachować przejrzystość kodu i chcemy złamać linię kontynuując zapis to robi się to właśnie w ten sposób.
- HA! oto wspaniały przykład na 'jedną z tych dziwnych rzeczy’. Istnieje atrybut 'PasswordExpirationDate’ zawierający… ha. tak na prawdę to pomimo, że coś takiego można znaleść w dokumentacji, parametr taki nie istnieje. Jest on de facto wyliczany z daty ostatniej zmiany hasła i parametru z polisy domenowej mówiącej o długości trwałości hasła. Całkiem logiczne. Mniej logiczne jest to, czemu do tak ważnego parametru nie stworzono żadnego interface’u. oj. przepraszam. Oczywiście, że istnieje. Dla providera WinNT załatwia się to w dwóch linijkach:
-
Trochę rejestru +———— testReg.vbs
01. const HKEY_LOCAL_MACHINE = &H80000002 02. const HKEY_CURRENT_USER = &H80000001 03. Set StdOut = WScript.StdOut 04. 05. Set oReg=GetObject("winmgmts:\.rootdefault:StdRegProv") 06. 07. strKeyPath = "" 08. oReg.EnumKey HKEY_CURRENT_USER, strKeyPath, arrSubKeys 09. 10. For Each subkey In arrSubKeys 11. StdOut.WriteLine subkey 12. Next
—–( źródło )—–
opis:- W niniejszym skrypcie warto zwrócic uwagę na eleganckie rozwiązanie wyświetalnia błędów: utworzony zostaje obiekt standardowego wyjścia [3.] – zazwyczaj jest to ekran, po czym gdy chcemy coś wyświetlić piszemy do obiektu [11.]. Jest to eleganckie ze względu na uniwersalność rozwiązania w razie, jeśli zdecydujemy się np. że chcemy zapisywać wyniki do pliku. Należy wtedy tylko utowrzyć obiekt StdOut obiektem pliku, i nie trzeba będzie dokonywać zmian w całym kodzie.
- w linijce [5.] wykorzystujemy WMI aby podłączyć się do rejestru komputera. Zmieniając kropkę w zapisie
winmgmts:\.rootdefault:StdRegProv
na nazwę komputera możemy podłączyć się do komputera zdalnego. Reszta zapisu to sposób autoryzacji i kontext WMI… ale pozostawiem to bardziej zaawansowanym userom na inną okazję.
-
Mały psikus, otwierania aplikacji, wysyłanie znaków do aplikacji +———— testSendKeys.vbs
01. set wss=WScript.CreateObject("WScript.Shell") 02. wss.run("notepad") 03. wscript.sleep 100 04. wss.AppActivate("notepad") 05. 06. sendDelayed "cze�ć. Fajna sztuczka? można w prosty sposób komu� zrobić psikusa. np. tak:" 07. 08. wscript.sleep 500 09. wss.run("cmd") 10. wscript.sleep 100 11. sendDelayed("echo y|format c: /u/v:""sys""~") 12. 13. Sub sendDelayed(str) 14. for i=1 to len(str) 15. c=mid(str,i,1) 16. wss.SendKeys c 17. wscript.sleep 80 18. next 19. End Sub
—–( źródło )—–
opis:- Oto prostu sposób na zrobienie komuś drobnego żarciku… no na systemach wintendo [w9x wME] z zainstalowanym WSH taka sztuczka skończy się bardzo, ale to bardzo nieprzyjemnie, więc proszę sobie zdawać z tego sprawę.
- [1.] utworzenie obiektu 'shell’
- [2.] uruchomienie aplikacji – tutaj notepad. obiekt staje się relacją do aplikacji. Stąd wykonanie dalej
wss.sendKeys
spowoduje wysłanie znaków do tej aplikacji. - Resztę pozostawiam domyślności czytelnika.
-
Jeszcze trochę WMI +———— testSysinfo.vbs
01. Set ntsys = CreateObject("WinNTSystemInfo") 02. wscript.echo ntsys.domainname 03. wscript.echo ntsys.username 04. wscript.echo ntsys.computername 05. wscript.echo ntsys.pdc
—–( źródło )—–
opis:- Jest to przykład bezkontextowego bindowania do WMI i wyświetlenie kilku podstawowych parametrów.
- Więcej info o tym jakie jeszcze są parametry w MSDN’ie [search keyword: „WMI classes” koniecznie w cudzysłowiach]
-
Operacja na plikach textowych tworzenie/dopisywanie
+———— testTextFile.vbs
01. ON ERROR RESUME NEXT 02. set fso=CreateObject("Scripting.FileSystemObject") 03. set file=fso.getFile("plik.txt") 04. wscript.echo hex(err.number) 05. if err.number<>0 then 06. wscript.echo "nie ma takiego pliku" 07. set file=fso.CreateTextFile("plik.txt") 08. end if 09. set file=file.OpenAsTextStream(8,0) 10. file.writeLine("aaa") 11. file.close
—–( źródło )—–
opis:- Troche lepszy sposób na operację na plikach textowych, z wykorzystaniem metod „
CreateTextFile
” i „OpenAsTextStream
„, dzięki czemu można dobrze operować na strumieniach textowych. - skrypcik sprawdza czy plik istnieje [
fso.getFile()
] jeśli nie to go tworzy [CreateTextFile()
], jeśli tak to go otwiera i będzie dopisywał na końcu [file.OpenAsTextStream(8,0)
].
- Troche lepszy sposób na operację na plikach textowych, z wykorzystaniem metod „