Powershell Befehle absetzen und Ergebnis einlesen

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 17 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    Powershell Befehle absetzen und Ergebnis einlesen

    Hallo zusammen,

    wie kann ich folgende Powershell Befehle absetzen und das Ergebnis mir anzeigen lassen bzw. in eine Variable schreiben?

    telnet <IP.Adresse> <Port>
    login <Benutzername> <Passwort>
    port list

    Ergebnis 250 0000 (Am Ende interessieren mich nur die 4 Nullen)

    Das Ganze soll für NETIO 230B IP-Steckdosen sein die 4 Steckdosen haben, die man per Befehle ein und ausschalten kann (Das kann ich bereits). Was mir aber jetzt noch fehlt, ist das Auslesen der aktuellen Stellungen der Steckdosen. Das Ergebnis 0000 liefert hier also alle Steckdosen aus. 1111 = alle an usw.

    Am Ende muss es auch nicht Powershell sein, sondern gerne auch etwas anderes, was man mit VB.Net ansteuern kann.

    Benutze Windows 10 und VS 2022

    Vielen Dank

    Volker
    Hallo zusammen,

    habe gerade mal die KI - Maschine angeschmissen und dort die Lösung für mein Problem gefunden

    Klasse hinzugefügt
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.Net.Sockets
    2. Imports System.IO
    3. Imports System.Text
    4. Public Class TelnetClient
    5. Private client As TcpClient
    6. Private stream As NetworkStream
    7. Private reader As StreamReader
    8. Private writer As StreamWriter
    9. Public Sub Connect(hostname As String, port As Integer)
    10. Try
    11. client = New TcpClient(hostname, port)
    12. stream = client.GetStream()
    13. reader = New StreamReader(stream)
    14. writer = New StreamWriter(stream)
    15. writer.AutoFlush = True
    16. Catch ex As Exception
    17. Console.WriteLine("Fehler beim Verbinden mit dem Telnet-Server: " & ex.Message)
    18. End Try
    19. End Sub
    20. Public Function ExecuteCommand(command As String) As String
    21. If client IsNot Nothing AndAlso client.Connected Then
    22. writer.WriteLine(command)
    23. Return reader.ReadLine()
    24. Else
    25. Return "Keine Verbindung zum Telnet-Server hergestellt."
    26. End If
    27. End Function
    28. Public Sub Disconnect()
    29. If client IsNot Nothing Then
    30. client.Close()
    31. End If
    32. End Sub
    33. End Class​


    und hier der Aufruf

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private Sub btnTelnetConnect_Click(sender As Object, e As EventArgs) Handles btnTelnetConnect.Click
    3. Dim telnet As New TelnetClient()
    4. telnet.Connect("192.168.xxx.xxx", <Port>)
    5. Dim response As String
    6. response = telnet.ExecuteCommand("login <Benutzer> <Passwort")
    7. MsgBox("Antwort vom Server: " & response)
    8. response = telnet.ExecuteCommand("port list")
    9. MsgBox("Antwort vom Server: " & response)
    10. telnet.Disconnect()
    11. End Sub
    12. End Class


    Somit dürfte mein Problem erst einmal gelöst sein.

    Frohe Ostern Euch allen

    Volker
    Du solltest TelnetClient IDisposable implementieren lassen, das ordentlich implementieren, dann kannst Du im Aufruf mit Using arbeiten.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Hallo RodFromGermany,

    vielen Dank für den Hinweis.

    Sieht jetzt so bei mir aus

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class TelnetClient
    2. Implements IDisposable
    3. ...
    4. End Class
    5. Function Status_anzeigen(IPAdresse As String, Port As Integer) As String
    6. Using telnet As New TelnetClient()
    7. telnet.Connect(IPAdresse, Port)
    8. Dim response As String
    9. response = telnet.ExecuteCommand("login admin admin")
    10. ' MsgBox("Antwort vom Server: " & response)
    11. response = telnet.ExecuteCommand("port list")
    12. ' MsgBox("Antwort vom Server: " & response)
    13. telnet.Disconnect()
    14. Return Mid(response, Len(response) - 3, 4)
    15. End Using
    16. End Function


    Funktionieren tut es mit oder ohne Deinen Hinweis.

    Using - Blöcke und IDisposable machen das Ganze intern stabiler und geben die Ressourcen besser frei. Habe ich das so grob richtig verstanden bzw. korrekt umgesetzt?

    Ich muss dazu sagen, dass das Holen der Informationen von all meinen Steckdosen (4 Stück) so schnell und korrekt läuft, das ein Zeitverlust für das Holen der 4 Infos gar nicht spürbar ist.
    Zusätzlich läuft mein Programm eh nicht ständig. Was ich ggf. noch einbauen könnte, wäre ein Timer, der den aktuellen Status in regelmäßigen Abständen überprüft. Aber das ist ja jetzt für mich kein Problem mehr.

    Als ich ChatGPT gefragt habe nach einer Lösung, war ich sehr überrascht, dass die Antwort sofort auf Anhieb funktionierte. Klar, meine Daten müsste ich natürlich noch anpassen, aber das Grundgerüst war sofort lauffähig.
    Natürlich greift hier auch wieder die C&P - Bremse und man sollte das Ergebnis auch soweit prüfen und verstehen, was man sich da so als Lösung vorlegen lässt. Aber manchmal sind es nur ein paar kleine Zeilen, und schon ist das Problem gelöst. Klappt aber auch nicht immer bzw. die Frage sollte schon sehr genau sein.

    Die KI ist doch sehr weit mittlerweile. Mal sehen, was da in den nächsten Jahren noch auf uns zukommt.

    Gruß

    Volker

    Volker Bunge schrieb:

    Visual Basic-Quellcode

    1. Return Mid(response, Len(response) - 3, 4)
    Was ist das für eine Programmiersprache :?:
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @RodFromGermany
    Microsoft.VisualBasic

    Volker Bunge schrieb:

    Using - Blöcke und IDisposable machen das Ganze intern stabiler und geben die Ressourcen besser frei. Habe ich das so grob richtig verstanden bzw. korrekt umgesetzt?
    bzgl. umgesetzt: kann man nicht sagen ohne deine Implementation von IDisposable zu sehen. Wenn die leer wäre, hilft das nix.^^
    bzgl. verstanden: IDisposable macht es dir überhaupt erst möglich Ressourcen sauber und sicher freizugeben. Wenn man es denn korrekt umsetzt.
    Ein Using-Block ruft lediglich die Dispose Methode besser eingebettet auf.






    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „Haudruferzappeltnoch“ ()

    Haudruferzappeltnoch schrieb:

    Microsoft.VisualBasic
    Die Frage ging nicht an Dich, sondern an Volker Bunge.
    Das sind VB-Nicht-Net-Ranz-Befehle, und der Thread-Titel heißt VB.NET.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    Volker Bunge schrieb:

    ...korrekt umgesetzt?

    Vermutlich nicht ansonsten würdest du telnet.Disconnect() nicht benötigen. Aber im Grunde genommen benötigst du IDisposable garnicht. So wie ich dein Vorhaben verstanden habe würde dir ja eine Methode vollkommen ausreichen.

    Alternative ohne IDisposable

    VB.NET-Quellcode

    1. If TryGetStatus(IPAddress.Parse("127.0.0.1"), 8500, PowerOutletStatus) Then
    2. Console.WriteLine(PowerOutletStatus.ToString())
    3. End If

    VB.NET-Quellcode

    1. Public Shared Function TryGetStatus(ByVal ip As IPAddress, ByVal port As Integer, ByRef status As PowerOutletStatus) As Boolean
    2. status = Nothing
    3. Try
    4. Using client As New TcpClient()
    5. client.Connect(New IPEndPoint(ip, port))
    6. If Not client.Connected Then
    7. Return False
    8. End If
    9. Dim sw As New StreamWriter(client.GetStream())
    10. sw.AutoFlush = True
    11. sw.WriteLine("login user password")
    12. Dim sr As New StreamReader(client.GetStream())
    13. Dim response As String = sr.ReadLine()
    14. If response <> "200" Then
    15. Return False ' Login failed
    16. End If
    17. sw.WriteLine("port list")
    18. response = sr.ReadLine()
    19. Dim m As Match = Regex.Match(response, "(\\d)(\\d)(\\d)(\\d)$")
    20. If Not m.Success Then
    21. Return False
    22. End If
    23. status = New PowerOutletStatus(
    24. m.Groups(1).Value = "1",
    25. m.Groups(2).Value = "1",
    26. m.Groups(3).Value = "1",
    27. m.Groups(4).Value = "1"
    28. )
    29. sw.Dispose()
    30. sr.Dispose()
    31. Return True
    32. End Using
    33. Catch ex As Exception
    34. ' Handle exception
    35. End Try
    36. Return False
    37. End Function

    VB.NET-Quellcode

    1. Friend Class PowerOutletStatus
    2. Public Property IsPowerOutletOneEnabled As Boolean
    3. Public Property IsPowerOutletTwoEnabled As Boolean
    4. Public Property IsPowerOutletThreeEnabled As Boolean
    5. Public Property IsPowerOutletFourEnabled As Boolean
    6. Public Sub New()
    7. End Sub
    8. Public Sub New(ByVal isPowerOutletOneEnabled As Boolean, ByVal isPowerOutletTwoEnabled As Boolean, ByVal isPowerOutletThreeEnabled As Boolean, ByVal isPowerOutletFourEnabled As Boolean)
    9. IsPowerOutletOneEnabled = isPowerOutletOneEnabled
    10. IsPowerOutletTwoEnabled = isPowerOutletTwoEnabled
    11. IsPowerOutletThreeEnabled = isPowerOutletThreeEnabled
    12. IsPowerOutletFourEnabled = isPowerOutletFourEnabled
    13. End Sub
    14. Public Overrides Function ToString() As String
    15. Return $"Steckdose 1: {IsPowerOutletOneEnabled}{vbNewLine}Steckdose 2: {IsPowerOutletTwoEnabled}{vbNewLine}Steckdose 3: {IsPowerOutletThreeEnabled}{vbNewLine}Steckdose 4: {IsPowerOutletFourEnabled}"
    16. End Function
    17. End Class

    @Fakiz Nicht korrekt umgesetzt.
    Auf IDisposable zu verzichten ist suboptimal.
    Dein Snippet 2, Zeilen 17 und 25 verlassen die Prozedur mit nicht beräumtem StreamReader und StreamWriter.
    Da sollte zumindest ein Finally-Block hin.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Da bin ich mir nicht sicher oder ich habe es bisher falsch verstanden.

    MSDN schrieb:

    Bei der Deklaration in einer using-Deklaration wird eine lokale Variable am Ende des Bereichs verworfen, in dem sie deklariert wurde


    using-Anweisung: Sicherstellen der ordnungsgemäßen Verwendung verwerfbarer Objekte
    @Fakiz Ausschließlich Deine TcpClient-Variable wird zerstört. Diese hier nicht:

    VB.NET-Quellcode

    1. Dim sw As New StreamWriter(client.GetStream())
    2. ' ...
    3. Dim sr As New StreamReader(client.GetStream())
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Hallo zusammen,

    vielen Dank erst einmal allen für die Antworten

    @RodFromGermany:

    Der Code sollte mir die letzten 4 Stellen des Rückgabewertes zurück liefern. Ich bin immer noch mit dem MID - Befehl unterwegs, daher dieser Ansatz.

    Habe es aber jetzt in Return response.Substring(4, 4) geändert. Mal sehen, ob ich mir diese Schreibweise angewöhnen kann. Ich bemühe mich.

    @Haudruferzappeltnoch:

    Ich habe Implements IDisposable einfach nur da eingesetzt. Der Rest ist so wie in meiner Antwort 2.

    @Fakiz:

    Vielen Dank für das Codebeispiel.

    Gruß
    Volker

    RodFromGermany schrieb:

    Das sind VB-Nicht-Net-Ranz-Befehle, und der Thread-Titel heißt VB.NET
    Dann solltest du das konkreter benennen. So wie ich das verstanden habe, ist Microsoft.VisualBasic ein Namespace in der Programmiersprache VB und wie man sieht in einem VB.NET Projekt verwendbar, also ist der Täg eigentlich auch nicht falsch gesetzt. Aber gut, ich verstehe nun worauf du hinaus wolltest.

    Volker Bunge schrieb:

    Ich habe Implements IDisposable einfach nur da eingesetzt. Der Rest ist so wie in meiner Antwort 2.
    Ah, dann guck nochmal in deine TelnetClient Klasse. Da wurde dir nachdem du das Implements IDisposable eingefügt hast nämlich eine Dispose-Methode generiert und da sind Anpassungen vorzunehmen, sonst bringt das gar nix.
    Len() kannst du auch durch .Length ersetzen, aber wie es aussieht musst du die Länge ja gar nicht kennen, in diesem Fall

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „Haudruferzappeltnoch“ ()

    Haudruferzappeltnoch schrieb:

    So wie ich das verstanden habe, ist Microsoft.VisualBasic ein Namespace in der Programmiersprache VB und wie man sieht in einem VB.NET Projekt verwendbar

    Dieser Namespace richtet sich hauptsächlich an die, die aus der VB6 Welt kommen um ihnen den Einstieg zu VB.NET zu erleichtern. Eventuell werden die VB6 Befehle aus diesem Namespace intern auf die entsprechenden .NET Befehle gemappt. Also bei Len(String) wird intern String.Lenght ausgeführt. Da müsste man mal einen Blick in der Sourcecode von diesem Namespace werfen. Es gibt aber gute Gründe diesen Namespace nicht zu verwenden. Darüber gibt es einige Abhandlungen und auch hier auf vb-paradise gibt es was dazu.
    Mfg -Franky-

    Haudruferzappeltnoch schrieb:

    Kann Mid() vb.net und vb6 sein.
    Wenn solch in C# nicht vorkommt, ist es nicht .NET.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    RodFromGermany schrieb:

    Wenn solch in C# nicht vorkommt, ist es nicht .NET.

    Eher unwahrscheinlich das das jemand macht, aber diesen Namespace kannst auch in C# verwenden und wenn es etwas in C# gibt, das es in VB.NET nicht gibt, ist dann VB.NET kein .NET? ;)
    Mfg -Franky-
    @-Franky- Wie Du siehst, gilt die Umkehrung nicht. ;)
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!