Archiv der Kategorie: Tipps

Kleine Tipps für Zwischendurch: C#-Code testen

Wer lediglich ein paar Zeilen C#-Code testen möchte, muss dafür nicht Visual Studio starten, um dort ein Projekt anlegen zu müssen, wenngleich dies natürlich kein allzu großer Aufwand ist und es mit Visual Studio Code einen Editor gibt, der vielsprachig ist. Es geht auch per PowerShell und dem vielseitigen Add-Type-Cmdlet. Über den MemberDefinition-Parameter wird der C#-Code für eine Membermethode übergeben. Name der Klasse und eventuell auch ein Namespace werden per Parameter festgelegt.

Das folgende Beispiel veranschauhlicht die einfache Vorgehensweise. Eventuell wäre eine statische Methode noch etwas kürzer.

Kleine Tipps für Zwischendurch: Regexe mit Umlauten und anderen Zeichen und die Fehlermeldung „[x-y]-Bereich in umgekehrter Reihenfolge“

Regexe praktisch und alles andere als kompliziert, wenn man sich auf einfache Anwendungsfälle beschränkt. Etwa, das Zerlegen von Zeilen, die aus einem Tag in spitzen Klammern und einem Rest bestehen. Zum Beispiel:

Der Regex soll „slide“ und den Text liefern, der auf die schließende spitze Klammer folgt. Grundsätzlich kein allzu großes Problem, allerdings liefert der folgende Regex die Fehlermeldung [x-y]-Bereich in umgekehrter Reihenfolge:

Die Erklärung ist ebenfalls ganz einfach (vor allem, wenn man es weiß;). Da ich neben vielen Sonderzeichen auch den Bindestrich prüfe, kommt dieser in der Gruppe ebenfalls vor. Er muss dabei aber am Anfang der Gruppe stehen, da er ansonsten als Metazeichen interpretiert wird. Ich hatte ja erwähnt, dass die Fehlermeldung eine ganz einfache Ursache hat.

Der richtige Regex ist daher:

PoshConf Europe 2018 – es gibt noch freie Plätze und wer speakt wie oft und über was

In knapp 3 Wochen startet in Hannover die PowerShell Conference Europe 2018 – vom 17. bis 20. April. Aktuell gibt es noch freie Plätze. Wer sich immer schon einmal mit dem Erfinder der PowerShell Jeffrey Snover oder dem „Brain“ hinter der PowerShell-Sprache Bruce Payette unterhalten möchte (oder falls vom Gespräch auf der letzten Konferenz noch Fragen offen geblieben sind) hat dazu die Gelegenheit. Alle Infos unter http://www.psconf.eu/.

Ich werde dieses Mal nicht dabei sein, aber mich interessiert natürlich trotzdem wer welche Vorträge hält.

Unter http://powershell.beer steht die gesamte Agenda im JSON-Format zur Verfügung.

Der folgende Befehl gibt sie übersichtlich aus:

(Das $ sollte eigentlich nicht erforderlich sein)

Mich interesiert natürlich welche Sprecher die meisten Vorträge halten und natürlich auch welche das sind. Das kleine „Problem“ ist, dass es bei einigen Vorträgen mehrere Sprecher gibt und die Speaker-Eigenschaft daher auch mehrere Namen enthält.

Der folgende Befehl gibt die Sprecher gruppiert nach ihrem Namen und sortiert nach der Anzahl ihrer Vorträge aus.

Das Problem mit dieser Ausgabe ist nur, dass die Sprecher nicht einzeln aufgelistet werden, da es zu einem Vortrag auch mehrere Sprecher geben kann. Die Speaker-Eigenschaft enthält dann mehrere (zwei oder drei) per Komma getrennte Namen.

Wer das Problem selber lösen möchte, sollte jetzt nicht weiterlesen, sondern sich ca. 1 Stunde Zeit nehmen. Es hat mich nicht ganz so viel Zeit gekostet, aber es war schon ein wenig Hin- und Herprobieren erforderlich bis endlich das gewünschte Ergebnis herauskam.

Der Knackpunkt an der Geschichte war, dass ich zuerst auf Invoke-WebRequest umschalten musste, um den JSON-Text direkt zu erhalten (eventuell ist das auch nicht erforderlich) und dann darauf kommen musste, dass die Rückgabe aus einem einzelnen Objekt-Array besteht und nicht aus vielen Objekten – was die Ausgabe suggeriert (darauf bin ich in den letzten Jahren schon einige Male hereingefallen;) – der entscheidende Test ist für mich immer. ob Measure-Object ein Objekt zurückgibt oder mehrere. Ausgehend von einem einzigen Objekt habe ich dessen Content-Eigenschaft expandiert und aus dem resultierenden JSON-Text Objekte gemacht, die per ForEach durchlaufen werden. Da sich hinter der Speaker-Eigenschaft mehrere Namen verbergen können, werden diese per -split-Operator alle einzeln fein säuberlich getrennt und mit der zuvor gespeicherten Title-Eigenschaft zu einem neuen Objekt kombiniert. Dieses besitzt erneut eine Speaker-Eigenschaft mit dem Namen eines Speakers, nach der gruppiert werden kann.

Alles klar? Egal, hier ist ein möglicher Versuch:

Wer ist der Top-Speaker auf der PowerShell Conference Europe 2018?

Netzwerktools und ihre PowerShell-Pendants

Beim Vorbereiten auf einen MOC-Kurs zu Windows 10 ging es auch um die Netzwerkkonfiguration. Es ist erfreulich, dass in den aktuelleren MOC-Unterlagen auch die PowerShell inzwischen erwähnt wird und Gegenstand einiger Demos und Labs ist.

Da auch für mich als PowerShell-Kenner nicht immer auf Anhieb einfällt was z.B. das Pendant zu Nslookup oder ipconfig /flushdns ist, bin ich froh den folgenden Blog-Eintrag gefunden zu haben, in dem der Autor die klassischen Netzwerkkommandos den PowerShell-Befehlen gegenüberstellt:

https://blogs.technet.microsoft.com/josebda/2015/04/18/windows-powershell-equivalents-for-common-networking-commands-ipconfig-ping-nslookup/

Ein wenig kurios ist allerdings, dass dem Autor nicht klar war, dass PowerShell 5.0 zu verwenden nicht automatisch bedeutet, dass Befehle wie Get-NetIPAddress zur Verfügung stehen, da diese Teil des Betriebssystems und nicht der PowerShell sind. Das Ergebnis waren daher auch ein paar „bei mir läuft es nicht, obwohl ich Version 5.0 verwende“-Kommentare.

Was ich noch suche ist ein Pendant zu dem sehr praktischen Portqry.exe, das aber zuerst von einer Microsoft-Seite heruntergeladen werden muss.

Kleine Tipps für Zwischendurch: Alle Dienstnamen pro Svchost-Prozess ausgeben

Vor kurzem habe ich in einem Blog-Eintrag eine PowerShell-Befehlsfolge gefunden, die zu jedem Svchost-Prozess die Namen der Dienste ausgibt, die von diesem Prozess ausgeführt werden. Die Lösung war gut, aber leider sehr umständlich. Vermutlich war der Autor Entwickler und hat ein wenig zu sehr die Entwicklerdenkweise bei der Umsetzung der eigentlich einfachen Aufgabenstellung angewendet. Bei mir hat es auch ein paar Jahre gedauert bis ich mir diese Denkweise bei der PowerShell abgewöhnt hatte.

Mein Vorschlag für eine Unmsetzung sieht wie folgt aus.

Es kann lediglich eine Weile dauern bis eine Ausgabe erscheint.

Kleine Tipps für Zwischendurch: Eine IP-Adresse als Binärzahl ausgeben

Vielleicht gibt es eine einfachere Variante, aber bei der Folgenden gefällt mit die Unmsetzung gut:

So sieht die Adresse als Binärzahl aus:

Chocolatey mit Chocolatey installieren

Laut „Der Postillon“ ist das Henne oder Ei-Problem endlich gelöst: Das Ei war zuerst da.

Ein wenig erinnert mich diese humorvolle Meldung an die Installation der Package Managers Chocolatey per Install-Package und dem Chocolatey-Provider, der aber nachträglich installiert werden muss. Dank des ForceBootstrap-Parameters ist das kein Problem.

Der Pfad von Choco.exe muss allerdings zu Fuß zur Path-Umgebungsvariablen hinzugefügt werden:

Kleine Besonderheiten beim Umgang mit einer OrderedDictionary-Collection und wie man sie löst

Nach mehr als 10 Jahren intensiver PowerShell-Nutzung komme ich immer öfter in Situationen, in die Art und Weise wie PowerShell mit (Daten-) Typen umgeht einiges an Nerven kostet und ich mehr und mehr frage, ob dies bei richtigen Skriptsprachen wie Python oder Ruby auch so ist. Ein „Fehler“ aus heutiger Sicht war sicherlich, dass das PowerShell-Team damals im Jahr 2004 das Typensystem des .NET Framework übernommen hatte, das damals selber noch ganz neu war und erst in der Version 1.1 vorlag. Aus meiner Sicht wäre es besser gewesen, wenn die PowerShell-Entwickler damals ein eigenes Typensystem implementiert und sich nur so wenig wie möglich an das .NET-Typensystem angedockt hätten. Aber diese Option gab es damals nicht.

Die „Besonderheit“, um die es in diesem Blog-Beitrag geht, wird nur auf den zweiten Blick deutlich. Ausgangspunkt ist eine Hashtable, also eine Liste von Schlüssel=Wert-Paaren. Hier ein Beispiel:

Bis zu diesem Punkt ist hoffentlich alles klar. Wir haben eine Hashtable mit drei Schlüssel-Wert-Paaren. Die Schlüssel sind „1000“, „2000“ und „3000“.

Ein Problem mit Hashtables ist, dass es keine Garantie gibt, dass die Elemente in der Folge ausgegeben werden, in der sie hinzugefügt wurden. Um dieses Problem zu umgehen, muss dem @{} nur ein [Ordered] vorangestellt werden.

Jetzt bleibt die Reihenfolge erhalten. Der Grund dafür ist ganz einfach, dass die Hashtable keine Hashtable mehr ist. Die Variable H steht jetzt für ein OrderedDictionary. Das bedeutet unter anderem, dass die Methode ContainsKey für das Abfragen eines Schlüsselwertes nicht mehr vorhanden ist. Ein Skript, dass diese Methode verwendet, muss daher angepasst werden.

Sehr viel schwerer wiegt, dass die Verwendung des Schlüsselwertes nicht mehr funktioniert.

Ein

führt zu keinem Ergebnis mehr. Ein Wert wird über die allgemeine Item()-Methode abgerufen. Aber auch hier gibt es eine „Besonderheit“. Damit der Wert als Schlüssel und nicht als Index erkannt wird, muss der vom Typ Object sein.

Ein

liefert wieder nichts. Ein

liefert den Wert „Wert 1“.

Bei solchen Klimmzügen frage ich immer, wenn ich mit meinen 10+ Jahren PowerShell-Know how ins Schwimmen komme und einiges probieren muss, um zu gewünschten Ergebnis zu kommen (allerdings komplett ohne Internet-Recherche), wie soll es ein typischer PowerShell-Anwender ohne Programmiererfahrung schaffen?

Die Lösung für die ganze „Hashtable-Problematik“ besteht für mich darin, auf das [Ordered] zu verzichten und damit zu leben, dass die Reihenfolge der Werte nicht der Reihenfolge entspricht, in der die Werte zur Hashtable hinzugefügt wurden.

PS: Ein kleiner Trick fiel mir beim Schreiben des letzten Absatzes ein: Per Typenkonvertierung in eine Hashtable verhält sich das OrderedDictionary wieder wie eine Hashtable und es gibt z.B. eine ContainsKey()-Methode.

Damit funktioniert auch der Zugriff über den Schlüssel wieder wie gewohnt:

Praxistipp: RDP per PowerShell aktivieren

Der folgende Tipp ist eher ein „Note to self“, da man ihn „tausendfach“ im Internet findet. Eventuell nicht ganz so übersichtlich wie in meinem Blog.

Auf einemn frisch installierten Windows Server ist der RDP-Zugriff von außen zunächst deaktiviert.

Das folgende kleine PowerShell-Skript aktiviert den RDP-Zugriff. Im Kern geht es darum, ein bzw. zwei Einträge in der Registry zu setzen und eine Firewall-Regel zu aktivieren. Das muss natürlich nicht unbedingt per PowerShell-Remoting umgesetzt werden. Auch für das Setzen der Firewall-Regel gibt es zahlreiche Alternativen.

Die folgende Anleitung ist daher auch nur eine von vielen. Sie funktioniert in dieser Form erst ab Windows Server 2012 aufwärts, da hier PS-Remoting von Anfang an aktiv ist. Benutzername, einbruchsicheres Kennwort und IP-Adresse bitte anpassen.