Aufgabe Optimize Start Menu Cache Files entsorgen

Grade hat mich ein Kunde auf einen geplanten Task „Optimize Start Menu Cache Files“ auf seinen Servern aufmerksam gemacht (und hatte keine Lust (mehr) diese (immer wieder) händisch zu löschen).

Geplante Aufgabe „Optimize Start Menu Cache Files“ auf einem Remotedesktop Session Host

Um den Admin des Kunden von dieser nervigen Aufgabe zu befreien haben wir flott ein PowerShell Script geschrieben, welches die „Optimize Start Menu Cache Files“ Aufgaben auf allen Terminal Servern entfernt. Zusätzlich wird das Script auf einer Verwaltungsworkstation periodisch ausgeführt.

foreach ($TServer in (Get-ADComputer -Filter 'Name -like "T*"' -SearchBase "Distinguished Name der OU mit den Servern")) {
    Invoke-Command -ComputerName $TServer.DNSHostName -ScriptBlock { 
        Get-ScheduledTask | where { $_.TaskName -like "Optimize Start Menu Cache Files*" } | Unregister-ScheduledTask -Confirm:$false
    }
}

Eine Alternative zum PowerShell Script is es, einfach das Anpassen des Startbildschirmes für die Server per Gruppenrichtlinie zu deaktivieren. Jetzt noch die evtl. spannende Frage, was macht der Task eigentlich?

Macht der Benutzer Änderungen am Startbildschirm wird diese Aufgabe erstellt und startet sobald die Sitzung des Benutzers im Leerlauf (Idle) ist. Wenn die Aufgabe läuft werden diese Änderungen optimiert. Im Anschluss deaktiviert sich der Task und wird erst wieder aktiviert, sobald der User erneute Ändeurngen am Layout vornimmt.

Das Löschen ist allerdings überwiegend kosmetisch. Wirkliche Performance geht dadurch nicht verloren.

Auf Active Directory Start in Hyper-V VM warten

Den vollständigen Start des Active Directory in einer Hyper-V VM abwarten.

Das gestern vorgestellt Script „RebootAndWaitForServer“ wartet nur „stumpf“ bis die Hyper-V VM gebootet ist und der Prozess „winlogon.exe“ sowie der Dienst „LSM“ läuft. Stellt man jetzt eine Umgebung auf der grünen Wiese bzw. einen PoC oder eine Demoumgebung bereit, benötigt man unter Umständen einen Domänen Controller. Ein DC sollte nicht nur automatisch ausgerollt, sondern auch noch entsprechend konfiguriert werden. Die Konfiguration ist allerdings, logischerweise, erst möglich wenn die Active Directory Dienste gestartet und betriebsbereit sind. Auch hier gab es auf GitHub (WaitFor-ActiveDirectory) bereits eine Funktion, die in verschiedenen Tests nicht zuverlässig lief. In prduktiven Umgebungen sollte es diese Problem natürlich gar nicht erst, da immer mindestens zwei Domain Controller betrieben werden sollten, von denen einer immer erreichbar ist.

Das folgende Script liest die Uptime der Hyper-V VM aus, zieht diese vom aktuellen Datum ab und durchsucht dann die Ereignisanzeige „Active Directory Web Services“ in der VM auf die Instanz-Id „1073743024“.

# WaitForAD
Beispiel für die Variablen:
    [string]$VMName = "SERVER-VM01"
    [System.Management.Automation.PSCredential] $tempCred = new-object -typename System.Management.Automation.PSCredential ("Domain\Admin", (ConvertTo-SecureString P@ssw0rd! -AsPlainText -Force))
 
Oder ggfs. die Variablen abfragen:
    $VMName = Read-Host "Bitte den Namen des virtuellen Computers eingeben"
    $tempCred = Get-Credential
#>
 
function WaitForAD {
    param (
        [Parameter(Mandatory=$true)]
        [String]
        $VMName,
 
        [Parameter(Mandatory=$true)]
        [System.Management.Automation.PSCredential]
        $Credentials
 
    )
    $VM = Get-VM -Name $VMName
    $Uptime = $VM.Uptime.TotalSeconds
    $Date = $(Get-Date).AddSeconds(-($Uptime))
    Write-Host "[$($VMName)]:: Auf Active Directory warten" -ForegroundColor Yellow -NoNewline
    Invoke-Command -VMName $VMName -Credential $Credentials -ArgumentList $Date -ScriptBlock {
        param($Date)
        do {
            do {
                Write-Host "." -ForegroundColor Yellow -NoNewline
                Start-Sleep -Seconds 5
                $AD = get-service ADWS, DNS, KDC, NETLOGON, NTDS
            } until ($AD[0].Status -eq "running" -and $AD[1].Status -eq "running" -and $AD[2].Status -eq "running" -and $AD[3].Status -eq "running" -and $AD[4].Status -eq "running")
            Write-Host "." -ForegroundColor Yellow -NoNewline
            Start-Sleep -Seconds 5
            $Event = Get-EventLog -LogName "Active Directory Web Services" -Source ADWS -After $Date -InstanceId 1073743024 -Newest 1
        } until ($Event.Message -match "Die angegebene Verzeichnisinstanz wird nun von Active Directory-Webdiensten bedient" -or $Event.Message -match "Active Directory Web Services is now servicing the specified directory instance")
    }
    Write-Host " -> Ok!" -ForegroundColor Yellow
}
 
[string]$VMName = "SERVER-VM01"
[System.Management.Automation.PSCredential] $tempCred = new-object -typename System.Management.Automation.PSCredential ("Domain\Administrator", (ConvertTo-SecureString P@ssw0rd! -AsPlainText -Force))
 
WaitForAD $VMName $tempCred

Link zum Download: WaitForAD

Aint nobody got time for dat
Aint nobody got time for dat

Get-ADPrincipalGroupMembership Fehler bei Gruppen mit Slash

Fehler beim Auslesen von Gruppenmitgliedschaften mit Get-ADPrincipalGroupMembership bei Gruppen mit „/“ (Slash) im Namen.

Bei der Erstellung eines PowerShell Scriptes welches basierend auf Gruppenmitgliedschaften verschiedene Exchange-Eigentschaften der User setzen sollte ergab sich ein Problem mit dem CMDLet Get-ADPrincipalGroupMembership:

Get-ADPrincipalGroupMembership Fehler
Get-ADPrincipalGroupMembership Fehler

Get-ADPrincipalGroupMembership: Der Client konnte die Anforderung aufgrund ein es internen Fehler nicht verarbeiten. Wenn Sie weitere Informationen zum Fehler erhalten möchten, aktivieren Sie entweder IncludeExceptionDetailInFaults (entweder über das ServiceBehaviorAttribute oder das <serviceDebug>-Konfigurationsverhalten) für den Client, um die Ausnahmeinformationen zurück an den Server zu senden, oder aktivieren Sie die Ablaufverfolgung gemäß der Microsoft .NET Framework 3.0 SDK-Dokumentation, und prüfen Sie die Serverablaufverfolgungsprotokolle.


Bei xxxxx Zeichen:41
+ if ( (Get-ADPrincipalGroupMembership <<<< $User.DistinguishedName) xxxxx ) {
+ CategoryInfo: NotSpecified: (CN=xxxxx\,…xxxxx,DC=xxxxx :ADPrincipal) [Get-ADPrincipalGroupMembership], ADException
+ FullyQualifiedErrorId: Der Client konnte die Anforderung aufgrund eines internen Fehler nicht verarbeiten. Wenn Sie weitere Informationen zum Fehler erhalten möchten, aktivieren Sie entweder IncludeExceptionDetailInFaults (entweder über das ServiceBehaviorAttribute oder das <serviceDebug>-Konfigurationsverhalten) für den Client, um die Ausnahmeinformationen zurück an den Server zu senden, oder aktivieren Sie die Ablaufverfolgung gemäß der Microsoft .NET Framework 3.0 SDK-Dokumentation, und prüfen Sie die Serverablaufverfolgungsprotokolle.,Microsoft.ActiveDirectory.Management.Commands.GetADPrincipalGroupMembership

PowerShell Ausgabe: Get-ADPrincipalGroupMembership

Dieser Fehler tritt scheinbar auf, sobald der User Mitglied einer Gruppe mit einem „/“ ist. In diesem Fall hieß die Gruppe „02 Lohn / FiBu“. Nach der Umbenennung der Gruppe in „02 Lohn FiBu“ ließ sich das PowerShell Script mit CMDLet Get-ADPrincipalGroupMembership problemlos ausführen.