Advertisement
mikedopp

StartPowershellWebServer.ps1

Sep 30th, 2017
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. <#
  2. .Synopsis
  3. Starts powershell webserver
  4. .Description
  5. Starts webserver as powershell process.
  6. Call of the root page (e.g. http://localhost:8080/) returns a powershell execution web form.
  7. Call of /script uploads a powershell script and executes it (as a function).
  8. Call of /log returns the webserver logs, /starttime the start time of the webserver, /time the current time.
  9. /download downloads and /upload uploads a file. /beep generates a sound and /quit or /exit stops the webserver.
  10.  
  11. You may have to configure a firewall exception to allow access to the chosen port, e.g. with:
  12.   netsh advfirewall firewall add rule name="Powershell Webserver" dir=in action=allow protocol=TCP localport=8080
  13.  
  14. After stopping the webserver you should remove the rule, e.g.:
  15.   netsh advfirewall firewall delete rule name="Powershell Webserver"
  16. .Parameter BINDING
  17. Binding of the webserver
  18. .Inputs
  19. None
  20. .Outputs
  21. None
  22. .Example
  23. Start-Webserver.ps1
  24.  
  25. Starts webserver with binding to http://localhost:8080/
  26. .Example
  27. Start-Webserver.ps1 "http://+:8080/"
  28.  
  29. Starts webserver with binding to all IP addresses of the system.
  30. Administrative rights are necessary.
  31. .Example
  32. schtasks.exe /Create /TN "Powershell Webserver" /TR "powershell -file C:\Users\Markus\Documents\Start-WebServer.ps1 http://+:8080/" /SC ONSTART /RU SYSTEM /RL HIGHEST /F
  33.  
  34. Starts powershell webserver as scheduled task as user local system every time the computer starts (when the
  35. correct path to the file Start-WebServer.ps1 is given).
  36. You can start the webserver task manually with
  37.   schtasks.exe /Run /TN "Powershell Webserver"
  38. Delete the webserver task with
  39.   schtasks.exe /Delete /TN "Powershell Webserver"
  40. Scheduled tasks are always running with low priority, so some functions might be slow.
  41. .Notes
  42. Author: Markus Scholtes, 2016-10-22
  43. #>
  44. Param([STRING]$BINDING = 'http://localhost:8080/')
  45.  
  46. # No adminstrative permissions are required for a binding to "localhost"
  47. # $BINDING = 'http://localhost:8080/'
  48. # Adminstrative permissions are required for a binding to network names or addresses.
  49. # + takes all requests to the port regardless of name or ip, * only requests that no other listener answers:
  50. # $BINDING = 'http://+:8080/'
  51.  
  52. # HTML answer templates for specific calls, placeholders !RESULT, !FORMFIELD, !PROMPT are allowed
  53. $HTMLRESPONSECONTENTS = @{
  54.   'GET /'  =  @"
  55. <html><body>
  56.     !HEADERLINE
  57.     <pre>!RESULT</pre>
  58.     <form method="GET" action="/">
  59.     <b>!PROMPT&nbsp;</b><input type="text" maxlength=255 size=80 name="command" value='!FORMFIELD'>
  60.  <input type="submit" name="button" value="Enter">
  61.     </form>
  62. </body></html>
  63. "@
  64.   'GET /script'  =  @"
  65. <html><body>
  66.     !HEADERLINE
  67.     <form method="POST" enctype="multipart/form-data" action="/script">
  68.     <p><b>Script to execute:</b><input type="file" name="filedata"></p>
  69.     <b>Parameters:</b><input type="text" maxlength=255 size=80 name="parameter">
  70.  <input type="submit" name="button" value="Execute">
  71.     </form>
  72. </body></html>
  73. "@
  74.   'GET /download'  =  @"
  75. <html><body>
  76.     !HEADERLINE
  77.     <pre>!RESULT</pre>
  78.     <form method="POST" action="/download">
  79.     <b>Path to file:</b><input type="text" maxlength=255 size=80 name="filepath" value='!FORMFIELD'>
  80.  <input type="submit" name="button" value="Download">
  81.     </form>
  82. </body></html>
  83. "@
  84.   'POST /download'  =  @"
  85. <html><body>
  86.     !HEADERLINE
  87.     <pre>!RESULT</pre>
  88.     <form method="POST" action="/download">
  89.     <b>Path to file:</b><input type="text" maxlength=255 size=80 name="filepath" value='!FORMFIELD'>
  90.  <input type="submit" name="button" value="Download">
  91.     </form>
  92. </body></html>
  93. "@
  94.   'GET /upload'  =  @"
  95. <html><body>
  96.     !HEADERLINE
  97.     <form method="POST" enctype="multipart/form-data" action="/upload">
  98.     <p><b>File to upload:</b><input type="file" name="filedata"></p>
  99.     <b>Path to store on webserver:</b><input type="text" maxlength=255 size=80 name="filepath">
  100.  <input type="submit" name="button" value="Upload">
  101.     </form>
  102. </body></html>
  103. "@
  104.   'POST /script' = "<html><body>!HEADERLINE<pre>!RESULT</pre></body></html>"
  105.   'POST /upload' = "<html><body>!HEADERLINE<pre>!RESULT</pre></body></html>"
  106.   'GET /exit' = "<html><body>Stopped powershell webserver</body></html>"
  107.   'GET /quit' = "<html><body>Stopped powershell webserver</body></html>"
  108.   'GET /log' = "<html><body>!HEADERLINELog of powershell webserver:<br /><pre>!RESULT</pre></body></html>"
  109.   'GET /starttime' = "<html><body>!HEADERLINEPowershell webserver started at $(Get-Date -Format s)</body></html>"
  110.   'GET /time' = "<html><body>!HEADERLINECurrent time: !RESULT</body></html>"
  111.   'GET /beep' = "<html><body>!HEADERLINEBEEP...</body></html>"
  112. }
  113.  
  114. # Set navigation header line for all web pages
  115. $HEADERLINE = "<p><a href='/'>Command execution</a> <a href='/script'>Execute script</a> <a href='/download'>Download file</a> <a href='/upload'>Upload file</a> <a href='/log'>Web logs</a> <a href='/starttime'>Webserver start time</a> <a href='/time'>Current time</a> <a href='/beep'>Beep</a> <a href='/quit'>Stop webserver</a></p>"
  116.  
  117. # Starting the powershell webserver
  118. "$(Get-Date -Format s) Starting powershell webserver..."
  119. $LISTENER = New-Object System.Net.HttpListener
  120. $LISTENER.Prefixes.Add($BINDING)
  121. $LISTENER.Start()
  122. $Error.Clear()
  123.  
  124. try
  125. {
  126.     "$(Get-Date -Format s) Powershell webserver started."
  127.     $WEBLOG = "$(Get-Date -Format s) Powershell webserver started.`n"
  128.   while ($LISTENER.IsListening)
  129.   {
  130.     # analyze incoming request
  131.     $CONTEXT = $LISTENER.GetContext()
  132.     $REQUEST = $CONTEXT.Request
  133.     $RESPONSE = $CONTEXT.Response
  134.     $RESPONSEWRITTEN = $FALSE
  135.  
  136.     # log to console
  137.     "$(Get-Date -Format s) $($REQUEST.RemoteEndPoint.Address.ToString()) $($REQUEST.httpMethod) $($REQUEST.Url.PathAndQuery)"
  138.     # and in log variable
  139.     $WEBLOG += "$(Get-Date -Format s) $($REQUEST.RemoteEndPoint.Address.ToString()) $($REQUEST.httpMethod) $($REQUEST.Url.PathAndQuery)`n"
  140.  
  141.     # is there a fixed coding for the request?
  142.     $RECEIVED = '{0} {1}' -f $REQUEST.httpMethod, $REQUEST.Url.LocalPath
  143.     $HTMLRESPONSE = $HTMLRESPONSECONTENTS[$RECEIVED]
  144.       $RESULT = ''
  145.  
  146.     # check for known commands
  147.     switch ($RECEIVED)
  148.     {
  149.       "GET /"
  150.       { # execute command
  151.             # retrieve GET query string
  152.             $FORMFIELD = ''
  153.             $FORMFIELD = [URI]::UnescapeDataString(($REQUEST.Url.Query -replace "\+"," "))
  154.             # remove fixed form fields out of query string
  155.             $FORMFIELD = $FORMFIELD -replace "\?command=","" -replace "\?button=enter","" -replace "&command=","" -replace "&button=enter",""
  156.             # when command is given...
  157.             if (![STRING]::IsNullOrEmpty($FORMFIELD))
  158.             {
  159.                 try {
  160.                     # ... execute command
  161.                     $RESULT = Invoke-Expression -EA SilentlyContinue $FORMFIELD 2> $NULL | Out-String
  162.                 }
  163.                 catch   {}
  164.                 if ($Error.Count -gt 0)
  165.                 { # retrieve error message on error
  166.                     $RESULT += "`nError while executing '$FORMFIELD'`n`n"
  167.                     $RESULT += $Error[0]
  168.                     $Error.Clear()
  169.                 }
  170.             }
  171.             # preset form value with command for the caller's convenience
  172.             $HTMLRESPONSE = $HTMLRESPONSE -replace '!FORMFIELD', $FORMFIELD
  173.             # insert powershell prompt to form
  174.             $PROMPT = "PS $PWD>"
  175.             $HTMLRESPONSE = $HTMLRESPONSE -replace '!PROMPT', $PROMPT
  176.         break
  177.       }
  178.  
  179.       "GET /script"
  180.       { # present upload form, nothing to do here
  181.         break
  182.       }
  183.  
  184.       "POST /script"
  185.       { # upload and execute script
  186.  
  187.         # only if there is body data in the request
  188.         if ($REQUEST.HasEntityBody)
  189.         {
  190.             # set default message to error message (since we just stop processing on error)
  191.             $RESULT = "Received corrupt or incomplete form data"
  192.  
  193.             # check content type
  194.             if ($REQUEST.ContentType)
  195.             {
  196.                         # retrieve boundary marker for header separation
  197.                         $BOUNDARY = $NULL
  198.                         if ($REQUEST.ContentType -match "boundary=(.*);")
  199.                         {   $BOUNDARY = "--" + $MATCHES[1] }
  200.                         else
  201.                         { # marker might be at the end of the line
  202.                             if ($REQUEST.ContentType -match "boundary=(.*)$")
  203.                             { $BOUNDARY = "--" + $MATCHES[1] }
  204.                         }
  205.  
  206.                 if ($BOUNDARY)
  207.                 { # only if header separator was found
  208.  
  209.                             # read complete header (inkl. file data) into string
  210.                     $READER = New-Object System.IO.StreamReader($REQUEST.InputStream, $REQUEST.ContentEncoding)
  211.                             $DATA = $READER.ReadToEnd()
  212.                             $READER.Close()
  213.                             $REQUEST.InputStream.Close()
  214.  
  215.                             $PARAMETERS = ""
  216.                             $SOURCENAME = ""
  217.  
  218.                             # separate headers by boundary string
  219.                             $DATA -replace "$BOUNDARY--\r\n", "$BOUNDARY`r`n--" -split "$BOUNDARY\r\n" | % {
  220.                                 # omit leading empty header and end marker header
  221.                                 if (($_ -ne "") -and ($_ -ne "--"))
  222.                                 {
  223.                                     # only if well defined header (separation between meta data and data)
  224.                                     if ($_.IndexOf("`r`n`r`n") -gt 0)
  225.                                     {
  226.                                         # header data before two CRs is meta data
  227.                                         # first look for the file in header "filedata"
  228.                                         if ($_.Substring(0, $_.IndexOf("`r`n`r`n")) -match "Content-Disposition: form-data; name=(.*);")
  229.                                         {
  230.                                             $HEADERNAME = $MATCHES[1] -replace '\"'
  231.                                             # headername "filedata"?
  232.                                             if ($HEADERNAME -eq "filedata")
  233.                                             { # yes, look for source filename
  234.                                                 if ($_.Substring(0, $_.IndexOf("`r`n`r`n")) -match "filename=(.*)")
  235.                                                 { # source filename found
  236.                                                     $SOURCENAME = $MATCHES[1] -replace "`r`n$" -replace "`r$" -replace '\"'
  237.                                                     # store content of file in variable
  238.                                                     $FILEDATA = $_.Substring($_.IndexOf("`r`n`r`n") + 4) -replace "`r`n$"
  239.                                               }
  240.                                             }
  241.                                         }
  242.                                         else
  243.                                         { # look for other headers (we need "parameter")
  244.                                             if ($_.Substring(0, $_.IndexOf("`r`n`r`n")) -match "Content-Disposition: form-data; name=(.*)")
  245.                                             { # header found
  246.                                                 $HEADERNAME = $MATCHES[1] -replace '\"'
  247.                                                 # headername "parameter"?
  248.                                                 if ($HEADERNAME -eq "parameter")
  249.                                                 { # yes, look for paramaters
  250.                                                     $PARAMETERS = $_.Substring($_.IndexOf("`r`n`r`n") + 4) -replace "`r`n$" -replace "`r$"
  251.                                                 }
  252.                                             }
  253.                                         }
  254.                                     }
  255.                                 }
  256.                             }
  257.  
  258.                             if ($SOURCENAME -ne "")
  259.                             { # execute only if a source file exists
  260.  
  261.                                 $EXECUTE = "function Powershell-WebServer-Func {`n" + $FILEDATA + "`n}`nPowershell-WebServer-Func " + $PARAMETERS
  262.                             try {
  263.                                 # ... execute script
  264.                                 $RESULT = Invoke-Expression -EA SilentlyContinue $EXECUTE 2> $NULL | Out-String
  265.                             }
  266.                             catch   {}
  267.                             if ($Error.Count -gt 0)
  268.                             { # retrieve error message on error
  269.                                 $RESULT += "`nError while executing script $SOURCENAME`n`n"
  270.                                 $RESULT += $Error[0]
  271.                                 $Error.Clear()
  272.                             }
  273.                             }
  274.                             else
  275.                             {
  276.                                 $RESULT = "No file data received"
  277.                             }
  278.                 }
  279.                     }
  280.         }
  281.         else
  282.         {
  283.             $RESULT = "No client data received"
  284.         }
  285.         break
  286.       }
  287.  
  288.       { $_ -like "* /download" } # GET or POST method are allowed for download page
  289.       { # download file
  290.  
  291.         # is POST data in the request?
  292.         if ($REQUEST.HasEntityBody)
  293.         { # POST request
  294.                     # read complete header into string
  295.                 $READER = New-Object System.IO.StreamReader($REQUEST.InputStream, $REQUEST.ContentEncoding)
  296.                     $DATA = $READER.ReadToEnd()
  297.                     $READER.Close()
  298.                     $REQUEST.InputStream.Close()
  299.  
  300.                     # get headers into hash table
  301.                     $HEADER = @{}
  302.                 $DATA.Split('&') | % { $HEADER.Add([URI]::UnescapeDataString(($_.Split('=')[0] -replace "\+"," ")), [URI]::UnescapeDataString(($_.Split('=')[1] -replace "\+"," "))) }
  303.  
  304.                 # read header 'filepath'
  305.                 $FORMFIELD = $HEADER.Item('filepath')
  306.                 # remove leading and trailing double quotes since Test-Path does not like them
  307.                 $FORMFIELD = $FORMFIELD -replace "^`"","" -replace "`"$",""
  308.         }
  309.         else
  310.         { # GET request
  311.  
  312.                 # retrieve GET query string
  313.                 $FORMFIELD = ''
  314.             $FORMFIELD = [URI]::UnescapeDataString(($REQUEST.Url.Query -replace "\+"," "))
  315.                 # remove fixed form fields out of query string
  316.                 $FORMFIELD = $FORMFIELD -replace "\?filepath=","" -replace "\?button=download","" -replace "&filepath=","" -replace "&button=download",""
  317.                 # remove leading and trailing double quotes since Test-Path does not like them
  318.                 $FORMFIELD = $FORMFIELD -replace "^`"","" -replace "`"$",""
  319.         }
  320.  
  321.             # when path is given...
  322.             if (![STRING]::IsNullOrEmpty($FORMFIELD))
  323.             { # check if file exists
  324.                 if (Test-Path $FORMFIELD -PathType Leaf)
  325.                 {
  326.                     try {
  327.                         # ... download file
  328.                             $BUFFER = [System.IO.File]::ReadAllBytes($FORMFIELD)
  329.                             $RESPONSE.ContentLength64 = $BUFFER.Length
  330.                             $RESPONSE.SendChunked = $FALSE
  331.                             $RESPONSE.ContentType = "application/octet-stream"
  332.                             $FILENAME = Split-Path -Leaf $FORMFIELD
  333.                             $RESPONSE.AddHeader("Content-disposition", "attachment; filename=$FILENAME")
  334.                             $RESPONSE.OutputStream.Write($BUFFER, 0, $BUFFER.Length)
  335.                             # mark response as already given
  336.                         $RESPONSEWRITTEN = $TRUE
  337.                     }
  338.                     catch   {}
  339.                     if ($Error.Count -gt 0)
  340.                     { # retrieve error message on error
  341.                         $RESULT += "`nError while downloading '$FORMFIELD'`n`n"
  342.                         $RESULT += $Error[0]
  343.                         $Error.Clear()
  344.                     }
  345.                 }
  346.                 else
  347.                 {
  348.                     # ... file not found
  349.                     $RESULT = "File $FORMFIELD not found"
  350.                 }
  351.             }
  352.             # preset form value with file path for the caller's convenience
  353.             $HTMLRESPONSE = $HTMLRESPONSE -replace '!FORMFIELD', $FORMFIELD
  354.         break
  355.       }
  356.  
  357.       "GET /upload"
  358.       { # present upload form, nothing to do here
  359.         break
  360.       }
  361.  
  362.       "POST /upload"
  363.       { # upload file
  364.  
  365.         # only if there is body data in the request
  366.         if ($REQUEST.HasEntityBody)
  367.         {
  368.             # set default message to error message (since we just stop processing on error)
  369.             $RESULT = "Received corrupt or incomplete form data"
  370.  
  371.             # check content type
  372.             if ($REQUEST.ContentType)
  373.             {
  374.                         # retrieve boundary marker for header separation
  375.                         $BOUNDARY = $NULL
  376.                         if ($REQUEST.ContentType -match "boundary=(.*);")
  377.                         {   $BOUNDARY = "--" + $MATCHES[1] }
  378.                         else
  379.                         { # marker might be at the end of the line
  380.                             if ($REQUEST.ContentType -match "boundary=(.*)$")
  381.                             { $BOUNDARY = "--" + $MATCHES[1] }
  382.                         }
  383.  
  384.                 if ($BOUNDARY)
  385.                 { # only if header separator was found
  386.  
  387.                             # read complete header (inkl. file data) into string
  388.                     $READER = New-Object System.IO.StreamReader($REQUEST.InputStream, $REQUEST.ContentEncoding)
  389.                             $DATA = $READER.ReadToEnd()
  390.                             $READER.Close()
  391.                             $REQUEST.InputStream.Close()
  392.  
  393.                             # variables for filenames
  394.                             $FILENAME = ""
  395.                             $SOURCENAME = ""
  396.  
  397.                             # separate headers by boundary string
  398.                             $DATA -replace "$BOUNDARY--\r\n", "$BOUNDARY`r`n--" -split "$BOUNDARY\r\n" | % {
  399.                                 # omit leading empty header and end marker header
  400.                                 if (($_ -ne "") -and ($_ -ne "--"))
  401.                                 {
  402.                                     # only if well defined header (seperation between meta data and data)
  403.                                     if ($_.IndexOf("`r`n`r`n") -gt 0)
  404.                                     {
  405.                                         # header data before two CRs is meta data
  406.                                         # first look for the file in header "filedata"
  407.                                         if ($_.Substring(0, $_.IndexOf("`r`n`r`n")) -match "Content-Disposition: form-data; name=(.*);")
  408.                                         {
  409.                                             $HEADERNAME = $MATCHES[1] -replace '\"'
  410.                                             # headername "filedata"?
  411.                                             if ($HEADERNAME -eq "filedata")
  412.                                             { # yes, look for source filename
  413.                                                 if ($_.Substring(0, $_.IndexOf("`r`n`r`n")) -match "filename=(.*)")
  414.                                                 { # source filename found
  415.                                                     $SOURCENAME = $MATCHES[1] -replace "`r`n$" -replace "`r$" -replace '\"'
  416.                                                     # store content of file in variable
  417.                                                     $FILEDATA = $_.Substring($_.IndexOf("`r`n`r`n") + 4) -replace "`r`n$"
  418.                                               }
  419.                                             }
  420.                                         }
  421.                                         else
  422.                                         { # look for other headers (we need "filepath" to know where to store the file)
  423.                                             if ($_.Substring(0, $_.IndexOf("`r`n`r`n")) -match "Content-Disposition: form-data; name=(.*)")
  424.                                             { # header found
  425.                                                 $HEADERNAME = $MATCHES[1] -replace '\"'
  426.                                                 # headername "filepath"?
  427.                                                 if ($HEADERNAME -eq "filepath")
  428.                                                 { # yes, look for target filename
  429.                                                     $FILENAME = $_.Substring($_.IndexOf("`r`n`r`n") + 4) -replace "`r`n$" -replace "`r$" -replace '\"'
  430.                                                 }
  431.                                             }
  432.                                         }
  433.                                     }
  434.                                 }
  435.                             }
  436.  
  437.                             if ($FILENAME -ne "")
  438.                             { # upload only if a targetname is given
  439.                                 if ($SOURCENAME -ne "")
  440.                                 { # only upload if source file exists
  441.  
  442.                                     # check or construct a valid filename to store
  443.                                     $TARGETNAME = ""
  444.                                     # if filename is a container name, add source filename to it
  445.                                     if (Test-Path $FILENAME -PathType Container)
  446.                                     {
  447.                                         $TARGETNAME = Join-Path $FILENAME -ChildPath $(Split-Path $SOURCENAME -Leaf)
  448.                                     } else {
  449.                                         # try name in the header
  450.                                         $TARGETNAME = $FILENAME
  451.                                     }
  452.  
  453.                                 try {
  454.                                     # ... save file with the same encoding as received
  455.                                         [IO.File]::WriteAllText($TARGETNAME, $FILEDATA, $REQUEST.ContentEncoding)
  456.                                 }
  457.                                 catch   {}
  458.                                 if ($Error.Count -gt 0)
  459.                                 { # retrieve error message on error
  460.                                     $RESULT += "`nError saving '$TARGETNAME'`n`n"
  461.                                     $RESULT += $Error[0]
  462.                                     $Error.Clear()
  463.                                 }
  464.                                 else
  465.                                 { # success
  466.                                 $RESULT = "File $SOURCENAME successfully uploaded as $TARGETNAME"
  467.                             }
  468.                                 }
  469.                                 else
  470.                                 {
  471.                                     $RESULT = "No file data received"
  472.                                 }
  473.                             }
  474.                             else
  475.                             {
  476.                                 $RESULT = "Missing target file name"
  477.                             }
  478.                 }
  479.                     }
  480.         }
  481.         else
  482.         {
  483.             $RESULT = "No client data received"
  484.         }
  485.         break
  486.       }
  487.  
  488.       "GET /log"
  489.       { # return the webserver log (stored in log variable)
  490.         $RESULT = $WEBLOG
  491.         break
  492.       }
  493.  
  494.       "GET /time"
  495.       { # return current time
  496.         $RESULT = Get-Date -Format s
  497.         break
  498.       }
  499.  
  500.       "GET /starttime"
  501.       { # return start time of the powershell webserver (already contained in $HTMLRESPONSE, nothing to do here)
  502.         break
  503.       }
  504.  
  505.       "GET /beep"
  506.       { # Beep
  507.         [CONSOLE]::beep(800, 300) # or "`a" or [char]7
  508.         break
  509.       }
  510.  
  511.       "GET /quit"
  512.       { # stop powershell webserver, nothing to do here
  513.         break
  514.       }
  515.  
  516.       "GET /exit"
  517.       { # stop powershell webserver, nothing to do here
  518.         break
  519.       }
  520.  
  521.       default
  522.             {   # unknown command, return error
  523.         $RESPONSE.StatusCode = 404
  524.         $HTMLRESPONSE = '<html><body>Page not found</body></html>'
  525.         }
  526.  
  527.     }
  528.  
  529.     # only send response if not already done
  530.     if (!$RESPONSEWRITTEN)
  531.     {
  532.         # insert header line string into HTML template
  533.         $HTMLRESPONSE = $HTMLRESPONSE -replace '!HEADERLINE', $HEADERLINE
  534.  
  535.         # insert result string into HTML template
  536.         $HTMLRESPONSE = $HTMLRESPONSE -replace '!RESULT', $RESULT
  537.  
  538.         # return HTML answer to caller
  539.         $BUFFER = [Text.Encoding]::UTF8.GetBytes($HTMLRESPONSE)
  540.         $RESPONSE.ContentLength64 = $BUFFER.Length
  541.         $RESPONSE.OutputStream.Write($BUFFER, 0, $BUFFER.Length)
  542.         }
  543.  
  544.     # and finish answer to client
  545.     $RESPONSE.Close()
  546.  
  547.     # received command to stop webserver?
  548.     if ($RECEIVED -eq 'GET /exit' -or $RECEIVED -eq 'GET /quit')
  549.     { # then break out of while loop
  550.         "$(Get-Date -Format s) Stopping powershell webserver..."
  551.         break;
  552.     }
  553.   }
  554. }
  555. finally
  556. {
  557.   # Stop powershell webserver
  558.   $LISTENER.Stop()
  559.   $LISTENER.Close()
  560.   "$(Get-Date -Format s) Powershell webserver stopped."
  561. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement