Categories
PowerShell

Powershell Tail und Head vereint

Ausgabe der letzten und der ersten n-Zeilen in einemBefehl

In Unix/Linux Derivaten sind die Befehle tail und Head oft benutzte Werkzeuge zur Ausgabe der ersten/letzten Zeilen einer Datei oder der Ergebnisse eines Befehls. Direkt kombinieren kann man sie nicht. Hier sind sed/awk und andere Werkzeuge und Lösungen gefordert. Powershell bietet eine sehr effiziente Lösung.

Der erste Ansatz wäre die Ausgabe mit Select -Last und Select -First zu behandeln.

Get-ChildItem somefolder | Select -First 10

Get-ChildItem somefolder | Select -Last 10

Das geht aber nicht in einem Befehl (oder nur mit einer zu schreibenden Funktion). Damit haben wir das gleiche Problem wie mit head und tail in Unix.

Per Get-ChildItem und einem auf die Ausgabe angewendetem Sort Befehl erhält man eine Liste. Diese Ausgabe kann man als Array / Liste von Zeichenketten interpretieren und einzelne Elemente mit einen nachfolgenden Index in eckigen Klammern auswählen.

(Get-Content hashes.csv)[1]

Der “Trick” besteht darin, dass eine solche Powershell Liste auch einen Bereich adressieren kann und dieser Bereich “überlaufen” darf und dann von vorn anfängt. [0..10] gibt die ersten 11 Elemente aus. [10..-1] gibt alle Zeilen ab der 11. Zeile bis zur letzten (-1) aus.

[-10..10] gibt die letzten  10 und die ersten 11 Zeilen  aus (da 0 die erste Zeile ist). Das Ergebnis sieht etwas ungewöhnlich aus, da zuersrt die letzten Zeilen ausgegeben werden:

(gci $folder *jpg |Sort-Object LastWriteTime)[-10..10]

Dier zweite bis zehnte Zeile der Datei und die letzten sind sind in den blauen Rechtecken hervorgehoben, dier erste Zeile der Ausgabeliste ist in der Mitte.

Dieses Verfahren funktioniert für alle Listausgaben, wie Get-ChildIten, Get-Content, Get-Prozess und so weiter.

Categories
Middleware PowerShell

Powershell tail für Textdateien

In Powershell kann die Ausgabe der letzten n Zeilen in grossen Text/Ascii Dateien mit der -tail Option von Get-Content erfolgen:

Get-Content meineRiesigeDatei.csv -tail 25

Seit Powershell v3 bietet Get-Content (oder der zugehörige alias gc) die Option -tail. Leider gibt es keinen tail -f zur fortlaufenden Aktualisierung.

Categories
Middleware PowerShell

Powershell Equivalent zu Unix ‘ls -ltr | tail’

In Powershell kann die Ausgabe der neuesten n-Dateien mit diesem Befehl erfolgen:

  gci | sort LastWriteTime | select -last 60

In diesem Beispiel werden die Dateien im aktuellen Verzeichnis mit gci ausgegeben, nach letztem Schreibzugriff mit sort sortiert (neueste zuletzt) und dann werden nur die letzten 60 per select last 60 ausgegeben.

Categories
PowerShell Windows

PowerShell Drive alias:

PowerShell nutzt das Konzept der Laufwerke (=PowerShell Drives) sehr ausgiebig. So werden die Umgebungsvariablen in env: verwaltet, die Windows Registry aber auch die “normalen” Laufwerke wie “C:”.

Auch Aliasse für Kommandos sind ein PowerShell Drive sind.

Get-ChildItem alias:

Categories
PowerShell Windows

Mehrfache Einträge in großen Konfigurationsdateien oder Protokollen finden (Windows Powershell Lösung)

Im Post Mehrfache Einträge in großen Konfigurationsdateien oder Protokollen finden(Linux/Unix) habe ich gezeigt, wie mehrfach vorkommende Zeilen in Textdateien gefunden und automatisch entfernt werden können.
Windows hat im Zuge der Powershell ein mächtiges Werkzeug, dass dies auch kann. (Seit dem Windows 10 1709 Update kann man natürlich auch einfach die eingebaute bash nehmen….)

Zur Demonstration verwende ich eine Datei duplicates.txt:

Get-Content -Path duplicates.txt

Zeile kommt nur einmal vor
Zeile kommt zweimal vor
Zeile kommt dreimal vor
Zeile kommt zweimal vor
Zeile kommt dreimal vor
Zeile kommt auch nur einmal vor
Zeile kommt dreimal vor

Mehrfache vorkommende identische Zeilen und deren Anzahl findet und zählt man wie mit Group-Object

Get-Content -Path duplicates.txt |Group-Object

Count Name Group
—– —- —–
1 Zeile kommt nur einmal… {Zeile kommt nur einmal vor}
2 Zeile kommt zweimal vor {Zeile kommt zweimal vor, Zeile kommt zweimal vor}
3 Zeile kommt dreimal vor {Zeile kommt dreimal vor, Zeile kommt dreimal vor, Zeile kommt dreimal vor}
1 Zeile kommt auch nur e… {Zeile kommt auch nur einmal vor}

Wenn die Reihenfolge der Zeilen keine Bedeutung hat, ist es einfach, doppelte oder mehrfache Zeilen zu entfernen:

Get-Content -Path duplicates.txt | Sort-object -Unique

Zeile kommt auch nur einmal vor
Zeile kommt dreimal vor
Zeile kommt nur einmal vor
Zeile kommt zweimal vor

oder

Get-Content -Path duplicates.txt | sort-object | Get-Unique

Zeile kommt auch nur einmal vor
Zeile kommt dreimal vor
Zeile kommt nur einmal vor
Zeile kommt zweimal vor

Die Ausgabe aller mehrfach vorkommenden Zeilen kann mit einer einfachen Abfrage geschehen:

Get-Content -Path duplicates.txt | Group | ? { $_.Count -gt 1 } |Select -ExpandProperty Name

Schwieriger wird es, die doppelten Zeilen zu entfernen, wenn die Reihenfolge in der Datei erhalten bleiben soll. Eine Hash Tabelle hilft an dieser Stelle weiter. Die zugrunde liegende Idee ist, für jede Zeile beim ersten Auftreten einen Eintrag in einer Hashtabelle vorzunehmen. Sollte dieser Zeile erneut auftreten, wird sie übersprungen. Das ist der Code:

$hash = $null
$hashTable = @{}
Get-Content .\duplicates.txt | ForEach-Object {
  if ($hashTable.Item($_) -eq $null) {
    $_
    $hashTable.Add($_,”found”)
  }
}

Zeile kommt nur einmal vor
Zeile kommt zweimal vor
Zeile kommt dreimal vor
Zeile kommt auch nur einmal vor

Die ersten beiden Zeilen initialisieren die Tabelle $hashTable. Dann wird für jede neue Zeile ein Eintrag mit dem Wert “found” hinzugefügt (eine 1, ein true oder ähnlich würden es auch tun, Hauptsache ein Eintrag für die Zeile existiert.).

Achtung: Die Ausgabe von $hashTable.Keys gibt die Reihenfolge nicht wie in der Datei aus:

$hashTable.Keys

Zeile kommt dreimal vor
Zeile kommt zweimal vor
Zeile kommt nur einmal vor
Zeile kommt auch nur einmal vor

Sehr hilfreich sind die Erklärungen zu Powershell Hash Tabellen von den Scripting Guys.

Categories
PowerShell Windows

Umgebungsvariablen in der PowerShell

Abfragen von Umgebungsvariablen
Die Anzeige der Umgebungsvariablen war in der “alten” Kommandozwile (cmd) einfach per env durchzuführen.

Die PowerShell bietet einen ähnlich einfachen Aufruf mit Get-ChildItem oder per Alias gci. Zu beachten ist, dass Get-ChildItem einen Pfad erwartet:

Get-ChildItem env:

Eine bestimmte Variable kann mit env: abgefragt werden:

gci env:PATH

Einfacher kann die Variable auch wie jeder Variable in Powershell angezeogt werden.

$Env:Path

Dieser Weg eignet sich besonders gut für Skripte. An dieser Stelle zeigt die PowerShell ihre Stärke. Die Variable kann mit Zeichenkettenoperationen weiter verarbeitet werden, da es ein STRING Objekt ist. Beispielsweise kann -replace zum Bearbeiten von Teilen der Variable verwendet werden:

$Env:myVar=”Toast”
$Env:myVar

Toast

$Env:myVar = $Env:myVar -replace(“oa”,”e”)
Env:myVar

Test
 
Setzen und Ändern von Umgebungsvariablen
Eine Umgebungsvariable kann einfach über eine Zuweisung mit “=” gesetzt oder überschrieben werden:

$env:myVar=”D:\TEMP”
gci env:myVar

Möchte man an eine bestehende Variable etwas anhängen, geschieht dies per +=:

Name Value
—- —–
myVar D:\TEMP

Achtung: Bei der Verknüpfung ist die Syntax selbst korrekt anzugeben. Pfad Variablen (wie $env:PATH) erwarten oft ein “;” als Trennzeichen.

$env:myVar+=”;D:\Cache”
gci env:myVar

Name Value
—- —–
myVar D:\TEMP;D:\Cache

Achtung: Diese Variablen sind nur auf Prozessebene, also in der aktuellen Sitzung gesetzt. Um eine Variable dauerhaft zu setzen, ist auf die Funktionen des .NET Frameworks zurückzugreifen.

[Environment]::SetEnvironmentVariable(“myVar”, “TestWert”, “User”)

Der obige Befehl setzt oder überschreibt die Variable myVar mit dem Wert “TestWert” dauerhaft in der Umgebung des Benutzers. Der dritte Parameter bietet die folgenden Optionen:

  • User (Benutzer-Ebene) – Die Variable wird dauerhaft für diesen Benutzer gesetzt.
  • Machine (Maschinen-Ebene = System) – gültig für alle Benutzer des Systems. Dieser Aufruf erfordert adminsitrative Berechtigungen.
  • Process (Process-Ebene) – Das ist der Standard und entspricht dem Verhalten von $env:myVar

[Environment]::GetEnvironmentVariable(“myVar”, “machine”)

TestWert

Löschen von Umgebungsvariablen

Remove-Item env:myVar
gci env:myVar

gci : Der Pfad “myVar” kann nicht gefunden werden, da er nicht vorhanden ist.
In Zeile:1 Zeichen:1
+ gci env:myVar
+ ~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (myVar:String) [Get-ChildItem], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand

Das Löschen von Variablen auf System-Ebene (“machine”) oder Benutzer-Ebene (“User”) erfolgt mit dem .NET Aufruf:

[Environment]::SetEnvironmentVariable(“myVar”,$null,”Machine”)

Categories
PowerShell Windows

Powershell Test offener Ports auf einem Host

Unter Unix ist der Test offener Ports mit

telnet <hostname> <port>

beispielsweise:

telnet slomka.biz 443

eine übliche Vorgehensweise.

Unter Windows ist ein telnet Client meist nicht installiert. Die Powershell bietet mit dem Kommando Test-NetConnection eine sehr starken Alternative:

Test-NetConnection -ComputerName slomka.biz -Port 443

ComputerName : slomka.biz
RemoteAddress : 81.169.145.68
RemotePort : 443
InterfaceAlias : vEthernet (Virtueller Switch Qualcomm Atheros AR9485WB-EG Wireless Network Adapter)
SourceAddress : 192.168.4.202
TcpTestSucceeded : True

Für Skripte ist der Parameter -InformationLevel quiet sehr nütlich. Sie gibt nur ein True oder False zurück und kann damit in Abfragen einfach ausgewertet werden.

Test-NetConnection -ComputerName slomka.biz -CommonTCPPort http -InformationLevel quiet

True

Categories
PowerShell SAP Windows

PowerShell CmdLets für Microsoft Active Directory

Bei einer SAP Installation unter Windows sind bestimmte Gruppen und Benutzerzuordnungen im Active Directory Voraussetzung (siehe SAP Installation Guide).

Ein SAP Administrator sollte nicht Mitglied der Windows AD Administratoren Gruppe sein. Bei einer SAP Installation muss er aber sicherstellen, dass die vorausgesetzten Gruppen und Benutzer angelegt wurden.

Ein Beispiel: Bei der Installation des SAP Systems HSL sind die globale Gruppe SAP_HSL_GlobalAdmin und die Benutzer hsladm und SAPServiceHSL erforderlich. Die Benutzer müssen der Gruppe zugeordnet sein. Mit folgenden Abfragen kann dies überprüft werden:
Abfrage des Benutzers

Get-ADUser -properties MemberOf SAPServiceHSL

DistinguishedName :CN=SAPServiceHSL,CN=Users,DC=slomka,DC=biz
GivenName :
MemberOf : {}
Name : SAPServiceRPR
ObjectClass : user
ObjectGUID : 11111111-11a1-1111-a1111-aaa111aaa111
SamAccountName : sapservicerpr
SID : S-1-1-11-111111111-11111111111-111111111-11111
Surname : SAPServiceHSL
UserPrincipalName : sapservicehsl@slomka.biz

Abfrage der Mitglieder einer Gruppe

Get-ADGroupMember SAP_HSL_globaladmin

distinguishedName : CN=HSLADM,CN=Users,DC=slomka,DC=biz
name : HSLADM
objectClass : user
objectGUID : 11aaa1aa-a111-1a11-a111-1111aa111a1
SamAccountName : rpradm
SID : S-1-1-11-111111111-11111111111-111111111-11111

distinguishedName : CN=SAPServiceHSL,CN=Users,DC=slomka,DC=biz
name : SAPServiceHSL
objectClass : user
objectGUID : 11aaa1aa-a111-1a11-a111-1111aa111a1
SamAccountName : sapservicehsl
SID : S-1-1-11-111111111-11111111111-111111111-11111

Categories
PowerShell SAP Windows

Passwort eines Windows Service Accounts per PowerShell zurücksetzen

Um das Passwort eines Windows Service Benutzer zu ändern, kann in der PowerShell das CmdLet Reset-ADServiceAccountPassword verwendet werden.

Reset-ADServiceAccountPassword -Identity SAPServiceHSL

Das Kommando funktioniert nur bei standalone manage service accounts, nicht bei group managed service accounts (gMSA).

Categories
PowerShell

Auflösung von Variablen in der PowerShell gezielt steuern

In diesem Tipp geht es um das Maskieren von Variablen und deren Auflösung in der PowerShell. Wie kann ich also zum Beispiel den Text $VAR ausgeben, ohne dass der Inhalt der Variable $VAR angezeigt wird?
(Unter Auflösung einer Varibale wird die Anzeige des Inhaltes/Wertes der Variablen verstanden.)

Beispiel 1

$a = "Das ist die Variable a"
$b = "DAS IST b""$a und $b werden aufgelöst"

Das ist die Variable a und DAS IST b werden aufgelöst

Beispiel 2
In Literalstrings (umgeben mit einfachen Hochkomma) sollen Variablen nicht aufgelöst werden.

'$a und $b werden nicht aufgelöst'

$a und $b werden nicht aufgelöst

"`$a wird nicht aufgelöst, $b schon"

$a wird nicht aufgelöst, Das ist b schon

Beispiel 3

"`$a hat den Inhalt: $a"

$a hat den Inhalt: Das ist die Variable a
Der Trick im letzten Beispiel ist der Back-Tick ` (neben ß, mit SHIFT)