ElevateMe - Execution using elevated privileges without UAC prompt
For an English description refer to file "ReadMe.txt" included in the download.
ElevateMe bietet eine Möglichkeit, Prozesse mit den höchsten verfügbaren Privilegien des aktuellen Benutzers ohne UAC-Bestätigung auszuführen.
Dadurch können Automatisierungsskripts unbeaufsichtigt ausgeführt werden.
Das Skript richtet sich an Endnutzer auf ihren privaten Computern, wo sie der lokalen Administratorgruppe angehören.
Benutzung auf eigenes Risiko.
Installation:
Führe "Install_ElevateMe.ps1" aus. (im Download enthalten)
Benutzung
FAQ:
Wie kann das überhaupt funktionieren?
Ein geplanter Task kann so konfiguriert werden, dass er mit den höchsten verfügbaren Privilegien eines Benutzers läuft. Ist der Task einmal erstellt, führt seine Ausführung nicht mehr zu einer Bestätigung über den UAC Prompt. Um diesen geplanten Task wiederverwenden zu können, ist ein Broker Script nötig, das erhöhte Rechte erwirbt und die Schnittstelle zwischen dem Prozess mit niedrigen und dem mit erhöhten Rechten realisiert.
Warum ist die Schnittstelle ein VBScript?
Ja, ich weiß das ist old-school. Aber WScript.exe läuft ohne Fenster. Somit wirst du nie aufblitzende Konsolefenster sehen, die durch die Schnittstelle hervorgerufen werden.
Warum wird die Kommandozeile per Umgebungsvariable übergeben?
Auf den ersten Blick erscheint das eher umständlich. Wenn du allerdings darüber nachdenkst, wie schwierig es werden kann Anführungszeichen korrekt über die Grenzen unterschiedlicher Shells beizubehalten, könntest du eine Idee davon bekommen warum die Definition einer Umgebungsvariable viel einfacher wäre. Einmal definiert, musst du dir keine Sorgen über Einschränkungen der Parser mehr machen.
Warum erstellt das VBScript temporäre Dateien?
Synchronisation und Interprozesskommunikation sind immer etwas schwierig. Die Nutzung von Dateien ist verhältnismäßig einfach. Ein Write-Lock kann dazu verwendet werden Race Conditions zu vermeiden und Daten können in einer Datei zwischen unterschiedlichen Prozessen übermittelt werden.
Beispiele
Example 1a:
Batch Code um einen CMD Prompt mit erhöhten Rechten zu öffnen.
Example 1b:
PowerShell Code um einen PowerShell Prompt mit erhöhten Rechten zu öffnen.
Example 2a:
Der Batch Code unten hat eine zusätzlich erste Zeile, die prüft, ob der Prozess erhöhte Rechte hat. Falls er mit niedrigen Rechten läuft, wird die eigene Kommandozeile der Variablen cmdLn zugewiesen und an ElevateMe.vbs weitergegeben, um die Batchdatei erneut mit den höchsten verfügbaren Privilegien auszuführen.
Ziehe eine oder mehrere Dateien auf die Batchdatei um zu zeigen, dass auch Argumente an den Prozess mit erhöhten Rechten weitergereicht werden.
Du kannst diese erste Zeile in jedem Batch Code wiederverwenden, der erhöhte Rechte erfordert.
Example 2b:
Der PowerShell Code unten hat zwei zusätzliche erste Zeilen, die dasselbe tun, wie die erste Batch Zeile in Example 2a.
Example 2c:
VBScript Code mit demselben Verhalten von Example 2a und 2b.
Example 3a:
Dieser Batch Code ruft sich selbst erneut mit erhöhten Rechten auf und wartet auf die Beendigung dieses Prozesses. Er zeigt, wie man den Rückgabewert des Prozesses mit erhöhten Rechten bekommt.
Example 3b:
PowerShell Code mit demselben Verhalten wie 3a.
Example 3c:
VBScript Code mit demselben Verhalten wie 3a und 3b.
For an English description refer to file "ReadMe.txt" included in the download.
ElevateMe bietet eine Möglichkeit, Prozesse mit den höchsten verfügbaren Privilegien des aktuellen Benutzers ohne UAC-Bestätigung auszuführen.
Dadurch können Automatisierungsskripts unbeaufsichtigt ausgeführt werden.
Das Skript richtet sich an Endnutzer auf ihren privaten Computern, wo sie der lokalen Administratorgruppe angehören.
Benutzung auf eigenes Risiko.
Installation:
Führe "Install_ElevateMe.ps1" aus. (im Download enthalten)
- Der Benutzer wird einmalig zur UAC-Bestätigung aufgefordert.
- Datei "%LOCALAPPDATA%\ElevateMe.vbs" wird erstellt (wobei %LOCALAPPDATA% üblicherweise "C:\Users\<Dein Benutzername>\AppData\Local" ist).
- Der Geplante Task "ElevateMe" wird erstellt.
Benutzung
Code:
%LOCALAPPDATA%\ElevateMe.vbs envVarName [wndStyle] [sync]
envVarName Name einer Umgebungsvariable, die die mit höchsten verfügbaren
Privilegien auszuführende Kommandozeile beinhaltet.
ACHTUNG: Übergib NICHT die Kommandozeile selbst. Weise sie erst
einer Umgebungsvariable zu und übergib nur den Name der Variable
ohne sie zu ihrem Wert zu expandieren.
wndStyle (optional) Ganzzahliger Wert der das Erscheinungsbild des Fensters
für den Prozess mit erhöhten Rechten spezifiziert.
Im Zweifel, wähle 1, 3 oder 7. Standardwert ist 1.
Mögliche Werte sind:
0 Das Fenster ist unsichtbar und ein anderes Fenster ist aktiv.
1 Aktiviere und blende das Fenster ein.
2 Aktiviere und minimiere.
3 Aktiviere und maximiere.
4 Wiederherstellen. Das aktive Fenster bleibt aktiv.
5 Aktiviere und stelle wieder her.
6 Minimiere and aktiviere das nächste top-level Fenster in der Z
Reihenfolge.
7 Minimiere. Das aktive Fenster bleibt aktiv.
8 Blende das Fenster in seinem derzeitigen Zustand ein. Das
aktive Fenster bleibt aktiv.
9 Aktiviere und stelle wieder her. Nutze diesen Wert um ein
minimiertes Fester wiederherzustellen.
10 Setze das Erscheinungsbild des Fensters basierend auf dem
Zustand des Programms das die Anwendung startet.
sync (optional) Ganzzahliger Wert, der spezifiziert, ob der Prozess mit
erhöhten Rechten mit der Ausführung des aufrufenden Prozesses
synchronisiert wird. Wert 0 steht für "falsch", jeder andere Wert
steht für "wahr". Standardmäßig ist der Prozess mit erhöhten
Rechten synchronisiert ("wahr"). Das bedeutet, der aufrufende
Prozess wartet auf die Beendigung des Prozess mit erhöhten
Rechten, bevor er mit der Ausführung fortfährt.
"ElevateMe.vbs" stellt das Arbeitsverzeichnis des aufrufenden Prozesses für den
Prozess mit erhöhten Rechten wieder her. Argumente können Teil der ausgeführten
Kommandozeile sein, getrennt durch Leerzeichen.
Rückgabewert:
- Wenn ein Fehler im VBScript Code auftritt, wird die VBScript Fehlernummer
zurückgegeben (z.B. 13 für einen falschen Typ des zweiten oder dritten
Arguments, oder 450 wenn kein Argument übergeben wurde).
- Ansonsten, wenn die Run Methode fehlschlägt, gibt das Script einen HRESULT
Code zurück (wie -2147024894 für Datei Nicht Gefunden).
- Ansonsten, wenn 0 als sync Parameter übergeben wurde, gibt das Script 0
zurück.
- Ansonsten gibt das Script den Exit Code des Prozesses mit erhöhten Rechten an
den aufrufenden Prozess zurück.
FAQ:
Wie kann das überhaupt funktionieren?
Ein geplanter Task kann so konfiguriert werden, dass er mit den höchsten verfügbaren Privilegien eines Benutzers läuft. Ist der Task einmal erstellt, führt seine Ausführung nicht mehr zu einer Bestätigung über den UAC Prompt. Um diesen geplanten Task wiederverwenden zu können, ist ein Broker Script nötig, das erhöhte Rechte erwirbt und die Schnittstelle zwischen dem Prozess mit niedrigen und dem mit erhöhten Rechten realisiert.
Warum ist die Schnittstelle ein VBScript?
Ja, ich weiß das ist old-school. Aber WScript.exe läuft ohne Fenster. Somit wirst du nie aufblitzende Konsolefenster sehen, die durch die Schnittstelle hervorgerufen werden.
Warum wird die Kommandozeile per Umgebungsvariable übergeben?
Auf den ersten Blick erscheint das eher umständlich. Wenn du allerdings darüber nachdenkst, wie schwierig es werden kann Anführungszeichen korrekt über die Grenzen unterschiedlicher Shells beizubehalten, könntest du eine Idee davon bekommen warum die Definition einer Umgebungsvariable viel einfacher wäre. Einmal definiert, musst du dir keine Sorgen über Einschränkungen der Parser mehr machen.
Warum erstellt das VBScript temporäre Dateien?
Synchronisation und Interprozesskommunikation sind immer etwas schwierig. Die Nutzung von Dateien ist verhältnismäßig einfach. Ein Write-Lock kann dazu verwendet werden Race Conditions zu vermeiden und Daten können in einer Datei zwischen unterschiedlichen Prozessen übermittelt werden.
Beispiele
Example 1a:
Batch Code um einen CMD Prompt mit erhöhten Rechten zu öffnen.
Batch:
set "cmdLn=cmd /k" &%LOCALAPPDATA%\ElevateMe.vbs cmdLn 1 0
Example 1b:
PowerShell Code um einen PowerShell Prompt mit erhöhten Rechten zu öffnen.
Code:
$Env:cmdLn="powershell"; start "$Env:LOCALAPPDATA\ElevateMe.vbs" "cmdLn",1,0 -Wait
Example 2a:
Der Batch Code unten hat eine zusätzlich erste Zeile, die prüft, ob der Prozess erhöhte Rechte hat. Falls er mit niedrigen Rechten läuft, wird die eigene Kommandozeile der Variablen cmdLn zugewiesen und an ElevateMe.vbs weitergegeben, um die Batchdatei erneut mit den höchsten verfügbaren Privilegien auszuführen.
Ziehe eine oder mehrere Dateien auf die Batchdatei um zu zeigen, dass auch Argumente an den Prozess mit erhöhten Rechten weitergereicht werden.
Du kannst diese erste Zeile in jedem Batch Code wiederverwenden, der erhöhte Rechte erfordert.
Batch:
@>nul 2>&1 %__APPDIR__%net.exe session||(setlocal EnableDelayedExpansion&set "cmdLn=!CMDCMDLINE!"&%LOCALAPPDATA%\ElevateMe.vbs cmdLn 1 0&exit /b)
@echo off
title ElevateMe Test
echo current directory: "%cd%"
echo arguments (if any): %*
pause
Example 2b:
Der PowerShell Code unten hat zwei zusätzliche erste Zeilen, die dasselbe tun, wie die erste Batch Zeile in Example 2a.
Code:
If (-Not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)){
$Env:cmdLn=(gwmi Win32_Process -Filter ProcessId=$PID).CommandLine;start "$Env:LOCALAPPDATA\ElevateMe.vbs" "cmdLn",1,0 -Wait;Exit}
$Host.UI.RawUI.WindowTitle = "ElevateMe Test"
"current directory: `"$PWD`""
"arguments (if any):`n $($ARGS -Join `"`n `")"
pause
Example 2c:
VBScript Code mit demselben Verhalten von Example 2a und 2b.
Code:
Option Explicit
Dim oWSh, isElevated
Set oWSh = CreateObject("WScript.Shell")
On Error Resume Next : oWSh.RegRead "HKEY_USERS\S-1-5-19\Environment\TEMP" : isElevated = (Err.Number = 0) : On Error GoTo 0
If Not isElevated Then
oWSh.Environment("PROCESS")("cmdLn") = GetOwnCmdLine : oWSh.Run oWSh.Environment("PROCESS")("LOCALAPPDATA") & "\ElevateMe.vbs cmdLn 1 0", 1, True
Else
Dim out, arg
out = "current directory: """ & oWSh.CurrentDirectory & """" & vbLf & "arguments (if any):"
For Each arg In WScript.Arguments
out = out & vbLf & " " & arg
Next
oWSh.PopUp out, 0, "Elevated", vbSystemModal Or &h00040000& Or &h00200000&
End If
Function GetOwnCmdLine()
Dim oWmi, colProcs, oProc, pid, guid
guid = Left(CreateObject("Scriptlet.TypeLib").Guid, 38)
oWSh.Run """winver.exe"" tag" & guid, 0, False
Set oWmi = GetObject("winmgmts:\\.\root\cimv2")
Set colProcs = oWmi.ExecQuery("SELECT * FROM Win32_Process WHERE CommandLine LIKE '% tag" & guid & "'")
For Each oProc In colProcs : pid = oProc.ParentProcessID : oProc.Terminate : Next
Set colProcs = oWmi.ExecQuery("SELECT * FROM Win32_Process WHERE ProcessID=" & pid)
For Each oProc In colProcs : GetOwnCmdLine = oProc.CommandLine : Next
End Function
Example 3a:
Dieser Batch Code ruft sich selbst erneut mit erhöhten Rechten auf und wartet auf die Beendigung dieses Prozesses. Er zeigt, wie man den Rückgabewert des Prozesses mit erhöhten Rechten bekommt.
Batch:
@echo off &>nul 2>&1 %__APPDIR__%net.exe session &&goto elevatedBranch
setlocal EnableDelayedExpansion
set "cmdLn=!CMDCMDLINE!"
%LOCALAPPDATA%\ElevateMe.vbs cmdLn 1 1
endlocal &set "ret=%errorlevel%"
echo Return value of the elevated process: %ret%
pause
exit /b
:elevatedBranch
echo Elevated process returning 5 to demonstrate the exit code behavior.
pause
exit /b 5
Example 3b:
PowerShell Code mit demselben Verhalten wie 3a.
Code:
If (-Not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
$Env:cmdLn = (gwmi Win32_Process -Filter ProcessId=$PID).CommandLine
$proc = start "$Env:LOCALAPPDATA\ElevateMe.vbs" "cmdLn",1,1 -Wait -PassThru
"Return value of the elevated process: $($proc.ExitCode)"
pause
Exit
}
# elevated branch
"Elevated process returning 5 to demonstrate the exit code behavior."
pause
Exit 5
Example 3c:
VBScript Code mit demselben Verhalten wie 3a und 3b.
Code:
Option Explicit
Dim oWSh, isElevated
Set oWSh = CreateObject("WScript.Shell")
On Error Resume Next : oWSh.RegRead "HKEY_USERS\S-1-5-19\Environment\TEMP" : isElevated = (Err.Number = 0) : On Error GoTo 0
If Not isElevated Then
Dim ret
oWSh.Environment("PROCESS")("cmdLn") = GetOwnCmdLine : ret = oWSh.Run(oWSh.Environment("PROCESS")("LOCALAPPDATA") & "\ElevateMe.vbs cmdLn 1 1", 1, True)
oWSh.PopUp CStr(ret), 0, "Return value of the elevated process:", vbSystemModal Or &h00040000& Or &h00200000&
Else
oWSh.PopUp "Elevated process returning 5 to demonstrate the exit code behavior.", 0, "Elevated", vbSystemModal Or &h00040000& Or &h00200000&
WScript.Quit 5
End If
Function GetOwnCmdLine()
Dim oWmi, colProcs, oProc, pid, guid
guid = Left(CreateObject("Scriptlet.TypeLib").Guid, 38)
oWSh.Run """winver.exe"" tag" & guid, 0, False
Set oWmi = GetObject("winmgmts:\\.\root\cimv2")
Set colProcs = oWmi.ExecQuery("SELECT * FROM Win32_Process WHERE CommandLine LIKE '% tag" & guid & "'")
For Each oProc In colProcs : pid = oProc.ParentProcessID : oProc.Terminate : Next
Set colProcs = oWmi.ExecQuery("SELECT * FROM Win32_Process WHERE ProcessID=" & pid)
For Each oProc In colProcs : GetOwnCmdLine = oProc.CommandLine : Next
End Function