Mac Auslesen und Rechnername anpassen

  • Guten Abend liebe AutoIt Gemeinde.

    um mir AutoIt beizubringen dachte ich mir ich mache zu erst ein einfaches Script. Und zwar möchte ich das die MAC Adresse der Netzwerkkarte den Rechnernamen ergibt. Also hatte ich folgendes vor. Mittels CMD und ipconfig -all (das ganze wird dann in eine Textdatei gespeichert). Die MAC Adresse auszulesen. Das funktioniert ja auch soweit. Nur hänge ich an folgenden Sachen :

    1. In der Text Datei die MAC Adresse finden.
    2. Die MAC Adresse quasi kopieren und als Rechnername einfügen. (dies löst man wohl am einfachsten wenn man die MAC Adresse dann als Variable speichert.


    Ich will hier keinen vorgekauten Code haben. Nur denkanstöße :)


    Vielen Dank

    Edit :

    [autoit]

    Run("c:\windows\system32\cmd.exe")WinWaitActive("c:\windows\system32\cmd.exe")Send("ipconfig -all >> C:\Mac.txt")Send("{Enter}")Send("exit")Send("{Enter}")
    $datei = FileOpen("C:\Mac.txt", 0);

    [/autoit]

    Einmal editiert, zuletzt von Sonjiru (7. September 2013 um 22:18)

  • Du kannst Sachen in einer Textdatei finden bzw. auslesen indem du die dazugehörigen Funktionen wie

    [autoit]

    FileOpen
    FileRead
    FileClose

    [/autoit]


    benutzt und diese dann mit

    [autoit]

    _StringBetween
    StringRegExp

    [/autoit]

    kombinierst.

    Wie man das als Rechnernamen einfügt, da würde ich entweder die Fenster dafür öffnen (ist aber fehleranfällig) oder eine UDF im Internet suchen mit der man das machen kann,
    bzw. das Object für ObjCreate und die dazugehörigen Funktionen.

    // Um das Fenster zu schließen verwend lieber WinClose, ist sauberer und besser. Außerdem wird man sicherlich -ipconfig -all >> C:\Mac.txt im Run / ShellExecute so unterbringen können, das es schneller geht und du kannst das Run-Fenster verstecken mit @SW_HIDE in den opt_flags.

  • Okay

    Danke schonmal :)

    Wenn ich _StringBetween richtig verstehe. Benötige ich einen Suchstring. Denn ich ja allerdings nicht habe. Da ja jede MAC Adresse anderst ist.

    s_start = Anfang der Suche
    s_end = Ende der Suche

    Hab ich das so weit richtig verstanden?

    Nur was ist der Suchstring? Wie gesagt die MAC ist ja immer verschieden?

  • Zitat

    Hab ich das so weit richtig verstanden?

    Nein,

    der 1. Parameter ist dein Kompletter Text.

    das Ergebnis steht dann zwischen dem Text von Parameter 3 und Parameter 4.

    In der Hilfe ist ein Beispiel:

    [autoit]

    #include <String.au3>
    #include <Array.au3>

    [/autoit][autoit][/autoit][autoit]

    _Main()

    [/autoit][autoit][/autoit][autoit]

    Func _Main()
    Local $aArray1 = _StringBetween('[18][20][3][5][500][60]', '[', ']')
    _ArrayDisplay($aArray1, 'Default Search')
    EndFunc ;==>_Main

    [/autoit]

    Gibt also alles zwischen [ und ] aus.

  • Richtig verstanden.

    Der 1. Arrayeintrag beinhaltet den 1. Fund und der 2. den 2. Fund usw...
    Mit Hilfe von

    [autoit]

    UBound($aArray)

    [/autoit]

    kannst du die Größe eines Arrays rausfinden, aber Achtung. Wenn der Array 10 Einträge groß ist, dann ist der letzte Eintrag 9 deshalb verwendet man in Schleifen bsp.-weise das - 1

    [autoit]


    For $i = 0 To UBound($aArray) - 1
    Next

    [/autoit]

    Der 1. Parameter ist der Text in dem du suchen möchtest und im 2. steht der Text der vor der Mac-Adresse steht und im 3. der danach steht.
    Der letzte und dritte Parameter ist ob die Anfangs- und Endwerte die du festgelegt hast exakt so sein sollen. Wenn der dritte Parameter 1 ist dann gilt:

    Hallo <> haLlo

    Der 2. Parameter wäre also beispielsweise "Physikalische Adresse . . . . . . : " und der dritte ein @CRLF (Carriage Return Line Feed, auch Zeilenumbruch genannt)

    Wenn du das mit _StringBetween angewendet hast und es korrekt ist, dann wirst du vielleicht die Mac-Adressen rausfinden.

  • Ich bekomme nun folgenden Fehler :

    Zitat


    Line 21
    _StringBetween($s_string, $s_Start, $s_End)
    ^ ERROR

    Error : Variable used without being declared.

    Aber ich habe doch schon vorher alles deklariert?

    Code
    Run("c:\windows\system32\cmd.exe")WinWaitActive("c:\windows\system32\cmd.exe")Send("ipconfig -all >> C:\Mac.txt")Send("{Enter}")Send("exit")Send("{Enter}")
    $datei = FileRead("C:\Mac.txt");
    $s_string = $datei$s_Start = 'Physische Adresse . . . . . . :'$s_End = @CRLF
    _StringBetween($s_string, $s_Start, $s_End)
  • Hi,
    setze deinen Code bitte NICHT zwischen die "Code einfügen"-Tags sondern in den "AutoIt-Quellcode" und benutze den "Quellcode"-Reiter statt den "Editor".

    Dir haben die Includes gefehlt, schau mal links bei "Downloads" nach OrganizeIncludes.
    Weiterhin gibt _Stringbetween() sowohl einen Errorcode im Fehlerfall (bspw nichtfinden) aus, als auch ein Ergebnis-Array!

    Spoiler anzeigen
    [autoit]

    #include <String.au3>
    #include <array.au3>

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Run("c:\windows\system32\cmd.exe")
    WinWaitActive("c:\windows\system32\cmd.exe")
    Send("ipconfig -all >> C:\Mac.txt")
    Send("{Enter}")
    Send("exit")
    Send("{Enter}")
    $datei = FileRead("C:\Mac.txt");
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $datei = ' & $datei & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
    $s_string = $datei
    $s_Start = 'Physikalische Adresse . . . . . . :' ;XP32
    $s_End = @CRLF
    $mac=_StringBetween($s_string, $s_Start, $s_End) ;gibt ein Array zurück
    _arraydisplay($mac)

    [/autoit]

    Allerdings zeigt dieses Beispiel deutlich die Stärken von Regular Expressions. Damit werden die Entsprechungen (MAC-Adressen) im Text gefunden ohne von ggf. vom Betriebssystem abhängige Start- und Endstrings abhängig zu sein!

    Weiterhin wäre die Ermittlung der Mac-Adresse über diverse andere Verfahren möglich, bspw. AutoIt-Scriptomatic.

    ciao
    Andy


    "Schlechtes Benehmen halten die Leute doch nur deswegen für eine Art Vorrecht, weil keiner ihnen aufs Maul haut." Klaus Kinski
    "Hint: Write comments after each line. So you can (better) see what your program does and what it not does. And we can see what you're thinking what your program does and we can point to the missunderstandings." A-Jay

    Wie man Fragen richtig stellt... Tutorial: Wie man Script-Fehler findet und beseitigt...X-Y-Problem

    2 Mal editiert, zuletzt von Andy (8. September 2013 um 10:30)

  • Also ich habe es so ähnlich gemacht wie du. Jedoch wird mir nichts ausgegeben. Also habe ich mir gedacht ich muss es eventuell per "MsgBox" machen. Das gibt mir dann eine 0 aus.

    [autoit]

    #include <String.au3>
    #include <array.au3>

    [/autoit][autoit][/autoit][autoit]

    Run("c:\windows\system32\cmd.exe")
    WinWaitActive("c:\windows\system32\cmd.exe")
    Send("ipconfig -all >> C:\Mac.txt")
    Send("{Enter}")
    Send("exit")
    Send("{Enter}")

    [/autoit][autoit][/autoit][autoit]

    $datei = FileRead("C:\Mac.txt");
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $datei = ' & $datei & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
    $s_string = $datei
    $s_Start = 'Physische Adresse . . . . . . :'
    $s_End = @CRLF

    [/autoit][autoit][/autoit][autoit]

    $mac=_StringBetween($s_string, $s_Start, $s_End)

    [/autoit][autoit][/autoit][autoit]

    MsgBox(64,"Array", _ArrayDisplay($mac))

    [/autoit]
    • Offizieller Beitrag

    Hier mal eine alternative MAC-Abfrage:

    Spoiler anzeigen
    [autoit]


    #include <Array.au3>

    [/autoit] [autoit][/autoit] [autoit]

    $aMAC = _GetMACAddress()
    _ArrayDisplay($aMAC)

    [/autoit] [autoit][/autoit] [autoit]

    Func _GetMACAddress()
    Local $sMAC = ''
    Local Const $wbemFlagReturnImmediately = 0x10, $wbemFlagForwardOnly = 0x20
    Local $objWMIService = ObjGet('winmgmts:\\localhost\')
    Local $colItems = $objWMIService.ExecQuery('SELECT * FROM Win32_NetworkAdapter WHERE NetConnectionStatus=2', 'WQL', $wbemFlagReturnImmediately + $wbemFlagForwardOnly)
    If IsObj($colItems) Then
    For $objItem In $colItems
    $sMAC &= $objItem.MACAddress & @CR
    Next
    $sMAC = StringTrimRight($sMAC, 1)
    Return SetError(0, 0, StringSplit($sMAC, @CR))
    Else
    Return SetError(1, 0, 0)
    EndIf
    EndFunc ;==>_GetMACAddress

    [/autoit]
  • Danke,

    das hilft mir aber leider nicht weiter warum er mir die MAC Adresse nicht anzeigt.

    Edit : Okay jetzt weiß ichs.

    Die txt Datei wird nicht mehr erstellt..

    Edit 2 : Gestern wurde die txt datei noch erstellt.

    Heute bekomme ich ein "Zugriff verweigert". Sprich ich muss die Kommandozeile als Administrator starten.

    Kriegt man das auch unter AutoIt hin?

    Einmal editiert, zuletzt von Sonjiru (8. September 2013 um 14:23)

  • Natürlich, setz einfach in die 1. Zeile ein

    [autoit]

    #RequireAdmin

    [/autoit]

    und es sollte funktionieren.


    Jepp hab ich gemacht. (Muss ich halt einmal auf ja klicken :D oder kann man das auch noch automatisieren?, hatte das gestern mal versucht in dem ich 3 Mal Tab Sende + einmal Enter. Ging aber nicht)

    Jetzt wird die txt datei auch wieder erstellt. Das Array allerdings noch nicht ausgegeben.

  • Erstmal würde ich Oscars Lösung bevorzugen, da diese weit weniger umständlich und zuverlässiger ist.

    Zu deiner Methode:

    Es ist grober Unfug ein Kommandozeilenprogramm mit send() zu automatisieren. Alle Commandline Parameter kann man direkt in den run() Aufruf packen. Es ist außerdem ein unsinniger Umweg über eine Textdatei zu gehen, denn man kann die Rückgabe auch direkt in eine Variable schreiben. Dann braucht man auch keine Admin Rechte um eine Datei zu schreiben oder zu lesen.


    Hier mal eine Lösung die "ipconfig /all" sinnvoller anwendet:

    [autoit]


    #include <Constants.au3>
    #include <array.au3>
    #include <string.au3>

    [/autoit][autoit][/autoit][autoit]

    Dim $cmd = 'ipconfig /all'
    Dim $pid = Run(@ComSpec & " /c " & $cmd, "", @SW_HIDE,$STDOUT_CHILD)
    Dim $output = ""

    [/autoit][autoit][/autoit][autoit]

    While ProcessExists($pid)
    $output &= StdoutRead($pid)
    WEnd

    [/autoit][autoit][/autoit][autoit]

    ConsoleWrite($output & @CRLF)

    [/autoit][autoit][/autoit][autoit]

    $aResult = _StringBetween($output," Physikalische Adresse . . . . . . : ",@CRLF)
    _ArrayDisplay($aResult)

    [/autoit]
  • Bei mir matcht das _StringBetween garnicht ?

    Man sollte vl. noch die Beschreibung mit speichern, ich hab 3 Stück drin. Wär vl. mit RegEx einfacher:

    [autoit]

    #include <Constants.au3>
    #include <array.au3>
    #include <string.au3>

    [/autoit][autoit][/autoit][autoit]

    Dim $cmd = 'ipconfig /all'
    Dim $pid = Run(@ComSpec & " /c " & $cmd, "", @SW_HIDE,$STDOUT_CHILD)
    Dim $output = ""

    [/autoit][autoit][/autoit][autoit]

    While ProcessExists($pid)
    $output &= StdoutRead($pid)
    WEnd

    [/autoit][autoit][/autoit][autoit]

    ConsoleWrite($output & @CRLF)

    [/autoit][autoit][/autoit][autoit]

    $aResult = StringRegExp($output,"Beschreibung.*?:\s(.+?)\r\n.+?:\s(.+?)\s",3)
    _ArrayDisplay($aResult)

    [/autoit]
  • Okay alles klar. Werde ich mir merken :)

    Um nun den Rechnernamen anzupassen muss ich wohl folgendes machen :

    Das Array (sind ja mehrere MAC Adressen abgespeichert) in verschiedene Variablen Speichern (richtig?).

    Dann das entsprechende Fenster aufrufen und das die Variable einfügen`?

  • Bei mir matcht das _StringBetween garnicht ?

    Eventuell ist die Anzahl der Leerzeichen zwischen den Windows Versionen unterschiedlich oder aber es wird stattdessen ein @TAB gesetzt. Das meinte ich auch mit unzuverlässig. Oscar fragt einfach WMI danach, das geht mit jeder Windowsversion immer gleich und man muss auch nicht erst irgendwelche Ergebnistexte parsen.

    Um nun den Rechnernamen anzupassen muss ich wohl folgendes machen :

    Das Array (sind ja mehrere MAC Adressen abgespeichert) in verschiedene Variablen Speichern (richtig?).

    Dann das entsprechende Fenster aufrufen und das die Variable einfügen`?


    Nein, warum willst du das Ergebnis in Variablen speichern? Lass es einfach im Array, das ist schließlich eine Sammlung von Variablen Inhalten, die du problemlos einzeln ansprechen kannst. Willst du das erste Ergebnis haben kannst du dieses so abrufen:

    [autoit]


    msgbox(0,"Beispielausgabe",$aResult[0])

    [/autoit]

    Bevor du irgendwelche Rechnernamen änderst solltest du dir aber erstmal darüber klar sein welche der Mac Adressen nun eigentlich die Richtige ist. Ipconfig /all ist womöglich der falsche Ansatz. Über WMI kannst du denke ich besser ermitteln, welcher Adapter nun der primäre ist über den auch externe Verbindungen (Gateway?) möglich sind.

    Irgendwelche Fenster zu automatisieren um den Rechnernamen zu ändern ist im übrigen auch nicht notwendig, man kann das soweit ich mich entsinne über die Registry ändern. Dazu einfach mal google befragen "change hostname" oder "change pc name" sollten jedemenge Ergebnisse liefern.

    Einmal editiert, zuletzt von misterspeed (8. September 2013 um 15:48)

  • Genau, was ist eigentlich das Problem mit der WMI Lösung?

    Hier mal eine angepasste Version um die richtige MAC Adresse zu erhalten. Dafür brauchst du dann allerdings den Namen oder irgendeinen anderen Wert des Adapters.

    [autoit]

    Func GetMACAddress($sKey, $sValue, $sComputer="localhost")
    Local $oWMI, $oItems, $oItem
    $oWMI = ObjGet("winmgmts:\" & $sComputer & "")
    If @error Then Return SetError(1, 0, "")
    $oItems = $oWMI.ExecQuery("SELECT * FROM Win32_NetworkAdapter", "WQL", 0x30)
    If (Not IsObj($oItems)) Then Return SetError(2, 0, "")

    [/autoit][autoit][/autoit][autoit]

    For $oItem In $oItems
    If Execute("$oItem." & $sKey) = $sValue Then
    Return $oItem.MACAddress
    EndIf
    Next
    Return SetError(3, 0, "")
    EndFunc

    [/autoit]

    Beispiel:

    [autoit]

    MsgBox(0, "", GetMACAddress("Name", "Realtek RTL8168B/8111B Family PCI-E Gigabit Ethernet NIC (NDIS 6.20)"))

    [/autoit]
  • Genau, was ist eigentlich das Problem mit der WMI Lösung?

    Es gibt kein Problem an der WMI Lösung. Das ganze war mehr als kleine Aufgabe für mich gedacht um mich mit AutoIt vertraut zu machen. Hab mich durch das Buch gelesen und wollte das ganze nun umsetzen :)

  • Was ich mittlerweile an diesem Topic schade finde, ist das der Ersteller keine Snippets haben wollte sondern nur die Befehle.
    Das verbessern treibt den doch dazu sich mehr damit zu beschäftigen und sich mehr Wissen anzueignen, dazu gehört auch das Recherchieren.

    Mittlerweile sind echt viele Snippets gepostet worden was ich persönlicherweise nicht gut finde, weil man nichts drauß lernt.
    Es wäre besser gewesen (wie an den ersten Antworten zu erkennen ist) nur die Befehle dafür zu nennen und nicht gleich ganze Codes.

    Zitat von Sonjiru

    Ich will hier keinen vorgekauten Code haben. Nur denkanstöße :)