Windows Loginscripte – Scriptsprachen

Im letzten Artikel habe ich verschiedene Mechanismen für die Abarbeitung von Laufwerksverbindungen etc. gegenüber gestellt. Meine persönliche Präferenz dabei sind die klassichen Loginscripte und hier möchte ich ein wenig die verschiedenen Scriptsprachen gegenüberstellen, mit welchen ich schon hab Erfahrungen sammeln dürfen.



Batch

Der Klassiker schlechthin unter den Loginscripts. Die Befehle funktionieren seit ich IT-denken kann und sie machen was sie sollen.

Für einfachste Umgebungen sicherlich eine gute Wahl.

Der grösste Nachteil ist dem Alter geschuldeten schwachen Leistungsumfang. Solange z.B. alle Benutzer die gleichen Laufwerke benötigen funktioniert es tadellos. Sobald aber Gruppenmitgliedschaften geprüft werden müssen, kommt es schon langsam an seine Grenzen.

PowerShell

PowerShell bietet in seiner Fülle an Modulen und Befehlen viele Möglichkeiten und dies auch bei der Anmeldung.

Wenn man jedoch den Ursprung von PowerShell kennt wird einem schnell klar, dass die Sprache nicht auf Performance aus ist. PowerShell wurde entwickelt um den Administratoren eine Möglichkeit der Verwaltung und der Automatisierung zu bieten. Bei diesen Aufgaben kommt es sehr oft nicht auf die (Milli)Sekunden an und das bringt uns zum grossen Nachteil der Scriptsprache für den Anmeldeprozess. Je komplexer die Aufgaben des Loginscriptes sind, desto langsamer wird es und das spürt die Benutzerin/der Benutzer.

Ich hatte einen Kunden im Schulbereich mit einem Skript, welches mit rund 350 Zeilen die komplette Umgebung eines Benutzers eingerichtet hat. Vom Laufwerk, über die Drucker bis hin zu applikatorischen Einstellungen. Das Skript hat gemacht was es soll, es dauerte einfach jeweils zwischen 3 bis 4 Minuten pro Anmeldung!

Ein weiterer Nachteil kann sein, dass auf den Clients die PowerShell Versionen nachgepflegt werden müssen, je nach eingesetzten Befehlen.

VBScript (VBS)

VBScript ist für viele Systemtechniker erst einmal ein Buch mit sieben Siegeln. Es ist definitiv nicht so intuitiv wie Batch oder PowerShell, bietet jedoch auch eine Fülle von Möglichkeiten, wenn auch mit teils nicht verständlichen Einschränkungen.

Vor Jahren habe ich mich mit VBS auseinander gesetzt (auch geschuldet der Ausbildung) und es ist mittlerweile mein Favorit unter den Skriptsprachen aus folgenden Gründen:

  • Performance: VBS wird schnell abgearbeitet. Teilweise sogar zu schnell für das Windows, so dass bewusste Pausen eingepflegt werden müssen.
    Das vorher erwähnte PowerShell Skript wurde durch VBS abgelöst und benötigte nur noch 45 Sekunden statt mehrere Minuten.
  • Modular: Sauber geschrieben kann ein VBS basiertes Skript sehr modular aufgebaut werden.
  • OS integriert: VBS wird von sämtlichen aktuellen Windows Betriebssystemen unterstützt.

Die Skriptsprache hat auch seine Nachteile, über welche ich dank den Vorteilen hinweg sehen kann:

  • Fehlende Vereinfachung: Gewisse Aktionen können nicht einfach mit einer oder zwei Zeilen erledigt werden, sondern bedürfen um ein Vielfaches. So hatte nach der Ablösung des obigen genannten PowerShell Skriptes das neue VBS basierte nicht mehr rund 350 sondern über 3000 Zeilen.
  • Fehlende Funktionen: Verschachtelte Gruppenmitgliedschaften können z.B. nicht einfach ausgelesen werden. Für solche Fälle ist es jedoch möglich für diese eine Abfrage gezielt z.B. auf PowerShell auszuweichen.

KiXtart (aka KIX)

KIX ist eine weitere oft eingesetzte Skriptsprache. Auch diese ist einfach zu erlernen und anzuwenden. Sie bietet die Standardfunktionen, welche man üblicherweise benötigt. Vereinzelt habe ich diese schon vorgefunden, jedoch für mich hat sie folgenden erheblichen Nachteil:

  • Proprietär: benötigt zusätzliche Programmdateien (via NETLOGON) und ist in den letzten Jahren in der Community kaum mehr aktualisiert worden.

Ich würde somit KIX als umfangreicher wie Batch jedoch schwächer wie VBS/PowerShell einordnen.




Windows Loginscripte & Co.

Ich denke jeder Windows Admin kennt es. Die Benutzer möchten ihre Laufwerke gemappt und am liebsten auch gleich die Drucker verbunden haben. Ich möchte an dieser Stelle meine Sicht auf verschiedene Mechanismen werfen immer auch mit dem Fokus eines Citrix Admins.



Loginscripte

Irgendwelche Skripte welche während der Benutzeranmeldung Laufwerke und Drucker verbinden, Dateien kopieren, etc. gibt es schon seit eh und je. Oder zumindest kenne ich diese seit dem Beginn meiner IT Karriere (Windows 3.11, Windows 95, Windows NT).

Diese funktionieren in der Regel gut und schnell. Die Administratoren müssen sich lediglich mit der entsprechenden Skriptsprache auskennen und man kann loslegen.

Group Policy Preferences (GPP)

Mit Windows 2008/Windows Vista wurden die seit Windows 2000 bekannten Gruppenrichtlinien durch die „Group Policy Preferences“ (exakte Übersetzung mir nicht bekannt) erweitert. Diese kombiniert mit den dazu benötigten Clientseitigen Erweiterungen bieten eine einfach verständliche grafische Oberfläche für die gewünschten Aktionen, welche bei der Anmeldung eines Active-Directory Benutzers ausgeführt werden.

Die GPP sind wirklich intuitiv in der Handhabung und in einem einfachen Server-/Client-Netzwerk eine gute Wahl. Meiner Erfahrung und Meinung nach gibt es jedoch gerade im Citrix Virtual Apps and Desktop (oder DaaS) Umfeld zwei entscheidende Nachteile:

  • Performance: die Abarbeitung der GPP ist z.B. im Vergleich mit einem klassischen VBScript um einiges langsamer, was sich in der (negativen) Zufriedenheit der Benutzer widerspiegelt. Wenn dann noch viele Filter (WMI, Item-level Targeting, etc.) verwendet werden, wird es umso träger.
  • Abhängigkeiten: es gibt div. Applikationen, welche beim Start vollständig verbundene Laufwerke und Drucker erwarten. Die GPP werden jedoch im Hintergrund ausgeführt und dabei kann es vorkommen, dass beim Start einer veröffentlichten Applikation die erwarteten Laufwerke und Drucker fehlen und es so zu anderen Problemen kommt.

3rd Party

Es gibt auf dem Markt div. Dritthersteller, welche sich der einfachen Verwaltung und der optimierten Anmeldeleistung verschrieben haben. In der Regel machen diese auch ihren Job, jedoch gibt es dabei für mich folgende Punkte zu bedenken:

  • Kosten: Dritthersteller schenken in der Regel nichts, also muss eine saubere Kosten-/Nutzen-Rechnung gemacht werden.
  • Abhängigkeiten: Normalerweise bringt jedes Dritthersteller-Produkt seine eigenen Komponenten mit. Diese müssen implementiert und gepflegt werden. In der Fehlersuche hat man diese zusätzlich zu berücksichtigen.
  • Betrieb: Als Consultant und/oder Engineer versuche ich Umgebungen immer so aufzubauen, dass sie später auch im Support nicht zu komplex werden. Je mehr man sich an die integrierten Mittel hält, umso einfacher ist in der Regel auch die Wissensvermittlung an Betriebsteams. Jede Komponente mehr macht den Support in der Regel nicht einfacher sondern eher umgekehrt.

Tabellarische Gegenüberstellung

Loginscripte GPP 3rd Party
Vorteile – OS eigene Mittel
– Je nach Sprache einfache Handhabung
– theoretisch ohne Active-Directory möglich
– OS eigenes Mittel
– Intuitive Handhabung
– grafische Verwaltungsoberfläche
– meist intuitive Handhabung
Nachteile – Performance abhängig von der eingesetzten Scriptsprache
– Scriptsprache muss erlernt werden
– teilweise komplexes Scripting notwendig
– Active-Directory notwendig
– je nach AD/GPO Struktur komplexe Verschachtelungen
– Performance, besonders bei vielen Filtern
– Kosten
– Abhängigkeiten, da mehr Komponenten notwendig
– Komplexität im Betrieb, da mehr Komponenten zu verwalten

Persönliche Präferenz

Die beste Erfahrung habe ich mit dem klassischsten gemacht: den Loginscripten. Diese sind je nach eingesetzter Sprache und Komplexität der Kunden-/Benutzerwünsche teils langwierig in der Entwicklung, aber danach laufen die Scripte normalerweise in der gewünschten Leistung.

Schlussendlich muss jeder für sich die richtige Lösung finden. Meiner Meinung nach am wichtigsten dabei ist, dass in einer Umgebung nur eine Lösung eingesetzt wird und nicht x verschiedene. Das Leben des IT-Personals ist meist schon kompliziert genug.




Installierte .NET Framework Version prüfen

Disclaimer: Bei diesem Artikel handelt es sich definitiv nicht um eine eigene „Entwicklung“.

Nicht selten setzen Programme eine bestimmte .NET Version voraus. Windows bietet leider keine einfache Möglichkeit um diese herauszufinden. Einzig der definierte Registry Wert gibt uns einen Aufschluss auf die interne Build-Nummer, aber nicht auf die konkrete Version.

Ich bin bei Microsoft selbst auf ein Skript gestossen, welches ich seither auf mit der entsprechenden Build Tabelle nachgeführt habe:

    $dotNet4Builds = @{
        '30319'  = @{ Version = [System.Version]'4.0'                                                     }
        '378389' = @{ Version = [System.Version]'4.5'                                                     }
        '378675' = @{ Version = [System.Version]'4.5.1'   ; Comment = '(8.1/2012R2)'                      }
        '378758' = @{ Version = [System.Version]'4.5.1'   ; Comment = '(8/7 SP1/Vista SP2)'               }
        '379893' = @{ Version = [System.Version]'4.5.2'   ; Comment = '(all Windows OS)'                  }
        '380042' = @{ Version = [System.Version]'4.5'     ; Comment = 'and later with KB3168275 rollup'   }
        '393295' = @{ Version = [System.Version]'4.6'     ; Comment = '(Windows 10)'                      }
        '393297' = @{ Version = [System.Version]'4.6'     ; Comment = '(NON Windows 10)'                  }
        '394254' = @{ Version = [System.Version]'4.6.1'   ; Comment = '(Windows 10)'                      }
        '394271' = @{ Version = [System.Version]'4.6.1'   ; Comment = '(NON Windows 10)'                  }
        '394802' = @{ Version = [System.Version]'4.6.2'   ; Comment = '(Windows 10 Anniversary Update)'   }
        '394806' = @{ Version = [System.Version]'4.6.2'   ; Comment = '(NON Windows 10)'                  }
        '460798' = @{ Version = [System.Version]'4.7'     ; Comment = '(Windows 10 Creators Update)'      }
        '460805' = @{ Version = [System.Version]'4.7'     ; Comment = '(NON Windows 10)'                  }
        '461308' = @{ Version = [System.Version]'4.7.1'   ; Comment = '(Windows 10 Fall Creators Update)' }
        '461310' = @{ Version = [System.Version]'4.7.1'   ; Comment = '(NON Windows 10)'                  }
        '461808' = @{ Version = [System.Version]'4.7.2'   ; Comment = '(Windows 10 / 1803)'               }
        '461814' = @{ Version = [System.Version]'4.7.2'   ; Comment = '(other OS than Windows 10 1803)'   }
        '528040' = @{ Version = [System.Version]'4.8'     ; Comment = '(Windows 10 / 1905 & 1911)'        }
        '528372' = @{ Version = [System.Version]'4.8'     ; Comment = '(Windows 10 / 2005 & 2010 & 2105)' }
        '528449' = @{ Version = [System.Version]'4.8'     ; Comment = '(Windows 11 / Server 2022)'        }
        '528049' = @{ Version = [System.Version]'4.8'     ; Comment = '(other OS or Windows 10 builds)'   }
        '533320' = @{ Version = [System.Version]'4.8.1'   ; Comment = '(Windows 11 / 2022)'               }
        '533325' = @{ Version = [System.Version]'4.8.1'   ; Comment = '(other OS or Windows 10 builds)'   }
    }

Die Ausführung sieht dann wie folgt aus:

Ich denke mit diesen Informationen kann man mehr anfangen als den reinen Build Nummern. ;-)

Viel Spass beim Nachbauen :-)




Installierte Windows Sprachpakete prüfen

In unseren Terminalservern und VDIs wollten wir mittels Scripten die Benutzer die OS Sprache ändern lassen. Die Aufbereitung des Images mittels Citrix AppLayering hatte so seine Tücken und für eine einfache Prüfung, ob und welche Sprachen zur Auswahl stehen, habe ich folgendes kleines Skript erstellt.

Es liest über WMI die OS Parameter aus und listet diese im Anschluss in der PowerShell Ausgabe:

$OSInfo = Get-WmiObject -Class Win32_OperatingSystem
$LanguagePacks = $OSInfo.MUILanguages
$LanguagePacks

Die Ausgabe sieht dann wie folgt aus:

Viel Spass beim Nachbauen :-)