Centrum skryptów - Systemy operacyjne

Jak utworzyć listę drukarek sieciowych dostępnych dla zalogowanego użytkownika?

Udostępnij na: Facebook

Skrypciarze odpowiadają na Wasze pytania

Cześć Skrypciarze!

Witamy w rubryce TechNet, w której Skrypciarze z firmy Microsoft odpowiadają na częste pytania dotyczące używania skryptów w administracji systemu. Jeśli macie jakieś pytania z tej dziedziny, zachęcamy do wysłania e-maila na adres: scripter@microsoft.com. Nie możemy zagwarantować odpowiedzi na każde otrzymane pytanie, ale staramy się jak możemy.

Jak utworzyć listę drukarek sieciowych dostępnych dla zalogowanego użytkownika?

Cześć Skrypciarze! Pytanie

Cześć, Skrypciarze! Jak utworzyć skrypt logowania tworzący listę drukarek sieciowych dostępnych dla zalogowanego użytkownika i zapisujący te informacje w pliku tekstowym?

-- RC

Cześć Skrypciarze! Odpowiedź

Cześć, RC! Najfajniejszą rzeczą po powrocie do pracy z weekendu czy wakacji jest… rety, nic nie przychodzi mi do głowy i w sumie nie wiem, co może być chociaż trochę fajnego po powrocie z urlopu. Nawet mój talent pisarski zawodzi w obliczu czegoś tak potwornego, powrót z weekendu czy urlopu. Chociaż inni mają pewnie gorzej, bo ja po wakacjach wracam zawsze do firmy Microsoft, a tam chociaż dokarmiam się intelektualnie i lingwistycznie, podsłuchując rozmowy kolegów i koleżanek. Taką na przykład rozmowę usłyszałem (broń Boże nie podsłuchałem) dziś w toalecie:

-No to jak to się stało, ze dostał gabinet z oknem?

-No musiałem mu dać. Powiedział, ze bez okna robi się nerwowy, a nawet może dostać ataku furii (nie padł przy tym ani jeden wulgaryzm – przyp.aut.). Nie chciałem żeby wpadał we wściekłość, więc musiałem mu dać to okno, no nie?

Nie trzeba chyba nadmieniać, że pokoje z oknem są w biurowcu najcenniejszym towarem i przydzielane są tylko najlepszym i najbystrzejszym (oraz naszej Skrypciarskiej Redaktorce). Tylko że nie wiedzieć czemu autor niniejszego artykułu siedzi teraz za biurkiem w pokoju bez okna… Może dlatego, że ukrywa się pod bardzo zmyślnym pseudonimem i mało kto zna jego prawdziwe imię. Może też dlatego, ze nigdy jeszcze nie zagroził nikomu, że bez okna dostanie ataku szału. Czas się nad tym zastanowić i wymyślić jakiś ciekawy napad, bo może za pomysłowy atak można dostać nawet dwa okna.

Tylko, że w żadnym wypadku atak szału. Na przemoc biurową trzeba być przynajmniej nierozleniwionym, czego nie można powiedzieć o piszącej to osobie, a na atak frustracji się nie nadajemy, ponieważ czujemy się w 100% spełnieni, mogąc napisać skrypt logowania tworzący listę drukarek sieciowych dostępnych dla zalogowanego użytkownika:

Const ForWriting = 2



Set objNetwork = CreateObject("Wscript.Network")



strName = objNetwork.UserName

strDomain = objNetwork.UserDomain

strUser = strDomain & "\" & strName



strText = strUser & vbCrLf



strComputer = "."



Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")



Set colPrinters = objWMIService.ExecQuery _

    ("Select * From Win32_Printer Where Local = FALSE")



For Each objPrinter in colPrinters

    strText = strText & objPrinter.Name & vbCrLf

Next



Set objFSO = CreateObject("Scripting.FileSystemObject")



Set objFile = objFSO.CreateTextFile _

    ("C:\Scripts\Printers.txt", ForWriting, True)



objFile.Write strText



objFile.Close

Dwie uwagi, zanim przejdę do objaśniania, na jakiej zasadzie działa nasz skrypt. Więc po pierwsze primo, nie zadziała na pewno ani w systemie Windows 2000, ani w żadnej wcześniejszej wersji. Dzieje się dlatego, że w tych wersjach systemu Windows klasa WMI Win32_Printer nie zawiera właściwości Local. Nie wpadajcie w szał – pokażemy także skrypt, który zadziała w starszych wersjach Windows.

Po drugie primo (wiem, wiem, że tak się nie mówi, ale może redakcja dojdzie do wniosku, że tracę zmysły robiąc tak poważne błędy językowe jak „po pierwsze primo”, nie mówiąc już o „po drugie primo”), powyższy skrypt zapisuje informację w pliku tekstowym o nazwie C:\Scripts\Printers.txt; każde uruchomienie skryptu powoduje zastąpienie zawartości pliku printers.txt najbardziej aktualną kolekcją informacji o drukarkach. Wszystko OK, ale być może nie o to chodziło. Jeśli tak, to konieczne będzie zmodyfikowanie kodu tworzącego zapisy do pliku tekstowego.

Teraz już możemy zabrać się za tłumaczenie, jak działa nasz dzisiejszy skrypt. Najpierw definiujemy stałą o nazwie ForWriting i ustawiamy jej wartość na 2; będziemy z niej korzystać podczas zapisywania informacji o drukarce do pliku tekstowego. Następnie tworzymy wystąpienie obiektu Wscript.Network i uruchamiamy poniższe trzy wiersze kodu:

strName = objNetwork.UserName

strDomain = objNetwork.UserDomain

strUser = strDomain & "\" & strName

W pierwszych dwóch wierszach ustalamy nazwę zalogowanego użytkownika (używamy przy tym właściwości UserName) oraz jego domenę (właściwość UserDomain). W trzecim wierszu natomiast łączymy nazwę użytkownika z domeną, podając nazwę użytkownika w formacie DOMAIN\username. Innymi słowy:

FABRIKAM\kenmyer

Następnie dołączamy do tych informacji znak powrotu karetki (używając do tego stałej vbCrLf języka VBScript) i przechowujemy je w zmiennej o nazwie strText:

strText = strUser & vbCrLf

Łączymy się potem z usługą WMI na komputerze lokalnym (z uwagi na to, ze jest to skrypt logowania, nie musimy się martwić o łączenie z usługą WMI na komputerze zdalnym). Następnie, używając poniższych wierszy kodu, pobieramy kolekcję wszystkich drukarek sieciowych dla danego komputera:

Set colPrinters = objWMIService.ExecQuery _

    ("Select * From Win32_Printer Where Local = FALSE")

Wybieramy tutaj wystąpienia klasy Win32_Printer lub przynajmniej wystąpienia, których właściwość Local ustawiona jest na False. Wynik naszej operacji jest następujący: jeżeli właściwość Local miała wartość True, mamy do czynienia z drukarką lokalną, a nie sieciową. Dlatego też skrypt nie działa dla programu Windows 2000 – klasa Win32_Printer w programie Windows 2000 nie zawiera właściwości Local.

Nie martwcie się jednak, a pod żadnym pozorem nie wpadajcie we wściekłość (szczególnie jeżeli siedzicie w pokoju bez okien), obiecaliśmy przecież, że można wyjść z tego impasu lokalnego.

Zanim jednak zdradzimy, jak to zrobić, skończmy najpierw objaśnianie skryptu wyjściowego. Po pobraniu informacji na temat drukarki uruchamiamy pętlę, która przechodzi przez całą kolekcję. Dla każdej drukarki w kolekcji używamy poniższego wiersza kodu i dodajemy nazwę (Name) drukarki do zmiennej strText:

strText = strText & objPrinter.Name & vbCrLf

Dzięki temu przypisujemy zmiennej strText nową wartość, która jest niczym innym, jak tylko istniejącą wartością strText, do której dodajemy nazwę drukarki oraz znak powrotu karetki.

Reszta to betka. Najpierw tworzymy wystąpienie obiektu Scripting.FileSystemObject, następnie korzystając z metody CreateTextFile, tworzymy nowy plik tekstowy o nazwie C:\Scripts\Printers.txt:

Set objFile = objFSO.CreateTextFile _

    ("C:\Scripts\Printers.txt", ForWriting, True)

Należy zwrócić uwagę na trzy parametry przekazywane metodzie CreateTextFile method:

Kompletna ścieżka (C:\Scripts\Printers.txt).
Stała ForWriting, która wskazuje na to, że chcemy dokonać zapisu w pliku.
Wartośc True, która instruuje skrypt, aby zastąpił istniejące wystąpienia C:\Scripts\Printers.txt. Jeżeli plik Printers.txt istnieje, skrypt go zastąpi, jeżeli jeszcze nie istnieje, nasz skrypt go dopiero utworzy

Następnie przywołujemy metodę Write i zapisujemy informację na temat drukarki do pliku, po czym używając metody Close zamykamy plik. Podczas otwierania pliku tekstowego powinniśmy zobaczyć taką informację:

FABRIKAM\kenmyer

\\atl-ps-01\b43-2927-a

\\atl-ps-01.fabrikam.com\b43-2315-a

\\atl-ps-02\HP LaserJet 5MP

Właśnie to chcielismy zobaczyć.

Co z systemem Windows 2000? Oto skrypt logowania, który będzie działał w wersji 2000 oraz Windows NT:

Const ForWriting = 2



strComputer = "."



Set objNetwork = CreateObject("Wscript.Network")



strName = objNetwork.UserName

strDomain = objNetwork.UserDomain

strUser = strDomain & "\" & strName



Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")



strText = strUser & vbCrLf



Set colPrinters = objWMIService.ExecQuery("Select * From Win32_Printer")



For Each objPrinter in colPrinters

    If Not objPrinter.Attributes And 64 Then 

        strText = strText & objPrinter.Name & vbCrLf

    End If

Next



Set objFSO = CreateObject("Scripting.FileSystemObject")



Set objFile = objFSO.CreateTextFile _

    ("C:\Scripts\Printers.txt", ForWriting, True)



objFile.Write strText



objFile.Close

Jaka jest różnica między skryptami? Tym razem musimy zwrócić wszystkie drukarki, zarówno lokalne, jak i sieciowe. Następnie sprawdzamy wartość właściwości typu maska bitów Attributes. Jeśli przełącznik o wartości 64 jest włączony, oznacza to, że chodzi o drukarkę lokalną. W przeciwnym razie musi to być drukarka sieciowa. W takim wypadku dodajemy właściwość Name drukarki do zmiennej strText.

Zanim jednak skończę, dodam, że po przemyśleniu dochodzę do wniosku, że pierwotna teza, iż pokoje z oknem przydzielane są tylko najlepszym i najbystrzejszym nie może być prawdziwa, bo nie ma innej opcji – pokój z największą liczbą okien musiałbym dostać ja. Przypuszczam, że chodzi tu tylko i wyłącznie o wiek i że nasza skrypciarska Redaktorka dostała tak lukratywny przydział nie z uwagi na to, że uważa się ją za bardzo, bardzo bystrą, a raczej bardzo, bardzo podeszłą w wieku (nie wypada napisać starą przecież).

Nie mówcie jej tylko o tym!

Uwaga od Redaktorki: Byłam w dziale personalnym i autor powyższych wypocin jest znacznie starszy od redaktorki, więc obala to chyba teorię o wieku... Ale więcej nic nie powiem, bo jeszcze by zrozumiał aluzję.
 Do początku strony Do początku strony

Centrum skryptów - Systemy operacyjne