Powershell Logfile Archiver

Leider gibt es heutzutage immer noch massenhaft Anwendungen, welche frisch fröhlich ihre Logfiles auf die Festplatte schreiben als gäbe es kein Morgen mehr. Dies hat zur Folge, dass der Platz auf der Festplatte immer weiter schrumpft und im ungünstigsten Fall, wenn es sich um die Systemplatte handelt, der ganze Server nicht mehr starten kann.

Um dem entgegen zu wirken habe ich ein kleines Script erstellt, welches alle Dateien welche älter als X Tage sind in komprimierten Archiven nach Monat ablegt. Die Monate wiederum in Ordner als Jahr abgelegt. Weiter löscht das Script alle Archiv Dateien, welcher älter als Y Tage sind. Somit haben wir die Logfiles welche jünger als X Tage sind im Klartext, alle die älter als X Tage sind komprimiert in Monats Archiven und alles was älter als Y Tage ist gar nicht mehr.

<#
.SYNOPSIS
  Moves Logfiles to archive packages for amount of time

.DESCRIPTION
  Moves logfiles older than specified days to monthly archives. Deletes archives older than archive retention days.

.PARAMETER Path
  Path to the folder where the logfiles are

.PARAMETER ArchivesRoot
  Path where the archives shall be stored. Defaults to $Path\Archives

.PARAMETER RetentionDays
  Number of days to skip archiving for. Defaults to 30

.PARAMETER RetentionArchiveDays
  Number of days which trigger an archive to be deleted if older. Defaults to 365

.INPUTS
  Path of the logfile folder

.OUTPUTS
  Reorganized Logfiles folder

.NOTES
  Author: Philipp R
  Version: 1.0
  Last Modify: 01.04.2020

.EXAMPLE
  .\LogArchiver.ps1 -Path C:\my\logs
#>
#Requires -Version 4

Param(
    [Parameter(Mandatory=$true, ValueFromPipeline=$true)][string]$Path,
    [string]$ArchivesRoot = "$Path\Archives",
    [int]$RetentionDays = 30,
    [int]$RetentionArchiveDays = 365
)

Begin{
    if(-not(Test-Path $Path)){
        Write-Host -ForegroundColor Red "Path not found, $Path"
        return
    }
}

Process{
    $CompressionCandidates = Get-ChildItem $Path -File | Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-$RetentionDays)}
    try{
        $CompressionCandidates | 
        Group-Object -Property {$_.LastWriteTime.Year} | ForEach-Object {
            $Year = $_.Name
            $_.Group | Group-Object -Property {$_.LastWriteTime.Month} | ForEach-Object {
                $TargetArchive = "$ArchivesRoot\$Year\$($_.Name).zip"
                # Create the year folder
                $null = New-Item -ItemType Directory -Path (Split-Path $TargetArchive) -ErrorAction SilentlyContinue
                # if archive exists add it otherwise create new
                $_.Group | Compress-Archive -Update:(Test-Path $TargetArchive) -DestinationPath $TargetArchive
            }
        }
        # Only remove files if we successfully archived them
        $CompressionCandidates | Select-Object -ExpandProperty FullName |  Remove-Item  -Force
    }
    catch {
        Write-Host -ForegroundColor Red "Something strange happened"
        $_.Exception
    }

    # Remove old archives
    $DueDate = (Get-Date).AddDays(-$RetentionArchiveDays)
    Get-ChildItem $ArchivesRoot | Where-Object { [int]($_.Name) -lt [int]($DueDate.Year) } | Select-Object -ExpandProperty FullName | Remove-Item -Recurse -Force
    Get-ChildItem "$ArchivesRoot\$($DueDate.Year)" | Where-Object { [int]($_.Name.Split(".")[0]) -lt $DueDate.Month } | Select-Object -ExpandProperty FullName | Remove-Item -Recurse -Force
}

End{

}

ADFS ID8025 Fehler

Die Konfiguration eines neuen ADFS Server ist mit dem nicht sehr aussagekräftigen Fehler ID8025 fehlgeschlagen. Die naheliegendste Ursache dafür scheint mir mit dem SSL Zertifikate zusammen zu hängen, da alle anderen Einstellungen Standart sind. Leider liefert mir weder eine Suche nach ID8025 noch das Handbuch von Microsoft einen Hinweis auf den Fehler. Also setzte ich beim Erstellen des Zertifikates an. Da es sich um meine HomeLab Installtion handelt, löse ich das Zertifikat von der Lets Encrypt CA mit dem Kommandozeilen Tool lego.

https://github.com/go-acme/lego

Mehr oder weniger zufällig fällt mir beim Anschauen der Hilfe für lego auf, dass beim erzeugen des privaten Schlüssel ein Algorithmus basierend auf elliptischen Kurven verwendet wird. Sobald ich das Zertifikat mit dem Argument -k rsa4096 erstelle lässt es sich ohne Probleme für ADFS verwenden.

Windows Passwort des lokalen Administrators ändern ohne Rechte

Das nachfolgende Szenario ist schon länger bekannt, jedoch möchte ich damit wieder einmal darauf hinweisen, wie wichtig es ist eine Festplatten Verschlüsselung einzusetzen.
Wenn eine Windows Installation unverschlüsselt ist, kann relativ einfach eine Shell mit den höchsten Rechten (NT AUTHORITY\System) gestartet werden. Damit lässt sich absolut alles mit einem System machen, wie z.B das Passwort des lokalen Adminstrators ändern um sich damit anzumelden.
Um diese Shell zu starten bedienen wir uns dem Windows Feature Eingabehilfen auf dem Login Bildschirm, welches immer als NT AUTHORITY\System Benutzer gestartet wird.
Es gibt verschiedene Varianten an diese Shell zu gelangen:

Variante 1: Programm kopieren (einfachere)

  1. Zielsystem mit WinPE oder Linux (mit NTFS Lese/Schreibberechtigungen) starten
  2. C:\Windows\System32\Utilman.exe nach Utilman.exe.bak umbenennen
  3. C:\Windows\System32\cmd.exe kopieren nach C:\Windows\System32\Utilman.exe
  4. Neustarten und die Eingabehilfen starten
  5. net user administrator <neuesPasswort>

winpe_utilman
windows_login_utilman

Variante 2: Image File Exection Options (komplexere)

  1. Zielsystem mit WinPE oder Linux (mit NTFS Lese/Schreibberechtigungen) starten
  2. Registry Hive C:\Windows\System32\config\SOFTWARE laden
  3. Zum Schlüssel (vom Zielsystem) wechseln KEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options
  4. Neuen Schlüssel erstellen mit Namen utilman.exe
  5. In diesem Schlüssel einen String Value erstellen Name = debugger Value = cmd.exe
  6. Neustarten und die Eingabehilfen starten
  7. net user administrator <neuesPasswort>

VB.net AES Encryption Modul

Benötigt: .Net Framework 3.5 (AES Cryptosystem)

Test Programm

Imports Encrpyt.CryptoAES.Crypto
Module Module1
    Sub Main()
        Dim enc = New Crypto
        enc.key = "x4!UnUfugeyaprachuT8DesAst55ew!2"
        Dim cstring As String = enc.EncryptString("I like encryption!")
        Console.WriteLine("Encrypted: " & cstring)
        Console.WriteLine("Decrypted: " & enc.DecryptString(cstring))
        Dim k = Console.ReadKey()
    End Sub
End Module

Encryption Modul

Imports System.Security.Cryptography
Imports System.IO
Imports System.Text
Module CryptoAES
    Public Class Crypto
        Private _key As String
        Public Property key() As String
            Get
                Return _key
            End Get
            Set(ByVal value As String)
                _key = value
            End Set
        End Property
        Public Sub EncryptFile(ByVal sInputFilename As String, _
                       ByVal sOutputFilename As String, _
                       ByVal sKey As String)
            Dim fsInput As New FileStream(sInputFilename, _
                                        FileMode.Open, FileAccess.Read)
            Dim fsEncrypted As New FileStream(sOutputFilename, _
                                        FileMode.Create, FileAccess.Write)
            Dim AES As New AesCryptoServiceProvider()
            'Set secret key for AES algorithm.
            'A 256-bit key and an IV are required for this provider.
            AES.KeySize = 256
            AES.Key = ASCIIEncoding.ASCII.GetBytes(sKey)
            'Set the initialization vector.
            AES.IV = ASCIIEncoding.ASCII.GetBytes(Left(sKey, 16))
            'Create the AES encryptor from this instance.
            Dim aesencrypt As ICryptoTransform = AES.CreateEncryptor()
            'Create the crypto stream that transforms the file stream by using AES encryption.
            Dim cryptostream As New CryptoStream(fsEncrypted, _
                                                aesencrypt, _
                                                CryptoStreamMode.Write)
            'Read the file text to the byte array.
            Dim bytearrayinput(CInt(fsInput.Length - 1)) As Byte
            fsInput.Read(bytearrayinput, 0, bytearrayinput.Length)
            'Write out the AES encrypted file.
            cryptostream.Write(bytearrayinput, 0, bytearrayinput.Length)
            cryptostream.Close()
            fsInput.Close()
        End Sub
        Public Sub DecryptFile(ByVal sInputFilename As String, _
            ByVal sOutputFilename As String, _
            ByVal sKey As String)
            Dim AES As New AesCryptoServiceProvider()
            'A 64-bit key and an IV are required for this provider.
            'Set the secret key for the AES algorithm.
            AES.Key() = ASCIIEncoding.ASCII.GetBytes(sKey)
            'Set the initialization vector.
            AES.IV = ASCIIEncoding.ASCII.GetBytes(sKey)
            'Create the file stream to read the encrypted file back.
            Dim fsread As New FileStream(sInputFilename, FileMode.Open, FileAccess.Read)
            'Create the AES decryptor from the AES instance.
            Dim aesdecrypt As ICryptoTransform = AES.CreateDecryptor()
            'Create the crypto stream set to read and to do a AES decryption transform on incoming bytes.
            Dim cryptostreamDecr As New CryptoStream(fsread, aesdecrypt, CryptoStreamMode.Read)
            'Print out the contents of the decrypted file.
            Dim fsDecrypted As New StreamWriter(sOutputFilename)
            fsDecrypted.Write(New StreamReader(cryptostreamDecr).ReadToEnd)
            fsDecrypted.Flush()
            fsDecrypted.Close()
            fsread.Close()
        End Sub
        Public Function EncryptString(ByVal sString As String) As String
            'Initialize AES Crypto Provider
            Dim AES As New AesCryptoServiceProvider()
            'Set KeySize to 256 Bit
            AES.KeySize = 256
            'Set the initialization vector and the encryption key
            AES.IV = ASCIIEncoding.ASCII.GetBytes(Left(_key, 16))
            AES.Key = ASCIIEncoding.ASCII.GetBytes(_key)
            'Create the AES Encryptor
            Dim aesencrypt As ICryptoTransform = AES.CreateEncryptor
            'Convert plain text to bytes
            Dim plaintext() As Byte = System.Text.Encoding.Unicode.GetBytes(sString)
            'Create the Stream
            Dim ms As New System.IO.MemoryStream
            'Create the encoder
            Dim encStream As New CryptoStream(ms, aesencrypt, CryptoStreamMode.Write)
            encStream.Write(plaintext, 0, plaintext.Length)
            encStream.FlushFinalBlock()
            Return Convert.ToBase64String(ms.ToArray)
        End Function
        Public Function DecryptString(ByVal sString As String) As String
            'Initialize AES Crypto Provider
            Dim AES As New AesCryptoServiceProvider()
            'Set KeySize to 256 Bit
            AES.KeySize = 256
            'Set the initialization vector and the encryption key
            AES.IV = ASCIIEncoding.ASCII.GetBytes(Left(_key, 16))
            AES.Key = ASCIIEncoding.ASCII.GetBytes(_key)
            'Create the AES Decryptor
            Dim aesdecrypt As ICryptoTransform = AES.CreateDecryptor
            'Convert plain text to bytes
            Dim encryptedstring() As Byte = Convert.FromBase64String(sString)
            'Create the Stream
            Dim ms As New System.IO.MemoryStream
            'Create the decoder
            Dim decStream As New CryptoStream(ms, aesdecrypt, CryptoStreamMode.Write)
            decStream.Write(encryptedstring, 0, encryptedstring.Length)
            decStream.FlushFinalBlock()
            Return System.Text.Encoding.Unicode.GetString(ms.ToArray)
        End Function
    End Class
End Module

Java Client Cache auf Terminal Server

Java Client Cache auf Terminal Server

Problembeschreibung:

Wenn die Profilgrössenbeschränkung von Benutzern auf einem Terminal Server auf einen niedrigen Wert (z.B 30 MB) eingestellt ist, kann es vorkommen, dass das Profil schnell überfüllt ist. Der Grund dafür ist der Java Cache der für jeden Benutzer im Roaming Profil gespeichert wird.

Lösung (zentraler Java Cache für alle Benutzer)

  1. Schreib Rechte für %SystemDrive%\Windows\Temp für alle Domain Users erteilen
  2. Den Ordner %SystemDrive%\Windows\Sun\Java\Deployment erstellt falls nicht vorhanden
  3. %UserProfile%\Application Data\Sun\Java\Deployment bei allen Usern löschen (wird neu erstellt beim ersten Besuch eine Java Seite)
  4. In diesem Ordner 2 Dateien anlegen
    deployment.config (Evtl. Laufwerkbuchstabe ändern

    deployment.system.config=file\:C\:\\WINDOWS\\Sun\\Java\\Deployment\\deployment.properties
    deployment.system.config.mandatory=true
    

    deployment.properties (Evtl. Laufwerkbuchstabe ändern und Java Version!)

    #
    deployment.cache.max.size=1000m
    deployment.cache.max.size.locked
    #
    deployment.javaws.splash.cache=C\:\\WINDOWS\\TEMP\\Java\\javaws\\cache\\splashes\\splash.xml
    deployment.javaws.splash.cache.locked
    #
    deployment.javaws.cachedir=C\:\\WINDOWS\\TEMP\\JAVA\\javaws\\cache
    deployment.javaws.cachedir.locked
    #
    deployment.javaws.cache.dir=C\:\\WINDOWS\\TEMP\\JAVA\\javaws\\cache
    deployment.javaws.cache.dir.locked
    #
    deployment.user.cachedir=C\:\\WINDOWS\\Temp\\JAVA\\cache
    deployment.user.cachedir.locked
    #
    deployment.user.tmp=C\:\\WINDOWS\\Temp\\JAVA\\tmp
    deployment.user.tmp.locked
    #
    deployment.system.cachedir=C\:\\WINDOWS\\Temp\\JAVA\\cache
    deployment.system.cachedir.locked
    #
    #deployment.browser.vm.mozilla=false
    #deployment.browser.vm.mozilla.locked
    #
    #deployment.browser.vm.iexplorer=false
    #deployment.browser.vm.iexplorer.locked
    #
    deployment.javaws.shortcut=NEVER
    deployment.javaws.shortcut.locked
    #
    deployment.proxy.type=3
    deployment.proxy.type.locked
    #
    deployment.javaws.autodownload=NEVER
    deployment.javaws.autodownload.locked
    #
    deployment.javapi.jre.1.6.0_18.args=-Xmx192M
    

tail für Windows

Wer hatte nicht auch schon das Bedürfnis ein Logfile “live” anzeigen zu lassen um es nicht ständig neu zu öffnen. Entwickler und diejenigen, die sich mit WSUS beschäftigen wissen wovon ich spreche.
Um den Windows Server Update Services zu troubleshooten muss ständig das Logfile in C:\Windows\WindowsUpdate.log neu geöffnet werden um Errormeldungen anzuschauen.
Unter Linux gibt es ein tolles Tool, mitdem man Textfiles live anschauen kann, bis Ctrl+C gedrückt wird. Dieses Tool heisst tail mit dem Switch -f werden neue Einträge im File kontinuierlich angezeigt.
Wäre doch auch gut für Windows? Gibt es!
GUI
Tail for Win32
mTail
WinTail
Command Line
Windows Server 2003 Resource Kit Tools (getestet auf Server 2008 und Windows 7!)
C:\Users\pri>tail /?
usage: TAIL [switches] [filename]*
switches: [-?] display this message
[-n] display last n lines of each file (default 10)
[-f filename] keep checking filename for new lines

Error parsing the server "ServerName" "Clients.xml" file.

Windows 7 und der vSphere Infrastructure Client

Ich arbeite seit kurzem mit Windows 7 und habe sehr rasch festgestellt, dass der vSphere Client überhaubt nicht funktioniert. Das Problem ist bei VMware bekannt und sollte mit dem Endkunden Release von Windows 7 behoben sein. Ich verwende das RC; evtl. ist dieses Problem schon bei dem RTM (Release to Manufacturers) gelöst.
fehler1fehler2
Es gibt allerdings einen Workaround für dieses Problem:
1. Obtain a copy of %SystemRoot%\Microsoft.NET\Framework\v2.0.50727\System.dll from a non Windows 7 machine that has .NET 3.5 SP1 installed.
2. Create a folder in the Windows 7 machine where the vSphere client is installed and copy the file from step 1 into this folder. For example, create the folder under the vSphere client launcher installation directory (+%ProgramFiles%\VMware\Infrastructure\Virtual Infrastructure Client\Launcher\Lib+).
3. In the vSphere client launcher directory, open the VpxClient.exe.config file in a text editor and add a element and a element as shown below. Save the file.
<?xml version=”1.0″ encoding=”utf-8″?>
<configuration>

<runtime>
<developmentMode developerInstallation=”true”/>
</runtime>
</configuration>
3. Create a batch file (e.g. *VpxClient.cmd*) in a suitable location. In this file add a command to set the DEVPATH environment variable to the folder where you copied the System.dll assembly in step 2 and a second command to launch the vSphere client. Save the file. For example,
SET DEVPATH=%ProgramFiles%\VMware\Infrastructure\Virtual Infrastructure Client\Launcher\Lib
“%ProgramFiles%\VMware\Infrastructure\Virtual Infrastructure Client\Launcher\VpxClient.exe”
4. (Optional) Replace the shortcut on the start menu to point to the batch file created in the previous step. Change the shortcut properties to run minimized so that the command window is not shown.
You can now use the VpxClient.cmd (or the shortcut) to launch the vSphere client in Windows 7.
Note that this workaround bypasses the normal .NET Framework loading mechanism so that assembly versions in the DEVPATH folder are no longer checked. Handle with care
Trackback: VMware Thread

RDP bricht ohne Timeout sofort ab

Ich hatte kürzlich das Problem, dass ich mich nicht mehr via RDP auf meinen PC zuhause verbinden konnte. Nach stundenlangem herumgebastle hatte ich dann endlich die Lösung gefunden.

Das Problem:

Die Ursache war der neuste Treiber von NVIDIA (6.14.11.7519) und XP SP3, welche scheinbar nicht kompatibel sind.
Im Event Viewer erscheint der Event 26 Application Popup: Application popup: : \SystemRoot\System32\RDPDD.dll failed to load

Die Lösung:

Manuell

In der Registry muss ein zusätzliche Eintrag gemacht werden, der die Session Image Size erhöht
HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management
Neuen DWORD Wert: SessionImageSize mit Wert dword:00000020 (Hex für 32)

oder Reg Datei importieren

SessionImageSize.reg (Rechtsklick -> Speichern unter)

Test "Application Installation" without Full OS Deploying on Windows Deployment System

As i set up a Windows Deployment Server in our Company and wanted to test the unattended Installation of Applications i had a big annoying Problem: Everytime i wanted to test a new unattended Setup i had to install the whole Operating System and wait for Apps installation to see if they work. Or if i simply changed one parameter in an Application and wanted to test this i had to wait about half an hour for OS Installation.
Without searching alot i found a valuable Resolution for this very time-consuming Problem:

  1. In Deployment Workbench (BDD2007) create a new Build (i.e. ApplicationsOnly)
  2. Right Click on the new Build select Properties and change to Task Sequence
  3. Now delete every Group and Step exept State Restore, Gather local only and Install Applications
  4. Click on State Restore and go to Options. Remove the Condition Line marked in Screenshot.

     

  5. On Client Computer type in cmd: cscript \\<WDS-Server>\<DistributionFolder>\scripts\LiteTouch.vbs
  6. As migration type choose Refresh this computer
  7. Then you have to enter some information (ComputerName, Domain etc.) You can leave domain blank and Join a workgroup, because we just install applications
  8. On next Screen Do not back up the existing computer
  9. Then choose the Build you created before (i.e ApplicationsOnly)
  10. On next Page you can select Applications you want to test.
  11. Then you have to enter some credentials to connect the Share on which the Applications lie
  12. Click Begin and watch the Errors of the Applications 😉

Total Cost of this Procedure depending on Applications (10 Min) VS. Deployment of whole OS and Apps (30-45 Min)
Note:
I’ve seen the phenomen, that some applications work on the ApplicationsOnly build and not on the Full XP SP2 build and vice-versa.
e.g MS Office 2003: In ApplicationsOnly build you have to call it via pro11.msi TRANSFORMS=*.mst and in XP SP2 build setup.exe TRANSFORMS=*.mst