ChromeOS – eine Alternative für ältere Geräte?

Ein Teil meiner privaten Computer erfüllen die Anforderungen von Windows 11 nicht mehr. Um nicht für jedes Familienmitglied einen neuen Rechner anschaffen zu müssen, schaue ich mir aktuell mögliche Alternativen an. Eine erste Alternative ist das mit den Chromebooks ausgelieferte ChromeOS – genauer genommen das ChromeOS Flex, welches frei für viele Geräte verfügbar ist.



Erste Informationen zu ChromeOS Flex findet man auf der entsprechenden Produkteseite von Google -> https://chromeos.google/products/chromeos-flex/
Von dieser aus gelangt man auf die Installationsanweisung. Man benötigt Google Chrome als Browser um in diesem die entsprechende Erweiterung zu installieren.

Installation

Wenn man einen USB Stick mit min. 8 GB (7.9 GB ist nicht genug!) verfügbar hat, kann man mit der genannten Erweiterung das Installationsmedium entweder für die gelistete Hardware, oder flexible für jedes Gerät erstellen:

Mit dem erstellten Stick startet man und kann dann auch zwischen Testen (Boot ab Stick) oder Installieren (Gerät wird komplett formatiert) entscheiden. Auf meinem alten Gerät wollte das Testszenario nicht funktionieren, somit habe ich die Installation ausgewählt. Nach langen 10 Minuten war dann auch das komplette Setup erledigt!

Einrichtung

Mit einem vorhandenen Google Account war die Einrichtung auch blitzschnell erledigt. Lediglich die Tastatursprachen mussten sicher eingestellt werden (DE-CH) aber danach lief alles durch. Das ChromeOS installiert auch sofort alle Erweiterungen aus einem vorhandenen Google Chrome (sofern gesynct) und war innert wenigen Minuten fertig. Noch ein passendes Hintergrund Bild aus dem Internet gesucht et voilà:

Arbeiten

Auch auf meinem alten Lenovo ThinkPad x260 war – man kann es wirklich so sagen – ein „WOW-Effekt“ vorhanden. Nicht gemessen, aber gefühlt nach wenigen Sekunden nach dem Start erscheint schon die Anmeldung und nach dieser kann man nach 1-2 Sekunden loslegen mit Arbeiten. Das Ganze von null, also kein Standby etc.

Die Apps sind einerseits im „Startmenü“ links oder unten in der Mitte zu finden. Ein Umstieg aus der klassischen Windows-Welt ist somit schon mal kein Problem:

Was ich an Applikationen testen konnte lief einwandfrei. Auch die Integration von OneDrive und M365 (Web Apps) makellos. Die Hardware wurde auch erkannt, so dass auch YouTube mit Sound funktionierte. Aus dieser Sicht kann ich nichts negatives berichten.

In den Einstellungen findet man sich als Windows-Benutzer auch sehr gut zurecht. Die Bedienung und Suche nichts neues.

Speziell zu erwähnen ist hier nur die Ausrichtung des Touchpads. Dieses verhielt sich standardmässig 180° anders wie gewohnt. Google hat hier jedoch einen einfachen Switch eingebaut. Was mir sehr positiv aufgefallen ist, weil ich das so sonst noch nie gesehen habe, ist die Akku Analyse. Ladestände und Verbrauchsanalysen kannte ich bereits, aber der Zustand des Akkus im allgemeinen (75% im Bild) habe ich so noch nie gesehen:

Ist man fertig mit der Arbeit, dann sucht man beim ersten Mal die entsprechenden Funktionen. Diese sind unten rechts bei der Uhr versteckt. Die Möglichkeiten sind auch hier für den gewohnten Windows-Benutzer nichts neues, ausser dass die Power-Funktionen hier zu finden sind. Und auch hier: kaum auf Herunterfahren geklickt, ist das Gerät schon aus:

Update

Während meiner Testphase hatte ich nur ein Update und dieses war kaum spürbar. Im Gegensatz zu Windows, welches gem. Murphys Gesetzen immer genau im falschen Moment viele Updates einspielt, führt ChromeOS die Updates im Hintergrund durch und man erhält nur einmal die Info, dass man doch bitte einmal neu starten soll. Dies ist dann in der bereits vorher beschriebenen kurzen Neustartzeit erledigt, und man arbeitet weiter.

Nachteile

Was könnte man als Nachteil bezeichnen?

Sicherlich die Einschränkung der Applikationen, dass hier die Auswahl nicht sehr gross ist. Falls man sich jedoch sowieso zu über 99% im Browser befindet, ist dies kein nennenswerter Nachteil.

Nach dem obigen Absatz ist natürlich die Abhängigkeit zum Internet nicht zu unterschätzen. Zugegebenermassen habe ich die Offlinefähigkeiten nicht getestet, da dies bei uns zu Hause kein Kriterium war. Ist aber sicherlich zu beachten/testen, bevor man auf ChromeOS umsteigt.

Was sich bei mir nun aktuell aber als KO-Kriterium abgezeichnet hat, ist die fehlende Unterstützung unseres Druckers. ChromeOS hat diesen zwar ohne weiteres Zutun erkannt und eingerichtet, der Drucker selbst kann aber mit den Druckjobs nichts anfangen und verwirft diese. Dies muss vor einer Umstellung und/oder bei der Beschaffung eines Druckers beachtet werden!

Fazit

Mir persönlich gefällt das ChromeOS sehr gut und stellt meiner Meinung nach eine gute Alternative für zu Hause dar. Voraussetzung ist aber ganz klar, dass man den Rechner vorwiegend mit Browser-Applikationen benutzt. Das schlanke Betriebssystem und die gezeigte Leistung haben überzeugt. Ich bin auch ein wenig traurig, dass unser Drucker dieses nicht unterstützt, sonst hätte ich für die privaten Anwendungszwecke die perfekte Alternative zu Windows gefunden.




Projekt Backups in DaVinci Resolve

Seit längerem arbeite ich laienhaft mit DaVinci Resolve als Videoschnitt Software. Als ich kürzlich Probleme damit hatte, bemerkte ich, dass eine Sicherung der lokalen Projektdatenbank gar nicht so intuitiv ist.

Backup mit GUI

Mit ein wenig Recherche fand ich dann aber einen Artikel, welcher aufs Handbuch referenzierte (jaja, wer lesen kann ist klar im Vorteil). Kurz zusammengefasst, gibt es im GUI folgende Möglichkeit:

Man wählt im Projektmanager die lokale Projektdatenbank und klickt auf das kleine ‚i‘ rechts davon. Im nächsten Menü hat man die Option eines Backups:

Im nächsten Fenster wählt man einfach den gewünschten Speicherort und die Datenbank ist gesichert:

Die Sicherung ist nichts anderes als ein ZIP Archiv. Wenn man dieses z.B. in 7-Zip wieder öffnet, erkennt man die Ordnerstruktur aus dem %AppData% Ordner:

Backup mit Script

Im Rahmen der oben genannten Fehlersuche bin ich noch auf mehrere Ordner gestossen, welche gesichert werden könnten. Ich habe mir deshalb kurzum ein kleines Backup Script geschrieben:

REM ############################################
REM
REM		USER VARIABLES
REM
REM ############################################

SET DRBackupPath=S:\PITBackupDrive\DavinciResolveBackup

In der Variable DRBackupPath kann ein individueller Sicherungsordner definiert werden.

REM Create time stamp variable for backup files
SET Timestamp=%date:~6,8%%date:~3,2%%date:~0,2%-%time:~0,2%%time:~3,2%

REM Define several paths
SET ZipPath=%ProgramFiles%\7-Zip
SET ZipExe=%ZipPath%\7z.exe
SET DRProgDataPath=%ProgramData%\Blackmagic Design\DaVinci Resolve
SET DRAppDataPath=%AppData%\Blackmagic Design\DaVinci Resolve
SET DRLibraryPath=%DRAppDataPath%\Support\Resolve Project Library

Die verschiedenen Variablen definieren u.a. einen Zeitstempel (Timestamp), den Pfad zu 7-Zip und die verschiedenen Ordnerpfade von Davinci Resolve.

REM Backup Resolve Project folder
"%ZipExe%" a -tzip "%DRBackupPath%\Resolve Projects-%Timestamp%.zip" "%DRLibraryPath%\Resolve Projects"

PAUSE

REM Backup Resolve AppData folder
"%ZipExe%" a -tzip "%DRBackupPath%\DaVinciResolveAppData-%Timestamp%.zip" "%DRAppDataPath%"

PAUSE

REM Backup Resolve ProgramData folder
"%ZipExe%" a -tzip "%DRBackupPath%\DaVinciResolveProgramData-%Timestamp%.zip" "%DRProgDataPath%"

PAUSE

Schlussendlich folgen die drei Sicherungsblöcke. Die Pausen können natürlich auch entfernt werden. Ich habe mir diese zur optischen Prüfung eingebaut, da ich das Script aktuell nur manuell ausführen werde.

Viel Spass beim Nachbauen :-)


Da der Upload von TXT Dateien scheinbar ohne grössere WP Modifikation nicht mehr funktioniert, hier noch das komplette Script:

@ECHO OFF

REM ****************************************
REM    	DavinciResolveBackup.bat
REM		
REM		Author: Urs Heeb
REM
REM		Changelog:
REM			20250529 - Script created
REM
REM		Description
REM			Script creates a backup of following
REM			Davinci Resolve folders:
REM				%ProgramData%\Blackmagic Design\DaVinci Resolve
REM				%AppData%\Blackmagic Design\DaVinci Resolve
REM				%AppData%\Blackmagic Design\DaVinci Resolve\Support\Resolve Project Library
REM			The destination path can be defined
REM			user variables
REM
REM		PRE-REQ:
REM			Installed 7-Zip (path defined in script)
REM
REM ****************************************

CLS

REM ############################################
REM
REM		USER VARIABLES
REM
REM ############################################

SET DRBackupPath=S:\PITBackupDrive\DavinciResolveBackup


REM Create time stamp variable for backup files
SET Timestamp=%date:~6,8%%date:~3,2%%date:~0,2%-%time:~0,2%%time:~3,2%

REM Define several paths
SET ZipPath=%ProgramFiles%\7-Zip
SET ZipExe=%ZipPath%\7z.exe
SET DRProgDataPath=%ProgramData%\Blackmagic Design\DaVinci Resolve
SET DRAppDataPath=%AppData%\Blackmagic Design\DaVinci Resolve
SET DRLibraryPath=%DRAppDataPath%\Support\Resolve Project Library

REM Backup Resolve Project folder
"%ZipExe%" a -tzip "%DRBackupPath%\Resolve Projects-%Timestamp%.zip" "%DRLibraryPath%\Resolve Projects"

PAUSE

REM Backup Resolve AppData folder
"%ZipExe%" a -tzip "%DRBackupPath%\DaVinciResolveAppData-%Timestamp%.zip" "%DRAppDataPath%"

PAUSE

REM Backup Resolve ProgramData folder
"%ZipExe%" a -tzip "%DRBackupPath%\DaVinciResolveProgramData-%Timestamp%.zip" "%DRProgDataPath%"

PAUSE



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.




WSUS – Konfiguration für MDT Umgebung

Ich habe mich in letzter Zeit mit MDT (Microsoft Deployment Toolkit) beschäftigt und mir da auch Gedanken zum WSUS gemacht. In meinem Umfeld wird MDT vor allem für die Installation/Wartung von Citrix Workern (Terminalserver und VDI) genutzt. Diese sind sehr oft auch aus dem Internet zugänglich und sollten daher auch auf einem zeitnahen Patch-Stand sein. Nur wie löst man dies am einfachsten?



Ich ging nun von folgenden Voraussetzungen aus:

  1. Der WSUS soll dediziert für MDT genutzt werden mit sparsamen Ressourcenverbrauch
  2. Die eingesetzten Produkte sind bekannt
  3. Die Client melden regelmässig den Patch-Level
  4. Updates werden freigegeben sobald verfügbar und benötigt

    • Die Tests finden bei der Abnahme der Citrix Worker statt

Die Installation eines WSUS ist im Internet bestens dokumentiert, ansonsten verweise ich auch gerne auf https://www.wsus.de/

Für die Automatisierung des WSUS habe ich bereits eine kleine Serie verfasst mit folgenden Artikeln:

Die Nummern in der Klammern referenzieren auf die entsprechenden Voraussetzungen.

Durch die Kombination der verschiedenen Automatisierungen läuft der WSUS nun soweit autonom und benötigt kaum mehr manuelle Pflege. :-)

Viel Spass beim Nachbauen.




WSUS – Automatisiertes Update Management

So cool WSUS (Windows Server Update Service) auch ist, so hat er sich leider seit dem Erscheinen mit Windows Server 2003 nicht wirklich weiter entwickelt. Im Bereich der Update-Pflege (Freigabe, Ablehnung, etc.) ist mir der WSUS noch immer nicht flexibel genug. Glücklicherweise kann man hier aber mit PowerShell Abhilfe schaffen und dafür habe ich in meinem Lab mehrere Scripte integriert.



Als erstes fangen wir einmal ganz zu Beginn an…

Beim Einrichten des WSUS wird man ja schön durch den Assistenten geführt mit der Frage nach den Produkten, Klassifizierungen, etc. und zu guter Letzt wird in der Regel die erste Synchronisation durchgeführt. Ist diese beendet würde man am liebsten schon die automatischen Freigaben konfigurieren… STOP!

Ersetzte Updates automatisch ablehnen

Leider schafft es Microsoft bis heute nicht, dass bereits ersetzte Updates gar nicht mehr auf alle WSUS in dieser Welt synchronisiert werden. Bei mir sah es zum Beispiel so aus, nachdem ich in meinem Lab die Windows 10 und Office 2016 Updates hinzugefügt hatte:

Hier kommt nun ein erstes Script in meiner Umgebung ins Spiel, welche ich bei Microsoft Learn gefunden habe. Das genannte Script habe ich für mich lediglich noch so modifiziert, dass ein eigener Pfad für die Logdateien genutzt werden kann, anstatt ein Unterordner vom Script-Pfad.

Das Script läuft bei mir als geplanter Task nach der WSUS Synchronisation und lehnt per se ersetzte Updates gleich einmal ab. So verhindere ich, dass die Update-Dateien später überhaupt heruntergeladen werden.

Voraussetzungen und Parameter für den ersten Task:
– Servicebenutzer benötigt WSUS Admin Rechte (entsprechende Gruppenmitgliedschaft)
– Programm: PowerShell.exe
– Parameter: -ExecutionPolicy Bypass <Pfad>\Decline-SupersededUpdates.ps1 -UpdateServer SERVERNAME -Port PORT#

Nachdem dieser Task ausgeführt wurde, sieht die Statistik schon ein erstes Mal aufgeräumter aus:

Nicht benötigte Updates automatisch ablehnen

Nun gibt es aber immer noch viele Updates, welche ich in meiner Umgebung nie benötigen werde. Ich habe mir deshalb ein Script aufgebaut, in welchem ich als erstes Ausschlüsse definiere wie z.B. Prozessortypen, Windows Editionen und Sprachen. Das Script wird ebenfalls in einem geplanten Task ausgeführt, nachdem die ersetzten Updates bereits bereinigt sind:

Voraussetzungen und Parameter für den ersten Task:
– Servicebenutzer benötigt WSUS Admin Rechte (entsprechende Gruppenmitgliedschaft)
– Programm: PowerShell.exe
– Parameter: -ExecutionPolicy Bypass <Script-Pfad>

Vergleicht man nun auch noch diese Statistik, so sieht es schon sehr viel aufgeräumter aus:

Benötigte Updates automatisch freigeben

Nun wollte ich in meiner Lab-Umgebung darauf verzichten mittels automatischer Freigabe einfach Updates freizugeben und herunter zu laden, obwohl ich sie wahrscheinlich nie benötige. Im vorherigen Artikel habe ich beschrieben, wie man die Clients dazu bringt einen regelmässigen Report zu erstellen. Diese Informationen nutze ich im dritten und letzten Script um angeforderte Updates automatisch freizugeben. Damit kann z.B. sichergestellt werden, dass beim nächsten Lauf einer MDT Tasksequenz der frisch aufgesetzte Rechner die aktuellsten Updates installiert hat.

Dieses Script lasse ich ebenfalls als geplanten Task nach den Bereinigungen ausführen:

Voraussetzungen und Parameter für den ersten Task:
– Servicebenutzer benötigt WSUS Admin Rechte (entsprechende Gruppenmitgliedschaft)
– Programm: PowerShell.exe
– Parameter: -ExecutionPolicy Bypass <Script-Pfad>

Hinweis: Dieses Script sollte natürlich NICHT in einer Umgebung eingesetzt werden, in welcher auch sämtliche Windows Updates einer Change- und Test-Prozedur unterstehen.

Viel Spass beim Nachbauen. :-)




WSUS – Clients zum Update Report zwingen

Wahrscheinlich kennt jeder Administrator, welcher auch WSUS im Einsatz hat die Thematik, dass die Clients mit den Reports auf sich warten lassen.

Nach ein wenig Recherche bin ich bei div. Blogs auf Scripts gestossen, welche den WU Client dazu bringen, dem WSUS sofort einen entsprechenden Report zu senden. Genanntes Script habe ich für mich so modifiziert, dass es nicht vom WSUS aus mittels „Invoke“ sondern direkt auf dem Client (Desktop OS wie auch Server OS) ausgeführt wird.

Voraussetzung ist natürlich, dass die entsprechenden GPO Einstellungen für die WSUS Kommunikation eingerichtet und funktionell sind. ;-)

Das unten verfügbare Script kann dann mittels geplantem Task als „SYSTEM“ regelmässig ausgeführt werden, damit der WSUS auch stets den aktuellen Patch-Stand seiner Zielcomputer weiss.

Parameter für den geplanten Task:
– Programm: PowerShell.exe
– Parameter: -ExecutionPolicy Bypass <Pfad zum Script>

Viel Spass beim Nachbauen. :-)




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 :-)




Citrix PVS Store – Replikationsskript V2

Im kürzlich erschienene Artikel habe ich die erste Fassung des Replikationsskriptes vorgestellt. In der aktuell überarbeiteten Version habe ich einerseits die Ausgaben ein wenig „verschönert“ und vor allem werden die Stores nun direkt aus dem PVS ausgelesen.

Voraussetzungen dafür sind:

  • Citrix PVS PowerShell Module an den Standardpfaden (kann in einer Variable angepasst werden)
  • Der ausführende Benutzer muss entsprechende PVS Rechte besitzen
  • Die Stores sollten verständliche Namen (Auswahl) und Beschreibungen (Hilfetexte bei Auswahl) vorweisen.

Zuerst wird nun also der Store Array dynamisch aus dem PVS ausgelesen. Voraussetzung dazu ist ein Laden des entsprechenden PVS PowerShell Moduls:

# Script variables
$PVSModulePath = "C:\Program Files\Citrix\Provisioning Services Console\Citrix.PVS.SnapIn.dll"

# Load PVS PowerShell module
Import-Module $PVSModulePath
# Get PVS vDisk stores from PVS configuration
# Create an array for later use
$Stores = Get-PvsStore

$StoreArray = $null
$StoreArray = @()
$StoreID = 0
ForEach ($Store in $Stores){
    $StoreID = $StoreID +1
    $SplitChar = $Store.Path.IndexOf(":")
    $StoreDisk = $Store.Path.Substring(0,$SplitChar)
    $StorePath = $Store.Path.Substring($SplitChar+1)
    $StoreName = $Store.StoreName
    $StoreArray += [pscustomobject]@{StoreID=$StoreID;Store=$StoreName;StoreDisk=$StoreDisk;StorePath=$StorePath;StoreDescription=$Store.Description}
}

Nun wird aus dem Array eine entsprechende PowerShell Auswahl generiert, wobei hier aktuell auch eine Limite von maximal 5 Stores eingebaut ist:

# Prompt for Store choice
$StoreTitle = "PVS vDisk stores"
$StoreMessage = "Chose the store to replicate:"
$CancelAll = New-Object System.Management.Automation.Host.ChoiceDescription "&Cancel", "Skip this operation and all subsequent operations."

# Generate choice output of each vDisk store to replicate
$StoreOptionCount = 0
ForEach ($Store2 in $StoreArray) {
    $StoreOptionCount = $StoreOptionCount + 1
    $ChoiceID = $Store2.StoreID
    $ChoiceStore = $Store2.Store
    $ChoiceHelp = $Store2.StoreDescription
    $ChoiceCmd = New-Object System.Management.Automation.Host.ChoiceDescription "&$ChoiceID $ChoiceStore", $ChoiceHelp
    New-Variable "StoreOption$ChoiceID" $ChoiceCmd
}

# Generate $StoreOptions variable for final choice output depending on the amount of options
Switch ($StoreOptionCount) {
    0 {$StoreOptions = [System.Management.Automation.Host.ChoiceDescription[]]($CancelAll)}
    1 {$StoreOptions = [System.Management.Automation.Host.ChoiceDescription[]]($CancelAll, $StoreOption1)}
    2 {$StoreOptions = [System.Management.Automation.Host.ChoiceDescription[]]($CancelAll, $StoreOption1, $StoreOption2)}
    3 {$StoreOptions = [System.Management.Automation.Host.ChoiceDescription[]]($CancelAll, $StoreOption1, $StoreOption2, $StoreOption3)}
    4 {$StoreOptions = [System.Management.Automation.Host.ChoiceDescription[]]($CancelAll, $StoreOption1, $StoreOption2, $StoreOption3, $StoreOption4)}
    5 {$StoreOptions = [System.Management.Automation.Host.ChoiceDescription[]]($CancelAll, $StoreOption1, $StoreOption2, $StoreOption3, $StoreOption4, $StoreOption5)}
}

Zu guter Letzt werden anhand der Auswahl die Variablen definiert:

# Prepare variables after the user entry
If ($Store2Replicate -eq 0) {
    # Cancel all
    return; break
}
Else {
    $IDStore = $Store2Replicate-1
    $StoreDisk = $StoreArray[$IDStore].StoreDisk
    $StorePath = $StoreArray[$IDStore].StorePath
    $LocalStore = $StoreDisk + ":" + $StorePath + "\"
    $RemoteStore = "\\" + $PVSRemote + "\" + $StoreDisk + "$" + $StorePath + "\"
    $LocalStorePath = $LocalStore + "*"
    $RemoteStorePath = $RemoteStore + "*"
}

Der restliche Teil ist soweit gleich geblieben und im ersten Artikel bereits beschrieben.

Viel Spass beim Nachbauen :-)