K.inc Tec Blog

Mein kleines EDV Logbuch

Category: Windows (Page 2 of 7)

Programme mit System-Konto starten

Auf manche Dateien kann man nur mit dem Systemkonto zugreifen. Das gilt besonders auch für Registry-Einträge. Diese sind auch für Administratoren manchmal nicht lesbar. Hierfür nutzen wir das Tool PsExec von SysInternals.

Programm interaktiv (-i) als System (-s) starten:

psexec -i -s c:\windows\regedit.exe

Genauso kann man aber auch z.B. die Powershell mit dem System-Konto starten:

psexec -i -s powershell.exe

Remote Desktop Services Zertifikatswechsel Wildcard

Diese Artikel beschreib einen Zertifikatswechsel mit Hilfe der Unternehmens PKI. Das neue Zertifikat wird über die Unternehmens CA beantragt. Dann wird das Zertifikat auf dem Sessionbroker und auf den RDS-Servern (Terminal Server) ausgerollt.

Weiterlesen

Exchange 2016 Updates

Wichtiger Thread-Beitrag von Marco Freund:

https://www.frankysweb.de/neue-sicherheitsupdates-fuer-exchange-server/

Ein Problem, welche ich in der Vergangenheit schon oft hatte, ist, dass nach einem Exchange Update die OWA/ECP Website nicht verfügbar ist und man seltsame Fehlermeldungen erhält – Entweder Error 400 oder die Seite wird unvollständig dargestellt. Mit den Logs konnte ich nicht viel anfangen.

Ich fand heraus, dass nach jedem Exchange Update zwei Skripte ausgeführt werden sollten. Das war mir lange so nicht bekannt. Vielleicht hilft es ja einem weiter. Hier sind die Skripte abgelegt (ggf. Installationsordner anpassen und Powershell mit Adminrechten starten)

C:\Program Files\Microsoft\Exchange Server\V15\Bin> .\UpdateCas.ps1
C:\Program Files\Microsoft\Exchange Server\V15\Bin> .\UpdateConfigFiles.ps1

Wichtig ist auch: Diese Skripte müssen auf dem Mailbox Server ausgeführt werden, also den Servern mit aktiver Mailbox Rolle oder auf Multi Role Servern. Es ist auf den Servern mit Client Access Rolle (betrifft nur Exchange 2010 und 2013) nicht erforderlich.

Exchange Nutzung von Wildcard Zertifikaten

Wer Wildcard Zertifikate in Exchange 2013 oder 2016 einsetzen will, muss ein paar Dinge beachten. Microsoft macht es mal wieder etwas komplizierter als nötig.

Weiterlesen

Exchange 2016 Warteschlange auf andere Partition verschieben

Auf einer neue Partition die Ordnerstruktur erstellen. Z.B.:

D:\Microsoft Exchange\Queue

Exchange Management Shell öffnen und folgendes Kommando eingeben:

Move-TransportDatabase.ps1 -QueueDatabasePath: "D:\Microsoft Exchange\Queue" -QueueDatabaseLoggingPath: "D:\Microsoft Exchange\Queue"

Dieses Script führt die Verschiebeanforderung für die Datenbank und die Logs durch. Die Datenbank und die Logs erscheinen nach der Verschiebung am neuen Speicherort.

Powershell – Installierte Programme auflisten

Regel #1: nutze nicht win32_product!!!

So gut wie alle Beispiele im Netz beziehen sich auf die WMI Provider win32_product. Abrufbar durch:

Get-WmiObject -Class Win32_Product | Where-Object { $_.Name -like "*Software*" }

oder

Get-CimInstance win32_product | Where-Object { $_.Name -like "*Software*" }

Es gibt gute Gründe, die dagegen Sprechen:

  1. Durch den Aufruf wird für jedes einzelne Produkt eine Konsitenzprüfung durchgeführt. Und wenn die fehlschlägt wird sogar noch eine Reparaturinstallation im Hintergrund versucht!!
  2. Deswegen ist der Aufruf auch ultralangsam
  3. Es wird nur Software aufgeführt, die durh einen Windows installer installiert wurde. Und das nutzt längst nicht jede Software

Zu Punkt 1 siehe:

https://support.microsoft.com/en-us/help/974524/event-log-message-indicates-that-the-windows-installer-reconfigured-al

Damit ist win32_product für alle Zeiten disqualifiziert!

Ja aber wie machen wir es denn jetzt?

Über die Registry!

Am einfachsten und am schnellsten geht es über die Registry und das ist auch der Weg, wie die Liste unter Programme hinzufügen/ändern erstellt wird. Es gibt Pfade für 32 Bit Apps und für 64 Bit Apps.

$Apps = @()

$Apps += Get-ItemProperty "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*"

$Apps += Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*"

$Apps | Out-Gridview

Den Tip mit der Registry habe ich von folgendem genialen Blog:

https://xkln.net/blog/please-stop-using-win32product-to-find-installed-software-alternatives-inside/

Dort wird auch beschriben, wie man Software ermittelt, die im Benutzerprofil unter AppData installiert ist. Sicherheitshalber hier per Copy&Paste, falls das Blog mal offline geht. Die Info wird für jeden Admin irgendwann Gold wert sein:

Finding apps that install into AppData

There has been a growing trend of application vendors making installers that deploy to a user’s profile (%userprofile%\AppData). This is commonly done (much to the dismay of the IT departments) to allow users to install programs without needing administrative privileges.

These applications will also have their installation documented in the registry, but under HKEY_CURRENT_USER instead of HKEY_LOCAL_MACHINE.

This poses a few challenges. Each user’s registry hive is located in their profile as %userprofile%\NTUSER.DAT.

  • If a user is logged in, this can be accessed by other (administrative) users on the system via the HKEY_USERS\$ACCOUNT_SID key
  • If a user is not logged in, the hive can be manually mounted using REG LOAD.

One catch is that if a user’s registry hive is already loaded (i.e., they are logged in) it cannot be loaded again as we will get a The process cannot access the file because it is being used by another process. error.

So we’ll need to enumerate a list of profiles in the system, determine whether we need to load their registry hive, mount it if we need to, pull the application install data, and finally unload the hive. The last part is important, failing to do so will leave the user unable to log in due to the same error we encountered above.

The first part of finding a list of profiles and determining whether they’re currently loaded is made easy by quering Win32_UserProfile

localpath                                 sid                                                              loaded special
---------                                 ---                                                              ------ -------
C:\Users\.NET v4.5 Classic                S-1-5-82-3876422241-1344743610-1729199087-774402673-2621913236   False  False
C:\Users\.NET v4.5                        S-1-5-82-271721585-897601226-2024613209-625570482-296978595      False  False
C:\Users\DefaultAppPool                   S-1-5-82-3006700770-424185619-1745488364-794895919-4004696415    False  False
C:\Users\MSSQL$MICROSOFT##WID             S-1-5-80-1184457765-4068085190-3456807688-2200952327-3769537534  True   False
C:\Users\test2                            S-1-5-21-1543284909-1794992621-2893585182-1019                   False  False
C:\Users\test1                            S-1-5-21-1543284909-1794992621-2893585182-1017                   False  False
C:\Users\md                               S-1-5-21-1543284909-1794992621-2893585182-1000                   True   False
C:\WINDOWS\ServiceProfiles\NetworkService S-1-5-20                                                         True   True
C:\WINDOWS\ServiceProfiles\LocalService   S-1-5-19                                                         True   True
C:\WINDOWS\system32\config\systemprofile  S-1-5-18                                                         True   True

There are some key pieces of information we need to extract from this output

  • The loaded parameter tells us if the profile (and therefore hive) is loaded
  • The special parameter tells us whether this is a system account – we can ignore those
  • The sid parameter gives us some clues on what type of account we’re dealing with.

Normal user accounts are prefixed with S-1-5-21, which matches the Microsoft documentation on Well known security identifiers.

Using this info we can put together a smarter function that pulls system wide installed applications, as well as those deployed across all user profiles. Using parameter sets we can allow the user to pull various combinations of data, though some will require administrative privileges:

ParameterRequires AdminData Returned
GlobalNoGlobally installed applications
GlobalAndAllUsersYesGlobally installed applications and all user installed applications. Default.
GlobalAndCurrentUserNoGlobally installed applications and applications installed under the profile of the user executing the function
CurrentUserNoApplications installed under the profile of the user executing the function
AllUsersYesAll user installed applications

And here is the function:

function Get-InstalledApplications() {
    [cmdletbinding(DefaultParameterSetName = 'GlobalAndAllUsers')]

    Param (
        [Parameter(ParameterSetName="Global")]
        [switch]$Global,
        [Parameter(ParameterSetName="GlobalAndCurrentUser")]
        [switch]$GlobalAndCurrentUser,
        [Parameter(ParameterSetName="GlobalAndAllUsers")]
        [switch]$GlobalAndAllUsers,
        [Parameter(ParameterSetName="CurrentUser")]
        [switch]$CurrentUser,
        [Parameter(ParameterSetName="AllUsers")]
        [switch]$AllUsers
    )

    # Excplicitly set default param to True if used to allow conditionals to work
    if ($PSCmdlet.ParameterSetName -eq "GlobalAndAllUsers") {
        $GlobalAndAllUsers = $true
    }

    # Check if running with Administrative privileges if required
    if ($GlobalAndAllUsers -or $AllUsers) {
        $RunningAsAdmin = (New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
        if ($RunningAsAdmin -eq $false) {
            Write-Error "Finding all user applications requires administrative privileges"
            break
        }
    }

    # Empty array to store applications
    $Apps = @()
    $32BitPath = "SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*"
    $64BitPath = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*"

    # Retreive globally insatlled applications
    if ($Global -or $GlobalAndAllUsers -or $GlobalAndCurrentUser) {
        Write-Host "Processing global hive"
        $Apps += Get-ItemProperty "HKLM:\$32BitPath"
        $Apps += Get-ItemProperty "HKLM:\$64BitPath"
    }

    if ($CurrentUser -or $GlobalAndCurrentUser) {
        Write-Host "Processing current user hive"
        $Apps += Get-ItemProperty "Registry::\HKEY_CURRENT_USER\$32BitPath"
        $Apps += Get-ItemProperty "Registry::\HKEY_CURRENT_USER\$64BitPath"
    }

    if ($AllUsers -or $GlobalAndAllUsers) {
        Write-Host "Collecting hive data for all users"
        $AllProfiles = Get-CimInstance Win32_UserProfile | Select LocalPath, SID, Loaded, Special | Where {$_.SID -like "S-1-5-21-*"}
        $MountedProfiles = $AllProfiles | Where {$_.Loaded -eq $true}
        $UnmountedProfiles = $AllProfiles | Where {$_.Loaded -eq $false}

        Write-Host "Processing mounted hives"
        $MountedProfiles | % {
            $Apps += Get-ItemProperty -Path "Registry::\HKEY_USERS\$($_.SID)\$32BitPath"
            $Apps += Get-ItemProperty -Path "Registry::\HKEY_USERS\$($_.SID)\$64BitPath"
        }

        Write-Host "Processing unmounted hives"
        $UnmountedProfiles | % {

            $Hive = "$($_.LocalPath)\NTUSER.DAT"
            Write-Host " -> Mounting hive at $Hive"

            if (Test-Path $Hive) {
            
                REG LOAD HKU\temp $Hive

                $Apps += Get-ItemProperty -Path "Registry::\HKEY_USERS\temp\$32BitPath"
                $Apps += Get-ItemProperty -Path "Registry::\HKEY_USERS\temp\$64BitPath"

                # Run manual GC to allow hive to be unmounted
                [GC]::Collect()
                [GC]::WaitForPendingFinalizers()
            
                REG UNLOAD HKU\temp

            } else {
                Write-Warning "Unable to access registry hive at $Hive"
            }
        }
    }

    Write-Output $Apps
}

Example usage

# Find installed applications installed globally and inside all user profiles (default behavior) and export to a CSV
Get-InstalledApplications | Select DisplayName, InstallLocation | Export-Csv AllApps.csv -NoTypeInformation
# Find installed applications within user profiles
Get-InstalledApplications -AllUsers | Select DisplayName, InstallLocation 
# Find installed applications within the current user profile
Get-InstalledApplications -CurrentUser | Select DisplayName, InstallLocation 

Get-Package

The last and probably most convenient option is Get-Package, but as is the way, there are a few caveats.

  1. You must be running PowerShell 5.1 or newer
  2. It won’t pull applications installed into user profiles that are not the user running the command

That is to say, Get-Package will detect:

  1. Globally installed applications
  2. Applications installed into the user profile of the user running the command

Get-Package returned 1345 items, but the vast majority of the extra rows were various updates (Windows Defender Security and Intelligence updates, Windows Malicious Software Removal Tool updates, monthly Cumulative Updates – you get the picture ).

Interestingly, there were a few NVIDIA applications under the HKLM path that my function above pulled but were not present in the Get-Package output (NVIDIA Display Session Container, NVIDIA Display Session Container, NVIDIA Control Panel, and a bunch more).

Get-Package also returned PowerShell modules installed via the PowerShell Gallery.

Get-Package returning PowerShell modules

Lastly, it also returned a few applications that had previously been uninstalled, though evidently they still left some traces behind.

Hopefully this provides everyone with faster and safer ways to query for installed applications. Remember, friends don’t let friends query Win32_Product.

Remote Desktop Services Standarddrucker gehen nach Abmeldung verloren

Bei neueren Terminal Server Umgebungen (bei uns Windows Server 2019) werden die verbundenen Drucker bei der Abmeldung gelöscht. Dieses Verhalten kann man über die Registry auf das alte Verhalten umstellen (Drucker werden beibehalten)

Für jeden Terminal Server folgenden Registry Eintrag setzen:

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Providers\Client Side Rendering Print Provider]
"RemovePrintersAtLogoff"=dword:00000000

Außerdem soll auf allen Druckern die „Druckaufbereitung auf dem Client“ abgeschaltet werden. Das kann man über die Druckverwaltung des Druckservers einstellen.

Exchange Transportagent deinstallieren

Hatte folgendes Problem mit TrendMicro und in dem Zuge was über die Transportagents gelernt:

https://success.trendmicro.com/solution/1097474-unable-to-start-exchange-transport-service-after-uninstalling-scanmail-for-exchange-smex-or-messag

get-transportagent
Uninstall-TransportAgent -Identity "ScanMail Routing Agent"
Uninstall-TransportAgent -Identity "ScanMail SMTP Receive Agent"

Migration Exchange 2010 auf Exchange 2016

https://www.frankysweb.de/howto-migration-von-exchange-2010-zu-exchange-2016/
https://www.frankysweb.de/exchange-server-patchlevel-ermitteln/
https://www.frankysweb.de/exchange-2016-installation-auf-windows-server-2012-r2/
https://www.frankysweb.de/howto-migration-von-exchange-2010-zu-exchange-2016/
https://www.frankysweb.de/migration-von-exchange-2010-zu-exchange-2016-teil-1/
https://www.frankysweb.de/migration-von-exchange-2010-zu-exchange-2016-teil-2/
https://www.frankysweb.de/migration-von-exchange-2010-zu-exchange-2016-teil-3/
https://www.frankysweb.de/howto-installation-exchange-2016-cu8-auf-server-2016/
https://www.frankysweb.de/exchange-2016-smtp-connector-und-wildcard-san-zertifikate/
Wenn das Zertifikat nicht auf SMTP angewendet werden kann.

https://docs.microsoft.com/en-us/Exchange/plan-and-deploy/supportability-matrix?view=exchserver-2019

Windows Domain Controller Notes

Generelle Kommandos und Notizen zum Umgang mit Domain Controllern. Wird evtl. irgendwann zu einzelnen Artikeln umgemünzt

Weiterlesen

© 2016 kinc.de