Centrum skryptów - Systemy operacyjne

Jak mapować dyski na podstawie adresu IP? 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 mapować dyski na podstawie adresu IP?

Cześć Skrypciarze! Pytanie

Cześć Skrypciarze! Używam waszego skryptu mapującego dyski na podstawie uczestnictwa w grupie i działa on całkiem dobrze. Jednak muszę go zmodyfikować tak, aby mapowanie dysków opierało się także na lokalizacji komputera (dokładniej mówiąc – na jego adresie IP). Przykładowo, mamy zdalną filię, która używa połączenia ISDN. Nie chcę, aby mapowanie dysków miało miejsce dla tego łącza; chcę natomiast, aby mapowanie dysków miało miejsce na lokalnym serwerze. Jak zmodyfikować wasz skrypt, aby podczas mapowania dysków wykorzystywał zarówno uczestnictwo w grupie, jak i adres IP?

-- BT

Cześć Skrypciarze! Odpowiedź

Cześć, BT. Zanim przejdę do skryptu, chcę opowiedzieć o pewnym zdarzeniu. Zaczepił mnie ostatnio jakiś praktykant na korytarzu i zapytał, jaką dobrą wyszukiwarkę internetową mógłbym mu polecić. Zgadnijcie, co mu odpowiedziałem Oczywiście:.

„Polecam Windows Live Search, to nie tylko bardzo dobra wyszukiwarka internetowa, ale także jedyna.”

Chyba mi uwierzył. Nie był to może miły żart i nie wszyscy go rozumieją, ale nie mogłem się powstrzymać.

No dobra, zabieram się do pracy.

BT używa skryptu logowania (opisanego we wcześniejszym artykule) jako sposobu mapowania dysków sieciowych na podstawie uczestnictwa użytkownika w określonej grupie katalogu Active Directory. Potrzebuje jednakże dodać kolejny warunek opierający się na adresie IP komputera (a mówiąc bardziej konkretnie – na trzecim oktecie adresu IP). Przykładowo, jeżeli użytkownik należy do grupy Finance Users, a adres komputera to 192.168.36.1, dysk zostanie zmapowany do \\atl-fs-01\finance. W przeciwnym wypadku, dysk zostanie zmapowany do \\atl-fs-02\finance.

Tak przy okazji, dzisiejsze pytanie jest chyba bardzo popularne, dostaliśmy już kilka zapytań o mapowanie dysków na podstawie adresu IP komputera. Dzisiejszy skrypt powinien zadowolić wiele osób.

Uwaga. Dostaliśmy także kilka maili z prośbą o polecenie dobrej wyszukiwarki internetowej. Oczywiście, że możemy: Windows Live Search.

Windows Live Search. To nie tylko dobra wyszukiwarka internetowa, to także jedyna wyszukiwarka internetowa.

Uwaga Redaktorki: Z uwagi na fakt, iż zawsze jesteśmy prawdomówni, przyznajemy, że Windows Live Serach może nie być jedyną wyszukiwarką internetową (z naciskiem na może). Jeżeli nie jest, poudawajmy, że jednak tak.

Jak zatem pomóc BT? Za pomocą poniższego skryptu:

On Error Resume Next



Set objSysInfo = CreateObject("ADSystemInfo")

Set objNetwork = CreateObject("Wscript.Network")



strUserPath = "LDAP://" & objSysInfo.UserName

Set objUser = GetObject(strUserPath)



strComputer = "."



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



Set colItems = objWMIService.ExecQuery _

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



For Each objItem in colItems

    For Each objAddress in objItem.IPAddress

        arrIPAddress = Split(objAddress, ".")

        If arrIPAddress(0) <> 0 AND arrIPAddress(0) <> 169 Then

            strAddress = arrIPAddress(2)

            Exit For

        End If

    Next

    Exit For

Next



For Each strGroup in objUser.MemberOf

    strGroupPath = "LDAP://" & strGroup

    Set objGroup = GetObject(strGroupPath)

    strGroupName = objGroup.CN



    Select Case strGroupName

        Case "Finance Users"

            If strAddress = 36 Then

                objNetwork.MapNetworkDrive "X:", "\\atl-fs-01\finance"

                Exit For

            Else

                objNetwork.MapNetworkDrive "X:", "\\atl-fs-02\finance"

                Exit For

            End If

        Case "Human Resource Users" 

            If strAddress = 36 Then

                objNetwork.MapNetworkDrive "X:", "\\atl-fs-01\hr"

                Exit For

            Else

                objNetwork.MapNetworkDrive "X:", "\\atl-fs-02\hr"

                Exit For

            End If

        Case "Manufacturing Users"

            If strAddress = 36 Then

                objNetwork.MapNetworkDrive "X:", "\\atl-fs-01\manufacturing"

                Exit For

            Else

                objNetwork.MapNetworkDrive "X:", "\\atl-fs-02\manufacturing"

                Exit For

            End If

        Case "Shipping and Receiving Users"

            If strAddress = 36 Then

                objNetwork.MapNetworkDrive "X:", "\\atl-fs-01\shipping"

                Exit For

            Else

                objNetwork.MapNetworkDrive "X:", "\\atl-fs-02\shipping"

                Exit For

            End If

    End Select

Next

Tak przy okazji, niech was nie odstrasza jego długość; jest taki długi, ponieważ uwzględniliśmy w nim kod mapowania dysków dla 4 lub 5 grup. Jak zaraz sami zobaczycie, większa część tego skryptu to tekst standardowy: może być kopiowana i wklejana i w bardzo prosty sposób wykorzystywana w innych skryptach. (Na przykład po zmianie nazwy grupy lub ścieżki sieci.)

Zaczynamy pracę od utworzenia wystąpień obiektów ADSystemInfo oraz Wscript.Network; obiekt ADSystemInfo pomoże nam połączyć się z kontem użytkownika w Active Directory dla lokalnego użytkownika, a obiekt Wscript.Network zmapuje dysk sieciowy. Po utworzeniu tych dwóch obiektów utworzymy ścieżkę ADsPath dla zalogowanego użytkownika za pomocą poniższego wiersza kodu:

strUserPath = "LDAP://" & objSysInfo.UserName

Posiadając ścieżkę ADsPath, możemy połączyć się z kontem użytkownika w Active Directory,wykonując ten oto wiersz kodu:

Set objUser = GetObject(strUserPath)

Uwaga. No dobra, przyznaję – to trochę pobieżne wyjaśnienie działania obiektu ADSystemInfo. Więcej informacji znajduje się we wspomnianym archiwalnym artykule.

Mam nawet lepszy pomysł, wypróbujcie Windows Live Search i poszukajcie tych informacji w Internecie.

Bo przecież Windows Live Search to nie tylko dobra, ale… powtarzam się, tak?

Teraz określimy adres IP dla lokalnego komputera, a jest to trochę bardziej skomplikowane, niż mogłoby się nam wydawać. (Dlaczego? Ponieważ komputery mają wiele kart sieciowych i/lub wiele adresów IP.) Na początek zastosujemy następujący wiersz kodu w celu połączenia się z usługą WMI na lokalnym komputerze:

strComputer = "."



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

Teraz zastosujemy ten oto wiersz kodu w celu pobrania kolekcji wszystkich „prawdziwych” kart sieciowych zainstalowanych na tym komputerze:

Set colItems = objWMIService.ExecQuery _

    ("Select * From Win32_NetworkAdapterConfiguration Where IPEnabled = True")
Uwaga. Co mam na myśli mówiąc „prawdziwe” karty sieciowe“? No cóż, klasa Win32_NetworkAdapterConfiguration przekazuje informacje na temat całej masy wirtualnych kart sieciowych oprócz tych prawdziwych, fizycznie istniejących. Na szczęście możemy odfiltrować te zjawy, uwzględniając klauzulę Where ograniczającą pobierane dane do tych kart sieciowych, których właściwość IPEnabled ma wartość True. I to właśnie tutaj zrobiliśmy.

Teraz przechodzimy do następującego fragmentu kodu:

For Each objItem in colItems

    For Each objAddress in objItem.IPAddress

        arrIPAddress = Split(objAddress, ".")

        If arrIPAddress(0) <> 0 AND arrIPAddress(0) <> 169 Then

            strAddress = arrIPAddress(2)

            Exit For

        End If

    Next

    Exit For

Next

Uruchamiamy tutaj pętlę For Each, która przejdzie przez naszą kolekcję kart sieciowych. Następnie od razu uruchamiamy drugą pętlę For Each, która przejdzie przez możliwe adresy IP dla każdej karty (ponieważ jedna karta może mieć więcej niż jeden adres IP, właściwość IPAddress przechowuje informacje w formie tablicy) Wewnątrz tej drugiej pętli używamy funkcji Split w celu rozdzielenia pierwszego adresu IP, używając kropki jako delimitera. Jeżeli mamy adres IP 192.168.1.2, będzie to oznaczać, że otrzymamy tablicę o nazwie arrIPAddress zawierającą następujące elementy:

  • 192
  • 168
  • 1
  • 2

Jak dotąd wszystko jasne? Dobrze. Idziemy zatem dalej.

Aby upewnić się, że mamy ważny adres IP wykonujemy poniższy wiersz kodu:

If arrIPAddress(0) <> 0 AND arrIPAddress(0) <> 169 Then

Dzięki temu upewniamy się, że pierwszy oktet w adresie IP (czyli element 0 w naszej tablicy) to nie jest 0 ani 169. Jeżeli pierwszy oktet to 0, prawdopodobnie mamy do czynienia z kartą nieposiadającą przypisanego adresu IP; jeżeli pierwszy oktet to 169 – karta posiada automatycznie przypisany adres IP. Jeżeli żaden z tych warunków nie ma wartości True, zakładamy, że mamy ważny adres IP. Mając to na uwadze, stosujemy następujący wiersz kodu w celu przypisania elementu 2 z tablicy (trzeciego oktetu adresu IP) do zmiennej o nazwie strAddress:

strAddress = arrIPAddress(2)
Uwaga. Pamiętajmy, że pierwszy element w tablicy ma numer indeksu 0, a drugi element 1. Dlatego też odnosimy się do arrIPAddress(2) podczas pobierania wartości trzeciego oktetu; trzeci element w tablicy ma numer indeksu 2.

Upewniwszy się, że mamy ważny adres IP, wywołujemy instrukcję Exit For w celu opuszczenia pętli For Each. Oznacza to, że jeżeli komputer posiada kilka przypisanych mu adresów IP, wykorzystamy pierwszy znaleziony ważny adres IP. (Nie powinniśmy mieć z tym żadnych problemów, skrypty logowania zazwyczaj używane są na komputerach klienckich, a komputery klienckie mają zazwyczaj przypisany jeden adres IP.)

Teraz możemy uruchomić pętlę w kolekcji grup do których należy zalogowany użytkownik, w tym celu zastosujemy poniższy wiersz kodu (atrybut MemberOf to atrybut posiadający wiele wartości, zawierający listę wszystkich grup, których uczestnikiem jest użytkownik):

For Each strGroup in objUser.MemberOf

Co robimy wewnątrz tej pętli? No cóż, na początek, dla każdej grupy znajdującej się w kolekcji stosujemy poniższy wiersz kodu w celu połączenia się z kontem grupy w Active Directory i pobrania wartości jej atrybutu CN:

strGroupPath = "LDAP://" & strGroup

Set objGroup = GetObject(strGroupPath)

strGroupName = objGroup.CN

Teraz uruchamiamy instrukcję Select Case i zaczynamy sprawdzać, czy użytkownik jest uczestnikiem danej grupy. Jeżeli tak, mapujemy odpowiednio dysk X. Na przykład:

Case "Finance Users"

    If strAddress = 36 Then

        objNetwork.MapNetworkDrive "X:", "\\atl-fs-01\finance"

        Exit For

    Else

        objNetwork.MapNetworkDrive "X:", "\\atl-fs-02\finance"

        Exit For

    End If

Ta czynność nie powinna wydawać się zbyt trudna. Pobieramy nazwę pierwszej grupy, do której należy użytkownik i sprawdzamy, czy jest to grupa o nazwie Finance Users. Jeżeli grupa ma taką nazwę, sprawdzamy, czy trzeci oktet adresu IP ma wartość 36; do tego służy ten oto wiersz kodu:

If strAddress = 36 Then

Jeżeli trzeci oktet ma wartość 36, mapujemy dysk X do \\atl-fs-01\finance; jeżeli nie, mapujemy dysk X do \\atl-fs-02\finance. W każdym razie, po zmapowaniu dysku X stosujemy instrukcję Exit For i opuszczamy pętlę For Each; dzięki temu unikniemy błędu w przypadku, gdy użytkownik będzie należał do więcej niż jednej grupy docelowej. (Dlaczego taki błąd miałby wystąpić? Ponieważ moglibyśmy próbować zmapować dysk X do \\atl-fs-01\shipping w przypadku, gdy został on już zmapowany do \\atl-fs-01\finance. A tak nie można.)

Ważne:

Uwaga. Załóżmy, że użytkownik należy do wielu grup; czy byłoby możliwe zmapowanie wielu dysków przypisując im w miarę potrzeby nieużywane litery dysków? Tak, chociaż, rzecz jasna, wymagałoby to dodatkowego nakładu pracy. Nie mamy teraz czasu, żeby omawiać tę kwestię, ale zachęcamy do zajrzenia do innego archiwalnego artykułu, w którym jest informacja, jak określić kolejną dostępną literę dysku na komputerze.

Mam nadzieję, że odpowiedź jest wyczerpująca, BT.

 Do początku strony Do początku strony

Centrum skryptów - Systemy operacyjne