Windows - A hálózaton található összes gép MAC címének listázása

forráskód letöltése
A rendszergazda feladatai közé tartozik a hálózat gépeinek pontos ismerete. Statisztika és nyilvántartás készítéshez gyakran szokták a gépeket a bennük lévő hálózati kártya MAC címei alapján azonosítani. A MAC cím egy egyedi azonosító, amelyből nincs két egyforma a világon. Bizony nem könnyű és főleg nagyon időigényes feladat végigjárni a hálózatot és leírogatni a címeket. Ennél jobb megoldást javaslunk: készítsünk egy VBScript-et, amely elvégzi helyettünk ezt a feladatot és az eredményt kiírja egy szövegfájlba. Sőt tovább is lépünk és két szkriptet fogunk készíteni: az egyik a hálózaton elérhető összes munkacsoport és tartomány gépeit vizsgálja, a másik csak az általunk megadott munkacsoportét vagy tartományét.
Cikkünkhöz mellékelve megtalálható az alábbiakban szereplő két szkript:
"MACList1.vbs" - Futtatása után kiírja a képernyőre és a c:\ MACAddressList.txt fájlba is a hálózaton elérhető összes tartomány és munkacsoport gépeinek MAC címét.
"MACList1.vbs" - Általunk a szkript második sorában megadott tartomány vagy munkacsoport összes gépének MAC címét listázza a képernyőre vagy a c:\ MACAddressList.txt fájlba.
A szövegfájl neve és elérési útja mindkét esetben a szkriptek első sorában módosítható.
A futtatás akkor lesz sikeres, ha az aktuálisan bejelentkezett felhasználó jogosult minden gépen elérni a hálózati beállításokat.
A futtatást a parancssori "cscript szkriptnév.vbs" utasítással kell végrehajtani.
A hálózatban elérhető összes tartomány és munkacsoport vizsgálata
Nézzük először az első eshetőséget, mely a hálózat összes tartományát és munkacsoportját ellenőrzi. Haladjunk végig a szkripten lépésről-lépésre.
Definiáljunk egy változót "FileName" névvel, adjuk értékül a szövegfájl nevét, ahová az összegyűjtött adatokat fogjuk írni.
FileName="c:\MACAddressList.txt"
A Windows Scripting Host (WSH), File System Object (FSO) használatával hozzuk létre a változóban megadott szövegfájlt. Ehhez szükségünk lesz egy új "FileSystemObject" objektumra, majd a "CreateTextFile" metódus meghívására.
Set fso = CreateObject("Scripting.FileSystemObject")
Set file = fso.CreateTextFile(FileName, True)
A gyűjtés eredményét nem csak a fájlban tároljuk, hanem a képernyőn is megjelenítjük. A két ábrázolásmód eltérő lesz, mert a képernyőre olyan információkat is kiírunk (pl.: "Keresés indul ....", amit a fájlba nem. Mindkét helyen jelenjen meg a szkript futtatásának dátuma és időpontja (now rendszerváltozó). A lista eleje (fejléce) a képernyőn az alábbiak szerint alakul.
Wscript.Echo "A hálózaton található gépek MAC címeinek listája."
Wscript.Echo
Wscript.Echo "Keresés indul ...."
Wscript.Echo
Wscript.Echo now
Wscript.Echo
A szövegfájlba nem írhatunk a "Wscript.Echo" utasítással. Egy üres sor beszúrásához a "WriteBlankLines(1)" parancsot kell használnunk, míg a "WriteLine" egy szövegsort ír bele, sorvége karakterrel a végén.
file.WriteBlankLines(1)
file.WriteLine "A hálózaton található gépek MAC címeinek listája."
file.WriteBlankLines(1)
file.WriteLine now
file.WriteBlankLines(1)
Most következik a lényegi rész: a hálózatban található tartományok és munkacsoportok a "WinNT" szolgáltatón keresztül érhetők el. Például "WinNT://Munkacsoport" vagy "WinNT://Microsoft.com". A rendszer gyökere a "WinNT:". Ha csak így hivatkozunk rá és nem adunk meg tartományt vagy munkacsoportot, akkor végignézi a teljes elérhető hálózatot.
Set Domains=GetObject("WinNT:")
Tehát a gyökérből kiindulva megkapjuk az összes tartományt és munkacsoportot és a bennük lévő összes objektumot. Közülük nekünk csak a számítógépekre van szükségünk a felhasználói fiókokra, csoportokra, stb. nem, ezért szűrjük az eredményt ("Filter=Array("Computer")"). Két egymásba ágyazott ciklus használata a legegyszerűbb megoldás: egyik a tartományt, másik azon belül a gépeket kezeli.
For Each Domain in Domains
 Domain.Filter=Array("Computer")
  For Each Computer in Domain
Most már lényegi információk birtokában vagyunk: tudjuk a gépneveket. Mivel egy ciklussal nézzük végig őket és pillanatnyilag a ciklusmagban járunk, írjuk ki a neveket elérési úttal együtt a képernyőre ("ADSPath" tulajdonság).
   Wscript.Echo
   Wscript.Echo "------------------------------------------------" 
   Wscript.Echo Computer.ADSPath
   Wscript.Echo
Tegyük meg ugyanezt a fájlban is.
   file.WriteBlankLines(1)
   file.WriteLine "------------------------------------------------" 
   file.WriteLine Computer.ADSPath
   file.WriteBlankLines(1)
Jelentkezzünk be az adott gépre a Windows Management Instrumentation (WMI) szolgáltatás használatával az aktuális felhasználói nevünkkel és jelszavunkkal ("impersonationLevel = impersonate"). Itt van egy kis buktató, ugyanis ennek érvényesnek kell lennie a távoli gépen és ezen túlmenően, rendszergazdai jogosultsággal kell bírnia. Tipikus ilyen fiók a tartományerdőben a "Vállalati Rendszergazda" ("Enterprise Administrator"). A WMI "winmgmts" interfészén keresztül érjük el a "Win32_ NetworkAdapter" osztályt és hajtsunk végre egy lekérdezést. A kapott eredményt ismét szűrjük meg, mert nekünk csak az "Ethernet 802.3" típusú hálózati adapterekre van szükségünk. Ebbe a kategóriába tartoznak a hálózati kártyák és néhány másik logikai eszköz is. Itt sajnos lesznek fals eredmények (pl.: Packet Scheduler Miniport), ezeket nem tudjuk kiszűrni, mert ugyanolyan elbírálásban részesülnek, mint a fizikailag ott lévő hálózati kártyák és MAC címmel is rendelkeznek.
   Set NetAdapterSet = GetObject ("winmgmts: {impersonationLevel = impersonate}\\" + Computer.Name).ExecQuery ("select * from Win32_NetworkAdapter where AdapterType='Ethernet 802.3'")
Ismét egy ciklussal haladjunk végig az összes visszakapott objektumon, mert lehet, hogy több hálózati kártya is van a gépben. Most jutottunk el a MAC címig (MACAddress tulajdonság), helyezzük el egy változóban (Body) és írjük mögé az operációs rendszer által hozzáfűzött megjegyzést (Description). Utóbbi az eszköz nevére és gyártási típusára utal (pl.: Realtek RTL8139 családú PCI gyors Ethernet NIC). A változót jelenítsük meg a képernyőn és írjuk ki a szövegfájlba is.
    for each NetAdapter in NetAdapterSet
     Body=NetAdapter.MACAddress & "  " & NetAdapter.Description & "   " & chr(13)
     Wscript.Echo Body
     file.write Body
    next
  Next
Next
A ciklusok lezárásával gyakorlatilag végeztünk is. Ami még hátra van: írjuk ki a képernyőre a "Keresés vége." feliratot és ismét a pontos dátumot, illetve zárjuk le a fájlt.
Wscript.Echo
Wscript.Echo "Keresés vége."
Wscript.Echo
Wscript.Echo now
Wscript.Echo
file.Close
Általunk megadott tartomány vagy munkacsoport vizsgálata
Következzék a második változat, ami csak egy általunk megadott tartományt vagy munkacsoportot ellenőriz. A szkript nagy része megegyezik az előzővel, ezért csak a különbségeket tárgyaljuk. Rögtön az elején definiáljuk a "DomainName" változót és írjuk be az ellenőrizendő tartomány vagy munkacsoport nevét.
FileName="c:\MACAddressList.txt"
DomainName="munkacsoport"
Set fso = CreateObject("Scripting.FileSystemObject")
Set file = fso.CreateTextFile(FileName, True)
Wscript.Echo "A hálózaton található gépek MAC címeinek listája."
Wscript.Echo
Wscript.Echo "Keresés indul ...."
Wscript.Echo
Wscript.Echo now
Wscript.Echo
file.WriteBlankLines(1)
file.WriteLine "A hálózaton található gépek MAC címeinek listája."
file.WriteBlankLines(1)
file.WriteLine now
file.WriteBlankLines(1)
A változó tartalmát fűzzük hozzá a "WinNT://" taghoz, így csak ezen belül történik a keresés és nem az összes elérhető helyen. Ebből következően nincs szükség az előbbi egymásba ágyazott ciklusra sem.
Set OnlyDomain = GetObject("WinNT://"+DomainName)
OnlyDomain.Filter=Array("computer")
 For Each Computer in OnlyDomain
   Wscript.Echo
   Wscript.Echo "------------------------------------------------" 
   Wscript.Echo Computer.ADSPath
   Wscript.Echo
   file.WriteBlankLines(1)
   file.WriteLine "------------------------------------------------" 
   file.WriteLine Computer.ADSPath
   file.WriteBlankLines(1)
   Set NetAdapterSet = GetObject ("winmgmts: {impersonationLevel = impersonate}\\"+Computer.Name).ExecQuery("select * from Win32_NetworkAdapter where AdapterType='Ethernet 802.3'")
    for each NetAdapter in NetAdapterSet
     Body=NetAdapter.MACAddress & "  " & NetAdapter.Description & "   " & chr(13)
     Wscript.Echo Body
     file.write Body
    next
Next
Wscript.Echo
Wscript.Echo "Keresés vége."
Wscript.Echo
Wscript.Echo now
Wscript.Echo
file.Close
Megjegyzés: Ha tartományt ellenőrzünk és be vannak kapcsolva a kliens gépek is, akkor egy gép kétszer fog szerepelni a listában. Az ok az, hogy a tartományvezérlő is szolgáltatja az eredményt és maga a kliens is. A problémát úgy lehet elhárítani, hogy a "winmgmts" interfésznél a "Computer.Name" változót behelyettesítjük a tartományvezérlő nevével.