none
Powershell Server zum ausführen von Cmdlets als Job mit vollem Zugriff auf Computer RRS feed

  • 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. 


    Samstag, 11. Februar 2017 08:18