Fragensteller
Powershell Server zum ausführen von Cmdlets als Job mit vollem Zugriff auf Computer

Allgemeine Diskussion
-
Mein Ziel ist es einen einfach Server in powershell zu schreiben, der (vorher definierte) Befehle auf der Maschine ausführt. Soweit hab ich das auch geschafft, wenn ich den Server laufen lasse, egal ob im ISE oder direkt mit Powershell ausführen funktioniert alles wunderbar. Der server muss aber im Hintergrund beim Starten des Computer laufen, also auch sobald das Anmeldefenster da ist. Wenn ich nun einen ScheduledJob daraus mache gibt es zwei mögliche Szenarien. Entweder der Server läuft an und Stoppt aber kurze Zeit später, oder der Server läuft er akzeptiert die Befehle, aber sie haben keine Auswirkungen auf die Maschine. Das gleiche Phänomen habe ich, wenn ich den Job bei Anmeldung eines Benutzers starten lasse, es passiert einfach nichts.
Folgende Befehle möchte ich ausführen, geschrieben als Module das ich im Server Importiere:
$code = @" [DllImport("user32.dll")] public static extern bool BlockInput(bool fBlockIt); "@ $userInput = Add-Type -MemberDefinition $code -Name UserInput -Namespace UserInput -PassThru function Enable-UserInput() { $userInput::BlockInput($false) } function Disable-UserInput() { $userInput::BlockInput($true) }
Und so sieht der Server aus:
Im Prinzip wartet der auf eine Anfrage und wenn die zu einer def vorher definierten Funktionen passt wird das ausgeführt. "GetScreenShot" macht ein Bild vom Aktuellen Desktop, speichert es lokal, und schickt es dann zurück. Disable/Enable-Input sperrt und gibt das Keyboard frei. Lock-Screen nimmt ein Bild und zeigt es ganz im Vordergrund an.
<# creates a WindowsForm for locking the screen $f = Path to image file #> function create-LockScreen($f){ $file = (get-item $f) [void][reflection.assembly]::LoadWithPartialName("System.Windows.Forms") $form = new-object Windows.Forms.Form $form.Text = "Desktop Locked" #$form.width = 1280 #$form.height = 1024 $form.WindowState = "Maximized" $form.FormBorderStyle = "None" $form.TopMost = $true $form.BackgroundImage = [System.Drawing.Image]::Fromfile($file) return $form } function lock-Screen($img){ $form = create-LockScreen($img) $form.Show() return $form } function enable-Screen($img){ $img.Close() } function parseRequest($req){ write-host $req if ($req.Contains("?Action=")){ $do = $req.Substring(8) }else{ $do = "Error" } return $do } function getScreenShot{ $pwd = $env:TEMP $screenCapturePathBase = "$pwd\ScreenCapture" $name = "${screenCapturePathBase}$"+(Get-Date).ToString('yyyyMMdd_HHmmss')+".jpg" #$bitmap.Save($name, $jpegCodec, $ep) $b = New-Object System.Drawing.Bitmap([System.Windows.Forms.Screen]::PrimaryScreen.Bounds.Width, [System.Windows.Forms.Screen]::PrimaryScreen.Bounds.Height) $g = [System.Drawing.Graphics]::FromImage($b) $g.CopyFromScreen((New-Object System.Drawing.Point(0,0)), (New-Object System.Drawing.Point(0,0)), $b.Size) $g.Dispose() $b.Save($name) return $name } function evalRequest($action){ switch ($action) { "getScreenShot" { $b = getScreenShot $response.ContentType = "image/jpeg" $buffer =[System.IO.File]::ReadAllBytes($b) return $buffer break; } "disableInput" { Disable-UserInput $m = "Disabled user input" $buffer = [System.Text.Encoding]::Unicode.GetBytes($m) $response.ContentType = "text/html" return $buffer break; } "enableInput" { Enable-UserInput $m = "Enabled user input" $buffer = [System.Text.Encoding]::Unicode.GetBytes($m) $response.ContentType = "text/html" return $buffer break; } "lockScreen" { Disable-UserInput $global:lockedscreen = lock-Screen("C:\users\Administrator\Desktop\keep-calm-and-listen-to-your-teacher-50.png") $m = "Locked Screen" $buffer = [System.Text.Encoding]::Unicode.GetBytes($m) $response.ContentType = "text/html" return $buffer break; } "enableScreen" { Enable-UserInput enable-Screen($global:lockedscreen) $m = "Enabled Screen" $buffer = [System.Text.Encoding]::Unicode.GetBytes($m) $response.ContentType = "text/html" return $buffer break; } "getBefore" { } "quit" { return $false # return $running break; } default { $m = "Error: Action does not exist!" $buffer = [System.Text.Encoding]::Unicode.GetBytes($m) $response.ContentType = "text/html" return $buffer break; } } } #function Start-Server{ $url = 'http://*:1992/' $logfile = "C:\Server_running.txt" write-host $url Add-Type -AssemblyName System.Windows.Forms Import-Module -Name ClientControl $listener = new-object system.net.httplistener $listener.prefixes.add($url) $listener.start() write-output "Start listener" | Out-File $logfile -Append $global:lockedscreen try{ # listening url. while ($listener.islistening) { # write-host "running1 = $running" write-output "Start listening...$((Get-Date).ToString('yyyyMMdd_HHmmss'))" | Out-File $logfile -Append $context = $listener.getcontext() $request = $context.request.Url $response = $context.response #$pattern = "{0} {1}" -f $request.httpmethod, $request.url.localpath write-output "$"+(Get-Date).ToString('yyyyMMdd_HHmmss')+"> $request" | Out-File $logfile -Append # write-host $request.query $todo = parseRequest($request.Query) $action = evalRequest($todo) #write-output "Action : $action" | Out-File $logfile -Append if (!$action){ $m = "Stopped Server" $buffer = [System.Text.Encoding]::Unicode.GetBytes($m) $response.ContentType = "text/html" $response.contentlength64 = $buffer.length $response.outputstream.write($buffer, 0, $buffer.length) $response.OutputStream.flush() $response.close() break; }else{ # $buffer =[System.IO.File]::ReadAllBytes($content) # $con = Get-Content -Stream -Path $content $response.contentlength64 = $action.length $response.outputstream.write($action, 0, $action.length) $response.OutputStream.flush() $response.close() } } } finally{ Write-Output "Server closed" | Out-File $logfile -Append $LISTENER.Stop() $LISTENER.Close() } # }
Es wäre jetzt wichtig, dass ich den Server so zum laufen bekomme, dass ich den Computer unabhängig von Benutzeranmeldung steuern kann, z.B niemand ist angemeldet User sitzt vor dem Computer kann aber nichts machen, weil alles gesperrt und während dessen, kann ich aber ScreenShots ziehen.
Ich wäre sehr dankbar wenn mir jemand Hilfestellung geben und evtl allgemein ein paar Tipps zu meinem Code geben könnte.
- Bearbeitet Yavor TanevMicrosoft contingent staff Montag, 13. Februar 2017 09:17 Titel
- Typ geändert Denniver ReiningMVP, Moderator Donnerstag, 16. Februar 2017 15:59 ....