VBScript mit mehr Rechten

Wenn man alte Scripts durchsieht, findet man die eine oder andere “Krampe”, die einen schmunzeln lässt.

Und eine davon schrieb ich vor 15 Jahren zum Setup von Windows-Embedded Terminals in VBScript.
Der Zweck: Das Script soll mit Admin-Rechten laufen und diese einfordern, wenn sie noch nicht vorhanden sind.


Mein Code sah so aus:

 1Public Function RunElevated()
 2  Const ElevationFlag = "E_L_E_V_A_T_E_D"
 3
 4  Dim i
 5  Dim strArgs
 6  strArgs = ""
 7  For i = 0 To WScript.Arguments.Length - 1
 8    If (WScript.Arguments(i) = ElevationFlag) Then
 9      RunElevated = True
10      Exit Function
11    End If
12    strArgs = strArgs & " """ & WScript.Arguments(i) & """"
13  Next
14
15  Dim sysShell
16  Set sysShell = CreateObject("Shell.Application")
17  Call sysShell.ShellExecute("wscript.exe", """" & _
18    WScript.ScriptFullName & """" & strArgs & " " & _
19    ElevationFlag, "", "runas", 1)    
20  RunElevated = False
21End Function
22
23Public Sub Main()
24  ......
25End Sub
26
27If RunElevated() Then
28  Call Main()
29End If

Weil ein Script nicht weiß, ob es mit “erhöhten (=Admin-) Rechten” oder ohne gestartet wurde, startet es sich selbst mit einem “geheimen” Parameter neu und diesmal mit den notwendigen Rechten.

Wird die Funktion
ShellExecute(file, arguments, directory, operation, show) mit dem operation Parameter runas aufgerufen, übernimmt die Shell die Anzeige des üblichen Dialogs für erhöhte Rechte, oder startet das Programm direkt, wenn die notwendigen Rechte schon vorhanden waren.

Beim ersten Aufruf startet sich das Script somit selbst mit erhöhten Rechten und fügt den geheimen Parameter an.
Der zweite Aufruf (mit den höheren Rechten) erkennt den geheimen Parameter und springt dann zum eigentlich gewünschten Scriptcode.

Apropos runas

Dass das Execute-Verb runas die UAC auffordert, den Zielprozess mit erhöhten Rechten zu starten, ist heute unter der ShellExecute Funktion dokumentiert.
Im Jahr 2010 mit den Platform-SDKs von 2008 fehlte diese Info jedoch und so war eine lange Suche im Netz notwendig, bis ich den Hinweis gefunden hatte.

Wenn man den neuen Prozess nicht per Pipes fernsteuern können muss, ist ShellExecute(runas) die übliche Methode mehr Recht zu erhalten. Die Alternative mit den Login-APIs ist recht kompliziert und funktioniert auch nicht in jedem Kontext.

Hier hat mir also ein Script vorgezeigt, wie meine nachfolgenden C++ Implementierungen auszusehen hatten und haben.

Fazit

Hier lobe ich mir sudo und doas aus der POSIX Welt.
Man kann jedes Programm und jedes Script einfach mit root Rechten starten und braucht keine Umwege.

Das Script entstand um sowohl von der Konsole mit Parametern oder direkt per Doppelklick vom Explorer gestartet werden zu können und funktionierte bei allen damaligen Installationen.

Den Code hätte man etwas einfacher gestalten können … aber hey, es funktioniert.