Centrum skryptów - Systemy operacyjne

Jak zmapować dysk na podstawie podsieci danego komputera?

Udostępnij na: Facebook

Skrypciarze odpowiadają na Wasze pytania

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 zmapować dysk na podstawie podsieci danego komputera?

Cześć, Skrypciarze! Moi ludzie zajmujący się CAD-em dość często podróżują. Chciałbym utworzyć skrypt logowania, który mapowałby dyski pod kątem ich lokalizacji w danym czasie, chodzi mi tu o podsieć. Chciałbym, żeby najpierw sprawdził, czy dany dysk został już zmapowany, a jeżeli tak, to żeby nie dokonywał żadnych zmian. Jeżeli jednak nie został jeszcze zmapowany, to chciałbym, żeby go zmapował w zależności od jego podsieci w danym czasie. Jak to zrobić?

-- GM

Cześć, GM! Myślisz sobie zapewne: „No, Olimpiada Skrypciarska 2008 dobiegła końca, Skrypciarz będzie musiał więc pisać o czymś innym”. Jeżeli tak myślicie, to jesteście w błędzie, o Olimpiadzie mogę pisać bezustannie – dziś na przykład mógłbym napisać, jakie zmiany planujemy w przyszłorocznej edycji. Owszem, straciłem trochę kontakt z rzeczywistością, nie wiem tak do końca kto prowadzi w wyborach. Nie wiem też kto ma jaki wynik w baseballu. No, w sumie to zupełnie nie wiem, co się dzieję, muszę chyba wziąć cały dzień wolnego na oglądanie różnych wiadomości i nadrobienie zaległości z wiedzy ogólnej.

Wiem natomiast, gdzie który dysk się znajduje, do tego nie potrzeba specjalnej wiedzy. Musicie tylko skorzystać z poniższego skryptu, który mapuje dany dysk na podstawie jego podsieci w danym momencie:

Set objNetwork = CreateObject("Wscript.Network")



strComputer = "."



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



Set colAdapters = objWMIService.ExecQuery _

    ("Select * From Win32_NetworkAdapterConfiguration Where IPEnabled=True")



For Each objAdapter in colAdapters

    For Each strAddress in objAdapter.IPAddress

        arrOctets = Split(strAddress, ".")

        If arrOctets(0) <> "" Then

            strSubnet = arrOctets(0) & "." & arrOctets(1) & "." & arrOctets(2)

            x = 1

            Exit For

        End If

        If x = 1 Then

            Exit For

        End If

    Next

Next



Set colItems = objWMIService.ExecQuery _

    ("Select * From Win32_LogicalDisk Where DeviceID = 'H:'")



If colItems.Count = 0 Then

    Select Case strSubnet

        Case "192.168.1" 

            objNetwork.MapNetworkDrive "H:", "\\arizona-fs-01\public"

        Case "192.168.2" 

            objNetwork.MapNetworkDrive "H:", "\\newmexico-fs-01\public"

        Case "192.168.3" 

            objNetwork.MapNetworkDrive "H:", "\\texas-fs-01\public"

    End Select

End If

Zanim zaczniemy, pozwolę sobie tylko nadmienić, że dziś pokażemy tylko, jak zmapować pojedynczy dysk. Jeżeli chcecie zmapować jeszcze jakieś dyski, to musicie:

  • Skopiować kod sprawdzający istnienie danego dysku.
  • Skopiować kod odpowiedzialny za zmapowanie dysku na podstawie podsieci.
  • Zmienić literę dysku i jego ścieżkę w zależności od potrzeb.

Tyle o innych możliwościach zastosowania naszego wspaniałego kodu. Powróćmy teraz do dzisiejszego kodu. Zaczynamy od utworzenia wystąpienia obiektu Wscript.Network; dzięki niemu będziemy mapować dysk za pomocą skryptu VBScript. Nastepnie łączymy się z usługą WMI na komputerze lokalnym, po czym korzystamy z poniższego wiersza kodu i metody ExecQuery w celu pobrania kolekcji wszystkich kart sieciowych zgodnych z TCP/IP na danym komputerze:

Set colAdapters = objWMIService.ExecQuery _

    ("Select * From Win32_NetworkAdapterConfiguration Where IPEnabled=True")

Jak powszechnie wiadomo, w obecnych czasach komputer może posiadać więcej niż jeden adres IP. Dzieje się tak na przykład, gdy jest podłączony do sieci jednocześnie przewodowo oraz bezprzewodowo. Nie stanowi to dla nas jednak żadnego problemu – zakładamy, że nawet jeżeli komputer ma więcej niż jeden adres IP, to i tak należą one do jednej podsieci. Mogą oczywiście sprawić nam problemy, ale jak napisaliśmy, zakładamy, że nie będą kłopotliwe, starczy więc nam jeden adres IP.

Co jednak, jeżeli zależy nam, żeby łącze przewodowe miało pierwszeństwo nad bezprzewodowym? Tym tematem zajmiemy się kiedy indziej. Teraz powróćmy do tematu kart sieciowych.

Pobieramy teraz kolekcję wszystkich kart sieciowych zgodnych z TCP/IP, a następnie ustawiamy pętlę For Each, która przechodzi przez wszystkie karty sieciowe w kolekcji:

For Each objAdapter in colAdapters

Żeby jeszcze bardziej skomplikować Wam życie, przypominamy, że jest również możliwe, żeby jedna karta sieciowa posiadała więcej niż jeden adres IP. Przecież właściwość IPAddress dla klasy WMI Win32_NetworkAdapterConfiguration przechowuje adresy IP w tablicy. Co to dla nas oznacza? Oznacza to, że w celu ustalenia adresu IP danego komputera musimy uruchomić drugą pętlę For Each. Ta druga pętla przejdzie przez adresy IP przypisane do danych kart sieciowych:

For Each strAddress in objAdapter.IPAddress

Wewnątrz drugiej pętli używamy metody Split , która rozdziela adres IP kropką:

arrOctets = Split(strAddress, ".")

Po co ta kropka? Każda podsieć składa się najczęściej z dwóch lub trzech pierwszych „oktetów” adresu IP (w zależności od tego, co rozumiecie przez słowo podsieć). Dla przykładu, adres IP 192.168.1.1 znajdziecie zapewne na podsieci 192.168.1. Prostym sposobem na otrzymanie pierwszych trzech oktetów jest rozdzielenie adresu za pomocą tablicy składającej się z następujących elementów:

  • 192
  • 168
  • 1

Kiedy dysponujemy już tablicą, następnym krokiem będzie zweryfikowanie czy to, co mamy jest rzeczywiście adresem IP, czy pustym ciągiem:

If arrOctets(0) <> "" Then

Zakładamy, że jest to adres, tworzymy więc nowy ciąg dla podsieci, składający się z pierwszych trzech oktetów (i kropek miedzy nimi):

strSubnet = arrOctets(0) & "." & arrOctets(1) & "." & arrOctets(2)

Innymi słowy, strSubnet będzie równy 192.168.1.

Teraz, gdy posiadamy już aktualny adres IP, ustawiamy wartość zmiennej x na 1, a następnie przywołujemy twierdzenie Exit For i wychodzimy z pętli For Each:

x = 1

Exit For

Po wyjściu z pętli sprawdzamy wartość x. Jeżeli jest równa 0, to oznacza to, że jeszcze nie odnaleźliśmy adresu IP, dlatego musimy powrócić do początku pętli zewnętrznej i rozpocząć wyszukiwanie na nowo, tym razem dla kolejnej karty sieciowej w kolekcji. Jeżeli x jest równe 1, oznacza to, że znaleźliśmy adres IP, wywołujemy więc ponownie twierdzenie Exit For, tym razem w celu wyjścia z pętli zewnętrznej (czyli tej, która przechodzi przez kolekcję kart sieciowych).

Dość mozolne to wszystko, ale skuteczne.

Teraz jesteśmy już gotowi do zmapowania dysku (dysku H), oczywiście przy założeniu, że dysk nie jest jeszcze zmapowany gdzie indziej. W celu zweryfikowania tego uruchamiamy następującą kwerendę WMI, która zwróci nam kolekcję dysków, których litera (DeviceID) jest równa H:

Set colItems = objWMIService.ExecQuery _

    ("Select * From Win32_LogicalDisk Where DeviceID = 'H:'")

Po zrobieniu tego powracamy do kolekcji w celu zweryfikowania, czy posiadamy w niej literę dysku – H. Robimy to, sprawdzając wartość właściwości Count naszej kolekcji; właściwość ta informuje nas, ile elementów (dysków) znajduje się w kolekcji:

If colItems.Count = 0 Then

Jeżeli jest równa 0, to oznacza to, ze komputer nie posiada dysku H, jeżeli zaś jest równa 1, to oznacza to coś odwrotnego, czyli jak zapewne się domyślacie fakt, że komputer posiada dysk H i należy go zostawić w spokoju. Jeżeli z kolei licznik jest równy 0, to sprawdzamy wartość strSubnet i mapujemy dysk H w zależności od tej wartości:

Select Case strSubnet

    Case "192.168.1" 

        objNetwork.MapNetworkDrive "H:", "\\arizona-fs-01\public"

    Case "192.168.2" 

        objNetwork.MapNetworkDrive "H:", "\\newmexico-fs-01\public"

    Case "192.168.3" 

        objNetwork.MapNetworkDrive "H:", "\\texas-fs-01\public"

End Select

Jeżeli nasza podsieć jest równa 192.168.1, to mapujemy dysk H do folderu \\arizona-fs-01\public, jeżeli wynosi 192.168.2, to mapujemy dysk H do folderu \\newmexico-fs-01\public. Itp., itd.

Myślę, że to dość wyczerpująca odpowiedź na Twoje pytanie, GM!

Co na świecie? Już sobie wszystko „odświeżyłem” (szkoda, ze mój mózg nie posiada takiej funkcji). Prezydent wyraził ponoć poparcie dla Johna McCaina i obiecał pomagać mu w kampanii wyborczej. Benedyktyni jadą na Kubę, bo Fidel Castro lubi ser. Kosowo niepodległe, w Niemczech strajki… Coś jeszcze?

Dobrze, o sporcie będzie jutro.

 Do początku strony Do początku strony

Centrum skryptów - Systemy operacyjne