Einleitung
Die Benutzerkontensteuerung (User Account Control, UAC) ist ein wichtiger Bestandteil der Windows-Sicherheit. UAC reduziert das Risiko von Malware, indem es die Fähigkeit von bösartigem Code einschränkt, mit Administratorrechten ausgeführt zu werden.
Mit UAC muss jede Anwendung, die das Administrator-Zugriffstoken benötigt, die Zustimmung des Endbenutzers einholen. Die einzige Ausnahme ist die Beziehung zwischen übergeordneten und untergeordneten Prozessen. Untergeordnete Prozesse erben das Zugriffstoken des Benutzers vom übergeordneten Prozess. Der übergeordnete und der untergeordnete Prozess müssen jedoch die gleiche Integritätsstufe haben.
UAC in Skripten unter Windows
Gelegentlich, aber dann wirklich problematisch, wird während der Ausführung eines Skripts eine Bestätigung für die Ausführung eines Befehls oder einer Anwendung angefordert. Als Beispiele seien hier cmd.exe, diskpart.exe und regedit.exe genannt.
Befindet man sich im interaktiven Modus, bestätigt man den Dialog und die Verarbeitung wird fortgesetzt.
Will man das Skript aber ohne Interaktionen (zum Beispiel remote) ausführen, muss man irgendwie um diese Dialog herumkommen.
PowerShell und die Eingabeaufforderung
Wenn wir über Skripting unter Windows reden, gibt es hauptsächlich Powershell und die Eingabeaufforderung, da beide in neueren Windows Versionen vorhanden sind und nicht zusätzlich installiert werden müssen.
Es gibt eine Reihe von meist freien Utilities und auch Workarounds um mit dem Problem umzugehen, soweit ich das aber vermeiden kann will ich keine 3rd-Party Utilities einsetzen (zumal diese dann im Netzwerk verteilt und auch gewartet werden müssen) und eine Deaktivierung der UAC kommt für mich nicht in Frage.
Microsoft hat hier in Windows selbst eine Lösung eingebaut, die bei mir sowohl in der Eingabeaufforderung (cmd.exe) als auch in der PowerShell sehr gut funktioniert.
Es gibt nämlich die Möglichkeit über eine Umgebungsvariable einen RunAsInvoker zu konfigurieren.
Um beispielsweise regedit.exe ohne UAC-Abfrage zu starten, verwendet man in der PowerShell folgenden Code:
:: Setzen des RunAsInvoker in PowerShell
[Environment]::SetEnvironmentVariable("__COMPAT_LAYER", "RunAsInvoker")
In der Eingabeaufforderung kann dagegen dieser Code verwendet werden.
:: Setzen des RunAsInvoker in der Eingabeaufforderung
set __COMPAT_LAYER=RunAsInvoker
Happy Skripting und Enjoy it, b!