Schlagwort-Archive: PowerShell

adlerweb // BitBastelei 2024-01-23 17:52:41

TIL: mag kein Plaintext. Wenn man Zugangsdaten für den Mailversand hinterlegt, der Zielserver aber nur AUTH PLAIN und nicht auch noch AUTH LOGIN oder NTLM unterstützt, dann geht PowerShell – unabhängig davon, ob man TLS nutzt oder nicht – hin und verwirft die Zugangsdaten. Es wird also trotz Angabe von Nutzername/Passwort einfach versucht die Mail ohne Login zu schicken. Ohne eine Warnung oder Fehlermeldung zu generieren. .

adlerweb // BitBastelei 2023-01-12 22:25:16

Me: Fragt was man heute so für ne holt, wenn am Ende etwas mit und rausfallen soll
Person: *nennt Java-Framework*

Ich sollte wohl noch spezifizieren, dass ich zwar durchaus "dreckige Dinge" wie oder akzeptiere, aber sicher nicht in die -Jauchegrube absteigen werde. Da setz ich ja lieber nen mit -Backend hin als sowas. XD

Windows/GPG/Smartcard – GPG mit Powershell bei SC-Verbindung neu starten

Beim Thema E-Mail-Verschlüsselung ist GPG weit verbreitet. Die Gundfunktionen sind z.B. mit Thunderbird und Enigmail oder gar eine Appliance auch für Einsteiger nutzbar und durch das WoT erstpart man sich die Abhängigkeit von – teils Zweifelhaften – zentralen Zertifizierungsstellen. Ich selbst nutze seit einiger Zeit keinen Softwareschlüssel sondern ein dediziertes HSM (Hardware Security Module) in Form eines YubiKey. Hiermit befindet sich der Key nicht mehr auf dem PC und auch die Verschlüsselung/Signierung läuft in Teilen auf dem Prozessor des YubiKey. Was unter Linux ohne große Änderungen funktioniert macht bei Windows eher wenig Spaß. Zwar ist auch GPG4Win in der Lage mit CryptoCards & Co umzugehen, häufiges Ein- und Ausstecken führt jedoch schnell zu einem hängenden GPG-Agent oder Absturzen der scdaemon.exe (GPG SmartCard Daemon). Einzige Abhilfe: Alle GPG-Prozesse beenden und neu starten. Da Verschlüsselung und Windows ohnehin eher selten zu finden ist sind auch Informationen dazu dünn gesät. Da ich teilweise um das System aus Redmond nicht herum komme und ein Fix in GPG4Win nicht in Sichtweite ist muss also wieder einmal der Holzhammer her: Irgendwie muss beim Einstecken des USB-Gerätes das GPG-System zurückgesetzt werden.

Also frisch ans Werk. Als Sprache soll mal wieder Powershell herhalten – direkt verfügbar, halbwegs systemnah, sollte passen. Über WMI kann man sich auch über ab- und angesteckte Geräte informieren lassen. Leider konnte ich keine Möglichkeit finden weitere Infos wie z.B. Hersteller oder Treiber gleich mit zu erhalten. Da sonst eher wenig Gerätefluktuation zu erwarten ist ziehe ich die „passt scho“-Karte und werde das GPG-System bei jedem neu auftauchenden Gerät einmal zurücksetzen.

#Requires -version 2.0
Register-WmiEvent -Class Win32_DeviceChangeEvent -SourceIdentifier deviceChange
write-host (get-date -format s) " Beginning script..."
do {
    $newEvent = Wait-Event -SourceIdentifier deviceChange
    $eventType = $newEvent.SourceEventArgs.NewEvent.EventType
    $eventTypeName = switch($eventType) {
        1 {"Configuration changed"}
        2 {"Device arrival"}
        3 {"Device removal"}
        4 {"docking"}
    }
    write-host (get-date -format s) " Event detected = " $eventTypeName

    $newEvent.SourceEventArgs.NewEvent | fl

    if ($eventType -eq 2) {
            write-host (get-date -format s) " Starting task in 3 seconds..."
            start-sleep -seconds 3
            taskkill /T /F /IM gpg-agent.exe
            taskkill /T /F /IM scdaemon.exe
            taskkill /T /F /IM kleopatra.exe

            start -FilePath 'C:\Program Files (x86)\GNU\GnuPG\gpg-agent.exe' -ArgumentList '--daemon' -WorkingDirectory 'C:\Program Files (x86)\GNU\GnuPG\' -LoadUserProfile -WindowStyle Minimized
    }
    Remove-Event -SourceIdentifier deviceChange
} while (1-eq1) #Loop until next event
Unregister-Event -SourceIdentifier deviceChange

Das Grundkonstrukt selbst scheint von Andy.L13 zu stammen, die kläglichen versuche von Mass-Storage auf andere USB-Geräte umzustellen stammen von mir. In Zeile 24 kann man für WindowStyle statt Minimized auch Hidden nutzen um das Ganze im Hintergrund laufen zu lassen – ich bevorzuge ein optisches Feedback. Das Script kann passend in Autostart oder als geplanter Task verstaut werden.

Sicher keine saubere Lösung, aber „works for me“.


Edit: Stackoverflow (bzw warriorpostman) liefert

Das folgende Script reagiert nur noch auf den vom YubiKey emulierten Smartcard-Reader. Das Objekt $Event.SourceEventArgs.NewEvent.TargetInstance sieht wie folgt aus – die Informationen für’s Query sollten sich im Gerätemanager finden lassen:

__GENUS                     : 2
__CLASS                     : Win32_PnPEntity
__SUPERCLASS                : CIM_LogicalDevice
__DYNASTY                   : CIM_ManagedSystemElement
__RELPATH                   : Win32_PnPEntity.DeviceID="USB\\VID_1050&PID_0116&MI_02\\6&***&0&0002"
__PROPERTY_COUNT            : 24
__DERIVATION                : {CIM_LogicalDevice, CIM_LogicalElement, CIM_ManagedSystemElement}
__SERVER                    : TESTRECHNER
__NAMESPACE                 : root\CIMV2
__PATH                      : \\TESTRECHNER\root\CIMV2:Win32_PnPEntity.DeviceID="USB\\VID_1050&PID_0116&MI_02\\6&***&0&0002"
Availability                : 
Caption                     : Microsoft Usbccid-Smartcard-Leser (WUDF)
ClassGuid                   : {50dd5230-ba8a-11d1-bf5d-0000f805f530}
CompatibleID                : {USB\Class_0b&SubClass_00&Prot_00, USB\Class_0b&SubClass_00, USB\Class_0b}
ConfigManagerErrorCode      : 0
ConfigManagerUserConfig     : False
CreationClassName           : Win32_PnPEntity
Description                 : Microsoft Usbccid-Smartcard-Leser (WUDF)
DeviceID                    : USB\VID_1050&PID_0116&MI_02\6&***&0&0002
ErrorCleared                : 
ErrorDescription            : 
HardwareID                  : {USB\VID_1050&PID_0116&REV_***&MI_02, USB\VID_1050&PID_0116&MI_02}
InstallDate                 : 
LastErrorCode               : 
Manufacturer                : Microsoft
Name                        : Microsoft Usbccid-Smartcard-Leser (WUDF)
PNPDeviceID                 : USB\VID_1050&PID_0116&MI_02\6&***&0&0002
PowerManagementCapabilities : 
PowerManagementSupported    : 
Service                     : WUDFRd
Status                      : OK
StatusInfo                  : 
SystemCreationClassName     : Win32_ComputerSystem
SystemName                  : TESTRECHNER
PSComputerName              : TESTRECHNER

Ich werde mich am Service WUDFRd (aka Gerät mit Windows SmartCard-Treber) orientieren. Prinzipiell könne man aber auch auf die USB-ID triggern uns so Scripte bauen, welche bei einstecken eines USB-Sticks ein Backup durchführen oder bei verbinden einer unbekannten USB-Tastatur entsprechend reagieren (böse Ente). Das zugehörige Script:

$query =  "Select * FROM __InstanceCreationEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_PnPEntity' AND TargetInstance.Service = 'WUDFRd'"

if( Get-EventSubscriber | Where-Object {$_.SourceIdentifier -eq "YubiHammer"}) {
    Unregister-Event YubiHammer
}

Register-WmiEvent -Query $query -SourceIdentifier YubiHammer -Action{
    $Global:RemoteProcMon=$event 

    start-sleep -seconds 3
    taskkill /T /F /IM gpg-agent.exe
    taskkill /T /F /IM scdaemon.exe
    taskkill /T /F /IM kleopatra.exe

    start -FilePath 'C:\Program Files (x86)\GNU\GnuPG\gpg-agent.exe' -ArgumentList '--daemon' -WorkingDirectory 'C:\Program Files (x86)\GNU\GnuPG\' -LoadUserProfile -WindowStyle Minimized
}

 

Symantec Backup Exec/PowerShell: Bandstatus aus Streamer lesen

Symantec Backup Exec ist als Backupsoftware vor allem in Umgebungen mit vielen physikalischen Systemen immer noch recht weit verbreitet. Über das mitgelieferte PowerShell-Modul lassen sich viele Aufgaben automatisieren und Informationen abrufen. Um die Funktion nutzen zu können muss das Modul in die aktuelle PowerShell-Sitzung importiert werden:

Import-Module 'C:\Program Files\Symantec\Backup Exec\Modules\BEMCLI\BEMCLI'

Als Beispiel lese ich hier den Magazininhalt eines angebundenen Bandroboters aus:

Get-BERoboticLibrarySlot -RoboticLibraryDevice "Wechsler 0001"

Name       SlotNumber IsCleaningSlot  Media
----       ---------- --------------  -----
Schacht 1  1          False           A003L5
Schacht 2  2          False           A005L5
Schacht 3  3          False           A011L5
Schacht 4  4          False           A013L5
Schacht 5  5          False           A024L5
Schacht 6  6          False           A031L5
Schacht 7  7          False           A033L5
Schacht 8  8          False           A048L5
Schacht 9  9          False           A034L5
Schacht 10 10         False           A041L5
Schacht 11 11         False           A049L5
Schacht 12 12         False           A060L5
Schacht 13 13         False           A061L5
Schacht 14 14         False           A062L5
Schacht 15 15         False           A063L5
Schacht 16 16         False
Schacht 17 17         False
Schacht 18 18         False           A064L5
Schacht 19 19         False
Schacht 20 20         False
Schacht 21 21         False
Schacht 22 22         False
Schacht 23 23         False

Ebenso ist es möglich Details der aktuell zugreifbaren Bänder auszulesen:

Get-BEMedia -MediaVault "Online-Bandmedien" -Verbose | Format-List Name,MediaSet,OverwriteProtectedUntilDate,OverwriteProtectedUntilDate -Force

Name                        : A003L5
MediaSet                    : Monatssicherungen (12 Monate schreibschutz)
OverwriteProtectedUntilDate : 01.02.3456 18:39:53
OverwriteProtectedUntilDate : 07.08.9012 18:39:53

In meinem Auftrag wurden diese Informationen verwendet um in regelmäßigen Zeitabständen eine „Idiotensichere“ Mail zu generieren, welche den „Bandwechselmitarbeitern“ mitteile welche Bänder aus dem Roboter entnommen und abtransportiert bzw. welche neuen Bänder in welche Slots eingelegt werden müssen.

Symantec Backup Exec: Bandstatus per PowerShell auslesen

Symantec Backup Exec ist eine in Windows-Umgebungen recht verbreitete Backup-Software. Seit einigen Versionen lassen sich große Teile auch über die „Microsoft-Bash“ PowerShell steuern. Für meinen Zweck wollte ich eine Liste aller im angeschlossenen Bandwechseler eingelegten Bänder und deren Status, so kann ich feststellen welche entnommen werden sollen. Im ersten Schritt muss das PowerShell-Modul geladen werden:

Import-Module 'C:\Program Files\Symantec\Backup Exec\Modules\BEMCLI\BEMCLI'

Nun wird die Liste der Bännder im Wechsler ausgelesen – hier lässt sich feststellen welches Band in welchem Slot des Wechslers verfügbar ist:

Get-BERoboticLibrarySlot -RoboticLibraryDevice "TapeLib01"

Name       SlotNumber IsCleaningSlot  Media
----       ---------- --------------  -----
Schacht 1  1          False           ADLR03L5
Schacht 2  2          False           ADLR05L5
Schacht 3  3          False           ADLR11L5
Schacht 4  4          False           ADLR13L5
Schacht 5  5          False           ADLR24L5
Schacht 6  6          False           ADLR31L5
Schacht 7  7          False           ADLR33L5
Schacht 8  8          False           ADLR48L5
Schacht 9  9          False           ADLR34L5
Schacht 10 10         False           ADLR41L5
Schacht 11 11         False           ADLR49L5
Schacht 12 12         False           ADLR60L5

Zuletzt werden die zugehörigen Banddaten wie z.B. die Dauer des Software-Schreibschutzes gelesen:

Get-BEMedia -MediaVault "Online-Bandmedien" -Verbose | Format-List Name,MediaSet,OverwriteProtectedUntilDate,OverwriteProtectedUntilDate -Force

Name                        : ADLR03L5
MediaSet                    : Monatssicherungen (12 Monate schreibschutz)
OverwriteProtectedUntilDate : 06.03.2016 02:39:53
[…]

Die Daten werden in meinem Fall am Ende einer externen Schnittstelle übergeben, welche die Bandstati sortiert und entsprechende Warnmeldungen zur Entnahme generieren kann.

Logrotate für Windows-Webserver IIS

Seriously, Microsoft? Der in Windows integrierte Webserver IIS kann problemlos vernünftige Log-Dateien erzeugen und besitzt auch eine Funktion diese bei Erreichen einer Zeitspanne oder eines Größenlimits zu schließen und eine neue beginnen. Was leider fehlt: Alte Dateien löschen. Es kommt was kommen musste: Auf einem Produktivserver durfte ich mehr als 100GB an logtechischen Textkauderwelsch finden. Platte voll.

Zwar kann man hier mit der in NTFS verfügbaren Ordnerkompression gegensteuern, eine Dauerlösung ist das aber sicher nicht. Am Ende habe ich auf Basis eines Powershell-Scriptes von Daniel Schroeder aka deadlydog etwas passendes gebastelt um hier Abhilfe zu schaffen. Regelmäßig über die Aufgabenplanung aufgerufen bleibt so der Ordner auf einem erträglichen Maß.

$limit = 15 #Delete Logs after 15 Days
$path = "C:\inetpub\logs\LogFiles\W3SVC1"

# Function to remove all files in the given Path that have not been modified after the given date.
# original written by deadlydog / Daniel Schroeder, http://blog.danskingdom.com/powershell-functions-to-delete-old-files-and-empty-directories/
# Requires Powershell >=2.0
function Remove-FilesNotModifiedAfterDate([parameter(Mandatory)][ValidateScript({Test-Path $_})][string] $Path, [parameter(Mandatory)][DateTime] $DateTime)
{
    Get-ChildItem -Path $Path -Recurse -Force -File | Where-Object { $_.LastWriteTime -lt $DateTime } | Remove-Item
    #Get-ChildItem -Path $Path -Recurse -Force -File | Where-Object { $_.LastWriteTime -lt $DateTime } | Format-List BaseName,LastWriteTime
}

Remove-FilesNotModifiedAfterDate -Path "$path" -DateTime ((Get-Date).AddDays(1-$limit))

Zum Ausführen wird mindestens PowerShell 2.0 benötigt. Ältere Betriebssysteme wie z.B. 2008R2 bringen nur PowerShell 1 mit, hier muss manuell über das Windows Management Framework aktualisiert werden.

Powershell über Aufgabenplanung (oder Batch) starten

Bild: https://adlerweb.info/blog/wp-content/uploads/2015/03/logpurgetask-279×300.pngMit der Powershell hat Microsoft zwar keine angenehm zu verwendende, aber immerhin sehr mächtige Konsole geschaffen, welche es ermöglicht eine Vielzahl an Aufgaben unter Windows über Scripte zu steuern. Ein Wichtiger Punkt bei der Automatisierung ist natürlich auch das zeitgesteuerte Ausführen –  im Windows-Jargon „Aufgabenplanung“ bzw. früher „Geplanter Task“. Leider lassen sich Powershell-Scripte nicht direkt als Programm ausführen, daher muss man etwas tricksen: Als Programmname gibt man „C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe“ ein – ja, 1.0 ist korrekt, auch neuere Powershell-Versionen sind in diesem Ordner zu finden. Der Pfad zum eigentlichen Script wird als Argument „-File“ hinterlegt – Anführungszeichen bei Bedarf natürlich nicht vergessen. Schon können Scripte zeitgesteuert – oder durch einen der anderen möglichen Trigger – gestartet werden. Die „üblichen“ Fallstricke der Aufgabenplanung (Berechtigungen, lauf ohne Anmeldung, etc) sind natürlich wie immer zu beachten.

"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -File "C:\Program Files (x86)\LogPurge\LogPurge.ps1"