PowerShell Skripte als SYSTEM ausführen
Es gibt immer wieder Situationen, in denen PowerShell-Skripte als lokales System (NT AUTHORITY\SYSTEM) ausgeführt werden müssen. Bei einem unserer Kunden wollten wir auf diese Weise ein Kennwort von Export-Clixml mit dem Schlüssel des lokalen Systems verschlüsselt speichern lassen, damit ein anderer Prozess dieses mit Import-Clixml wieder entschlüsseln und nutzen kann.
Welche Möglichkeiten gibt es?
Im Internet gibt es dazu einige Quellen, die grundsätzlich zwei Möglichkeiten beschreiben: Zum einen das Programm PsExec.exe, zum anderen die Windows-Aufgabenplanung. Bei letzterer wird allerdings nur die Nutzung der grafischen Oberfläche gezeigt. Dabei kann auch PowerShell genutzt werden, um eine Aufgabe anzulegen und auszuführen.
Welchen Code wollen wir ausführen?
Hier zunächst der PowerShell-Code, der als lokales System ausgeführt werden soll:
[CmdletBinding()] Param( [Parameter(Position = 0, Mandatory = $true)][string]$UserName, [Parameter(Position = 1, Mandatory = $true)][string]$Password, [Parameter(Position = 2, Mandatory = $false)][string]$Path = "$env:LOCALAPPDATA\Credential.xml" ) $secureString = ConvertTo-SecureString -String $Password -AsPlainText -Force $credential = [PSCredential]::new($UserName, $secureString) $credential | Export-Clixml -Path $Path
Das Skript übernimmt die Angaben für Benutzername und Kennwort im Klartext, damit diese später als Kommandozeilenparameter übergeben werden können. Optional kann der Speicherort für die zu erstellende Datei angegeben werden. Ich verwende dafür meist die Umgebungsvariable LOCALAPPDATA, die für das lokale System auf „C:\Windows\system32\config\systemprofile\AppData\Local“ gesetzt ist.
Das Skript ist bei mir als „C:\tmp\ExportCredential.ps1“ gespeichert, dieser Pfad wird im folgenden Code benötigt.
Wie erstellen wir mit PowerShell eine Aufgabe?
Der folgende Code muss nicht unbedingt als Skript gespeichert werden und kann einfach über die PowerShell ISE angepasst und ausgeführt werden. Wichtig ist lediglich, dass es sich um eine administrative PowerShell-Sitzung handelt.
Zunächst der fachliche Teil, der vom Benutzer das zu verschlüsselnde Kennwort abfragt und die Argumente für die Ausführung von PowerShell zusammensetzt:
$scriptFile = 'C:\tmp\ExportCredential.ps1' $credential = Get-Credential -Message 'Enter credential to be exported as SYSTEM' $password = $credential.GetNetworkCredential().Password $actionArgument = "-File $scriptFile -UserName $($credential.UserName) -Password $password"
Anschließend kann die Aufgabe erstellt und ausgeführt werden:
$action = New-ScheduledTaskAction -Execute powershell -Argument $actionArgument $principal = New-ScheduledTaskPrincipal -UserId SYSTEM $task = New-ScheduledTask -Action $action -Principal $principal $regTask = $task | Register-ScheduledTask ExportCredential $regTask | Start-ScheduledTask $regTask | Unregister-ScheduledTask -Confirm:$false
Da die Aufgabe im Anschluss direkt wieder gelöscht wird, ist das Kennwort nur sehr kurz im Klartext verfügbar. Damit ist diese Variante auch aus Sicherheitsgründen der Nutzung der grafischen Oberfläche vorzuziehen.
Bonus: Wie sind die Umgebungsvariablen des lokalen Systems gesetzt?
Wollen Sie nur sehr wenig PowerShell-Code ausführen, also zum Beispiel nur die Werte aller Umgebungsvariablen des lokalen Systems in eine Datei exportieren, dann setzen Sie den Wert der Variablen $actionArgument doch so und erstellen damit die Aufgabe:
$actionArgument = '-Command "& { gci Env: | tee C:\tmp\env_system.txt }"'
Fazit
Mit wenigen Zeilen PowerShell kann der Windows-Aufgabenplaner so gesteuert werden, dass kurzfristig eine Aufgabe angelegt und ausgeführt wird. Damit lassen sich Skripte ganz unkompliziert als lokales System ausführen.
Seminarempfehlung
WINDOWS POWERSHELL FÜR ADMINISTRATOREN PSHELL-01
Zum SeminarPrincipal Consultant bei ORDIX
Bei Updates im Blog, informieren wir per E-Mail.
Kommentare