Advertisement
UlrichC

Untitled

Jul 4th, 2019
942
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ########################Add Types###################################################
  2. Add-Type -AssemblyName PresentationFramework
  3. Add-Type -AssemblyName System.Windows.Forms
  4. Add-Type -Name Window -Namespace Console -MemberDefinition '
  5. [DllImport("Kernel32.dll")]
  6. public static extern IntPtr GetConsoleWindow();
  7.  
  8. [DllImport("user32.dll")]
  9. public static extern bool ShowWindow(IntPtr hWnd, Int32 nCmdShow);
  10. '
  11. $ErrorActionPreference = "SilentlyContinue"
  12.  
  13.  
  14. If (!([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {[System.Windows.Forms.MessageBox]::Show("This application needs to be ran as an administrator.", "Elevated Privilages Required."); Return; Exit 5}
  15.  
  16. $scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
  17. #Write-Host "Script Path: $ScriptPath"
  18.  
  19.  
  20.  
  21. #Quick check to make sure the machine even has a network location. Commented out to prevent other testers from getting stalled.
  22. If(!(Test-Connection -Cn admin.com -BufferSize 16 -Count 1 -ea 0 -quiet)) {[System.Windows.Forms.MessageBox]::Show("The Primary server is unreachable. Make sure Ethernet is connected.", "No Way to Phone Home."); Return;}
  23.  
  24. If (!(Test-Path "C:\Production Base Apps")) {mkdir "C:\Production Base Apps"}
  25. If (!(Test-Path "C:\Wim")) {mkdir "C:\Wim"}
  26.  
  27.  
  28. If (!(Test-Path "\\$Env:Computername\Production Base Apps")) {New-SmbShare -Temporary -Name "Production Base Apps" -ReadAccess "admin\u46 imaging rights" -Path "C:\Production Base Apps"}
  29. If (!(Test-Path "\\$Env:Computername\Wim")) {New-SmbShare -Temporary -Name "Wim" -ReadAccess "admin\u46 imaging rights" -Path "C:\Wim"}
  30. Function CountConnections {
  31.             $smb = Get-SMBSession | Where-Object {$_.ClientComputerName -Like "10.*"}
  32.             $Global:SessionCount = ($smb.clientcomputername).count
  33.             #Check if the variable is NULL.
  34.            IF (!($Global:SessionCount)) {$Global:SessionCount = "0"}
  35.             #Change content of TextBlock to the active number of connections
  36.             $syncHash.TextBlock_ActiveConnections.Text = "Number of clients connected:
  37.            $Global:SessionCount (Maximum of 20)"
  38.     }
  39.  
  40. Function WriteDate {
  41.     $SyncTime = Get-Date
  42.  #   Write-Output $SyncTime | Out-File "C:\Program Files\CacheDevice\LastSync.Date"
  43. }
  44. #$CountConnectionsFunction = Get-Content Function:\CountConnections -ErrorAction Stop
  45. #$CountConnectionsObject = New-Object System.Management.Automation.Runspaces.SessionStateFunctionEntry -ArgumentList 'CountConnections', $CountConnectionsFunction
  46.  
  47. $WriteDateFunction = Get-Content Function:\WriteDate -ErrorAction Stop
  48. $WriteDateFunctionObject = New-Object System.Management.Automation.Runspaces.SessionStateFunctionEntry -ArgumentList 'WriteDateFunction', $WriteDateFunction
  49.  
  50. #Add Function to session state
  51. $InitialSessionState = [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault()
  52. #$InitialSessionState.Commands.Add($CountConnectionsObject)
  53. $InitialSessionState.Commands.Add($WriteDateFunctionObject)
  54. $InitialSessionState.Commands.Add($scriptPath)
  55.  
  56.  
  57. #Start runspace for the WPF GUI.
  58. $Runspace = [runspacefactory]::CreateRunspace($InitialSessionState)
  59. $Runspace.ApartmentState = "STA"
  60. $Runspace.ThreadOptions = "ReuseThread"
  61. $Runspace.Open()
  62.  
  63. $code = {
  64.  
  65. #Write-Host "Script Path: $ScriptPath"
  66. #############################XAML Code stolen from Visual Studio#############################################
  67. [xml]$xaml = @"
  68. <Window
  69. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  70. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Name="Window_Main"
  71.  
  72. Title="Image Cache Software" Height="256" Width="380" ResizeMode="NoResize">
  73. <Grid Name="MainMenu">
  74. <TextBlock HorizontalAlignment="Left" TextWrapping="Wrap" Text="Your computer must syncronize with the primary Zen server before continuing." VerticalAlignment="Top" Margin="10,10,0,0" Height="64" Width="120"/>
  75. <Button x:Name="Button_ShutDown" Content="Shut Down" HorizontalAlignment="Left" VerticalAlignment="Top" Width="120" Margin="10,104,0,0"/>
  76. <Button x:Name="Button_StartCachingServices" Content="Start Caching Services" HorizontalAlignment="Left" VerticalAlignment="Top" Width="120" Margin="10,79,0,0"/>
  77. <TextBlock HorizontalAlignment="Left" TextWrapping="Wrap" VerticalAlignment="Top" Margin="140,137,0,0" Width="100" Height="25" TextAlignment="Center"><Run Text="Sync Status"/><LineBreak/><Run/></TextBlock>
  78. <Rectangle x:Name="Rectangle_Status" Fill="Red" HorizontalAlignment="Right" Height="25" Margin="0,137,339,0" Stroke="Black" VerticalAlignment="Top" Width="25"/>
  79. <Border BorderBrush="Black" BorderThickness="1" Margin="10,167,10,10">
  80.    <TextBlock x:Name="TextBlock_SyncStatus" HorizontalAlignment="Left" TextWrapping="Wrap" VerticalAlignment="Top" Margin="-1" Width="354" Height="69" TextAlignment="Center"><Run/><LineBreak/><Run Text="Waiting for Synchronization"/></TextBlock>
  81. </Border>
  82. <TextBlock x:Name="TextBlock_ActiveConnections" HorizontalAlignment="Left" TextWrapping="Wrap" VerticalAlignment="Top" Margin="172,10,0,0" Width="192"><Run Text="Number of clients connected:"/><LineBreak/><Run Text="(Maximum of 20)"/><LineBreak/><Run/></TextBlock>
  83. <Rectangle HorizontalAlignment="Left" Height="1" Margin="0,131,0,0" Stroke="Black" VerticalAlignment="Top" Width="374"/>
  84. <Rectangle HorizontalAlignment="Left" Height="132" Margin="139,0,0,0" Stroke="Black" VerticalAlignment="Top" Width="1" RenderTransformOrigin="0.5,0.5">
  85.    <Rectangle.RenderTransform>
  86.        <TransformGroup>
  87.            <ScaleTransform ScaleX="-1"/>
  88.            <SkewTransform/>
  89.            <RotateTransform/>
  90.            <TranslateTransform/>
  91.        </TransformGroup>
  92.    </Rectangle.RenderTransform>
  93. </Rectangle>
  94. <Button x:Name="CountSessions" Content="Show Active Connections" HorizontalAlignment="Left" VerticalAlignment="Top" Width="192" Margin="172,50,0,0"/>
  95.  
  96. </Grid>
  97. </Window>
  98. "@
  99.  ####################End of XAML code##################################
  100.  
  101.  #Load WPF into Hash Table.
  102. $syncHash = [hashtable]::Synchronized(@{})
  103. $reader=(New-Object System.Xml.XmlNodeReader $xaml)
  104. $syncHash.Window=[Windows.Markup.XamlReader]::Load( $reader )
  105.  
  106. Function WebServer {
  107.     $syncHash.Host = $host
  108.     $Runspace = [runspacefactory]::CreateRunspace()
  109.     $Runspace.ApartmentState = "STA"
  110.     $Runspace.ThreadOptions = "ReuseThread"
  111.     $Runspace.Open()
  112.     $Runspace.SessionStateProxy.SetVariable("syncHash",$syncHash)
  113.    
  114.    
  115.     $code = {
  116.  
  117.         <#
  118. .Synopsis
  119. Starts powershell webserver
  120. .Description
  121. Starts webserver as powershell process.
  122. Call of the root page (e.g. http://localhost:8080/) returns a powershell execution web form.
  123. Call of /script uploads a powershell script and executes it (as a function).
  124. Call of /log returns the webserver logs, /starttime the start time of the webserver, /time the current time.
  125. /download downloads and /upload uploads a file. /beep generates a sound and /quit or /exit stops the webserver.
  126. Any other call delivers the static content that fits to the path provided. If the static path is a directory,
  127. a file index.htm, index.html, default.htm or default.html in this directory is delivered if present.
  128.  
  129. You may have to configure a firewall exception to allow access to the chosen port, e.g. with:
  130.     netsh advfirewall firewall add rule name="Powershell Webserver" dir=in action=allow protocol=TCP localport=8080
  131.  
  132. After stopping the webserver you should remove the rule, e.g.:
  133.     netsh advfirewall firewall delete rule name="Powershell Webserver"
  134. .Parameter BINDING
  135. Binding of the webserver
  136. .Parameter BASEDIR
  137. Base directory for static content (default: the script's directory)
  138. .Inputs
  139. None
  140. .Outputs
  141. None
  142. .Example
  143. Start-Webserver.ps1
  144.  
  145. Starts webserver with binding to http://localhost:8080/
  146. .Example
  147. Start-Webserver.ps1 "http://+:8080/"
  148.  
  149. Starts webserver with binding to all IP addresses of the system.
  150. Administrative rights are necessary.
  151. .Example
  152. 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
  153.  
  154. Starts powershell webserver as scheduled task as user local system every time the computer starts (when the
  155. correct path to the file Start-WebServer.ps1 is given).
  156. You can start the webserver task manually with
  157.     schtasks.exe /Run /TN "Powershell Webserver"
  158. Delete the webserver task with
  159.     schtasks.exe /Delete /TN "Powershell Webserver"
  160. Scheduled tasks are always running with low priority, so some functions might be slow.
  161. .Notes
  162. Version 1.1, 2017-11-23
  163. Author: Markus Scholtes
  164. #>
  165. Param([STRING]$BINDING = 'http://+:8080/', [STRING]$BASEDIR = "")
  166.  
  167. # No adminstrative permissions are required for a binding to "localhost"
  168. # $BINDING = 'http://localhost:8080/'
  169. # Adminstrative permissions are required for a binding to network names or addresses.
  170. # + takes all requests to the port regardless of name or ip, * only requests that no other listener answers:
  171. # $BINDING = 'http://+:8080/'
  172.  
  173. if ($BASEDIR -eq "")
  174. {   # retrieve script path as base path for static content
  175.     if ($MyInvocation.MyCommand.CommandType -eq "ExternalScript")
  176.     { $BASEDIR = Split-Path -Parent -Path $MyInvocation.MyCommand.Definition }
  177.     else # compiled with PS2EXE:
  178.     { $BASEDIR = Split-Path -Parent -Path ([Environment]::GetCommandLineArgs()[0]) }
  179. }
  180. # convert to absolute path
  181. $BASEDIR = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($BASEDIR)
  182.  
  183. # MIME hash table for static content
  184. $MIMEHASH = @{".avi"="video/x-msvideo"; ".crt"="application/x-x509-ca-cert"; ".css"="text/css"; ".der"="application/x-x509-ca-cert"; ".flv"="video/x-flv"; ".gif"="image/gif"; ".htm"="text/html"; ".html"="text/html"; ".ico"="image/x-icon"; ".jar"="application/java-archive"; ".jardiff"="application/x-java-archive-diff"; ".jpeg"="image/jpeg"; ".jpg"="image/jpeg"; ".js"="application/x-javascript"; ".mov"="video/quicktime"; ".mp3"="audio/mpeg"; ".mpeg"="video/mpeg"; ".mpg"="video/mpeg"; ".pdf"="application/pdf"; ".pem"="application/x-x509-ca-cert"; ".pl"="application/x-perl"; ".png"="image/png"; ".rss"="text/xml"; ".shtml"="text/html"; ".swf"="application/x-shockwave-flash"; ".txt"="text/plain"; ".war"="application/java-archive"; ".wmv"="video/x-ms-wmv"; ".xml"="text/xml"}
  185.  
  186. # HTML answer templates for specific calls, placeholders !RESULT, !FORMFIELD, !PROMPT are allowed
  187. $HTMLRESPONSECONTENTS = @{
  188.     'GET /'  =  @"
  189. <html><body>
  190.     !HEADERLINE
  191.     <pre>!RESULT</pre>
  192.     <form method="GET" action="/">
  193.     <b>!PROMPT&nbsp;</b><input type="text" maxlength=255 size=80 name="command" value='!FORMFIELD'>
  194.     <input type="submit" name="button" value="Enter">
  195.     </form>
  196. </body></html>
  197. "@
  198.     'GET /script'  =  @"
  199. <html><body>
  200.     !HEADERLINE
  201.     <form method="POST" enctype="multipart/form-data" action="/script">
  202.     <p><b>Script to execute:</b><input type="file" name="filedata"></p>
  203.     <b>Parameters:</b><input type="text" maxlength=255 size=80 name="parameter">
  204.     <input type="submit" name="button" value="Execute">
  205.     </form>
  206. </body></html>
  207. "@
  208.     'GET /download'  =  @"
  209. <html><body>
  210.     !HEADERLINE
  211.     <pre>!RESULT</pre>
  212.     <form method="POST" action="/download">
  213.     <b>Path to file:</b><input type="text" maxlength=255 size=80 name="filepath" value='!FORMFIELD'>
  214.     <input type="submit" name="button" value="Download">
  215.     </form>
  216. </body></html>
  217. "@
  218.     'POST /download'  =  @"
  219. <html><body>
  220.     !HEADERLINE
  221.     <pre>!RESULT</pre>
  222.     <form method="POST" action="/download">
  223.     <b>Path to file:</b><input type="text" maxlength=255 size=80 name="filepath" value='!FORMFIELD'>
  224.     <input type="submit" name="button" value="Download">
  225.     </form>
  226. </body></html>
  227. "@
  228.     'GET /upload'  =  @"
  229. <html><body>
  230.     !HEADERLINE
  231.     <form method="POST" enctype="multipart/form-data" action="/upload">
  232.     <p><b>File to upload:</b><input type="file" name="filedata"></p>
  233.     <b>Path to store on webserver:</b><input type="text" maxlength=255 size=80 name="filepath">
  234.     <input type="submit" name="button" value="Upload">
  235.     </form>
  236. </body></html>
  237. "@
  238.     'POST /script' = "<html><body>!HEADERLINE<pre>!RESULT</pre></body></html>"
  239.     'POST /upload' = "<html><body>!HEADERLINE<pre>!RESULT</pre></body></html>"
  240.     'GET /exit' = "<html><body>Stopped powershell webserver</body></html>"
  241.     'GET /quit' = "<html><body>Stopped powershell webserver</body></html>"
  242.     'GET /log' = "<html><body>!HEADERLINELog of powershell webserver:<br /><pre>!RESULT</pre></body></html>"
  243.     'GET /starttime' = "<html><body>!HEADERLINEPowershell webserver started at $(Get-Date -Format s)</body></html>"
  244.     'GET /time' = "<html><body>!HEADERLINECurrent time: !RESULT</body></html>"
  245.     'GET /beep' = "<html><body>!HEADERLINEBEEP...</body></html>"
  246. }
  247.  
  248. # Set navigation header line for all web pages
  249. $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>"
  250.  
  251. # Starting the powershell webserver
  252. "$(Get-Date -Format s) Starting powershell webserver..."
  253. $LISTENER = New-Object System.Net.HttpListener
  254. $LISTENER.Prefixes.Add($BINDING)
  255. $LISTENER.Start()
  256. $Error.Clear()
  257.  
  258. try
  259. {
  260.     "$(Get-Date -Format s) Powershell webserver started."
  261.     $WEBLOG = "$(Get-Date -Format s) Powershell webserver started.`n"
  262.     while ($LISTENER.IsListening)
  263.     {
  264.         # analyze incoming request
  265.         $CONTEXT = $LISTENER.GetContext()
  266.         $REQUEST = $CONTEXT.Request
  267.         $RESPONSE = $CONTEXT.Response
  268.         $RESPONSEWRITTEN = $FALSE
  269.  
  270.         # log to console
  271.         "$(Get-Date -Format s) $($REQUEST.RemoteEndPoint.Address.ToString()) $($REQUEST.httpMethod) $($REQUEST.Url.PathAndQuery)"
  272.         # and in log variable
  273.         $WEBLOG += "$(Get-Date -Format s) $($REQUEST.RemoteEndPoint.Address.ToString()) $($REQUEST.httpMethod) $($REQUEST.Url.PathAndQuery)`n"
  274.  
  275.         # is there a fixed coding for the request?
  276.         $RECEIVED = '{0} {1}' -f $REQUEST.httpMethod, $REQUEST.Url.LocalPath
  277.         $HTMLRESPONSE = $HTMLRESPONSECONTENTS[$RECEIVED]
  278.         $RESULT = ''
  279.  
  280.         # check for known commands
  281.         switch ($RECEIVED)
  282.         {
  283.             "GET /"
  284.             {   # execute command
  285.                 # retrieve GET query string
  286.                 $FORMFIELD = ''
  287.                 $FORMFIELD = [URI]::UnescapeDataString(($REQUEST.Url.Query -replace "\+"," "))
  288.                 # remove fixed form fields out of query string
  289.                 $FORMFIELD = $FORMFIELD -replace "\?command=","" -replace "\?button=enter","" -replace "&command=","" -replace "&button=enter",""
  290.                 # when command is given...
  291.                 if (![STRING]::IsNullOrEmpty($FORMFIELD))
  292.                 {
  293.                     try {
  294.                         # ... execute command
  295.                         $RESULT = Invoke-Expression -EA SilentlyContinue $FORMFIELD 2> $NULL | Out-String
  296.                     }
  297.                     catch   {}
  298.                     if ($Error.Count -gt 0)
  299.                     { # retrieve error message on error
  300.                         $RESULT += "`nError while executing '$FORMFIELD'`n`n"
  301.                         $RESULT += $Error[0]
  302.                         $Error.Clear()
  303.                     }
  304.                 }
  305.                 # preset form value with command for the caller's convenience
  306.                 $HTMLRESPONSE = $HTMLRESPONSE -replace '!FORMFIELD', $FORMFIELD
  307.                 # insert powershell prompt to form
  308.                 $PROMPT = "PS $PWD>"
  309.                 $HTMLRESPONSE = $HTMLRESPONSE -replace '!PROMPT', $PROMPT
  310.                 break
  311.             }
  312.  
  313.             "GET /script"
  314.             { # present upload form, nothing to do here
  315.                 break
  316.             }
  317.  
  318.             "POST /script"
  319.             { # upload and execute script
  320.  
  321.                 # only if there is body data in the request
  322.                 if ($REQUEST.HasEntityBody)
  323.                 {
  324.                     # set default message to error message (since we just stop processing on error)
  325.                     $RESULT = "Received corrupt or incomplete form data"
  326.  
  327.                     # check content type
  328.                     if ($REQUEST.ContentType)
  329.                     {
  330.                         # retrieve boundary marker for header separation
  331.                         $BOUNDARY = $NULL
  332.                         if ($REQUEST.ContentType -match "boundary=(.*);")
  333.                         {   $BOUNDARY = "--" + $MATCHES[1] }
  334.                         else
  335.                         { # marker might be at the end of the line
  336.                             if ($REQUEST.ContentType -match "boundary=(.*)$")
  337.                             { $BOUNDARY = "--" + $MATCHES[1] }
  338.                         }
  339.  
  340.                         if ($BOUNDARY)
  341.                         { # only if header separator was found
  342.  
  343.                             # read complete header (inkl. file data) into string
  344.                             $READER = New-Object System.IO.StreamReader($REQUEST.InputStream, $REQUEST.ContentEncoding)
  345.                             $DATA = $READER.ReadToEnd()
  346.                             $READER.Close()
  347.                             $REQUEST.InputStream.Close()
  348.  
  349.                             $PARAMETERS = ""
  350.                             $SOURCENAME = ""
  351.  
  352.                             # separate headers by boundary string
  353.                             $DATA -replace "$BOUNDARY--\r\n", "$BOUNDARY`r`n--" -split "$BOUNDARY\r\n" | % {
  354.                                 # omit leading empty header and end marker header
  355.                                 if (($_ -ne "") -and ($_ -ne "--"))
  356.                                 {
  357.                                     # only if well defined header (separation between meta data and data)
  358.                                     if ($_.IndexOf("`r`n`r`n") -gt 0)
  359.                                     {
  360.                                         # header data before two CRs is meta data
  361.                                         # first look for the file in header "filedata"
  362.                                         if ($_.Substring(0, $_.IndexOf("`r`n`r`n")) -match "Content-Disposition: form-data; name=(.*);")
  363.                                         {
  364.                                             $HEADERNAME = $MATCHES[1] -replace '\"'
  365.                                             # headername "filedata"?
  366.                                             if ($HEADERNAME -eq "filedata")
  367.                                             { # yes, look for source filename
  368.                                                 if ($_.Substring(0, $_.IndexOf("`r`n`r`n")) -match "filename=(.*)")
  369.                                                 { # source filename found
  370.                                                     $SOURCENAME = $MATCHES[1] -replace "`r`n$" -replace "`r$" -replace '\"'
  371.                                                     # store content of file in variable
  372.                                                     $FILEDATA = $_.Substring($_.IndexOf("`r`n`r`n") + 4) -replace "`r`n$"
  373.                                                 }
  374.                                             }
  375.                                         }
  376.                                         else
  377.                                         { # look for other headers (we need "parameter")
  378.                                             if ($_.Substring(0, $_.IndexOf("`r`n`r`n")) -match "Content-Disposition: form-data; name=(.*)")
  379.                                             { # header found
  380.                                                 $HEADERNAME = $MATCHES[1] -replace '\"'
  381.                                                 # headername "parameter"?
  382.                                                 if ($HEADERNAME -eq "parameter")
  383.                                                 { # yes, look for paramaters
  384.                                                     $PARAMETERS = $_.Substring($_.IndexOf("`r`n`r`n") + 4) -replace "`r`n$" -replace "`r$"
  385.                                                 }
  386.                                             }
  387.                                         }
  388.                                     }
  389.                                 }
  390.                             }
  391.  
  392.                             if ($SOURCENAME -ne "")
  393.                             { # execute only if a source file exists
  394.  
  395.                                 $EXECUTE = "function Powershell-WebServer-Func {`n" + $FILEDATA + "`n}`nPowershell-WebServer-Func " + $PARAMETERS
  396.                                 try {
  397.                                     # ... execute script
  398.                                     $RESULT = Invoke-Expression -EA SilentlyContinue $EXECUTE 2> $NULL | Out-String
  399.                                 }
  400.                                 catch   {}
  401.                                 if ($Error.Count -gt 0)
  402.                                 { # retrieve error message on error
  403.                                     $RESULT += "`nError while executing script $SOURCENAME`n`n"
  404.                                     $RESULT += $Error[0]
  405.                                     $Error.Clear()
  406.                                 }
  407.                             }
  408.                             else
  409.                             {
  410.                                 $RESULT = "No file data received"
  411.                             }
  412.                         }
  413.                     }
  414.                 }
  415.                 else
  416.                 {
  417.                     $RESULT = "No client data received"
  418.                 }
  419.                 break
  420.             }
  421.  
  422.             { $_ -like "* /download" } # GET or POST method are allowed for download page
  423.             {   # download file
  424.  
  425.                 # is POST data in the request?
  426.                 if ($REQUEST.HasEntityBody)
  427.                 { # POST request
  428.                     # read complete header into string
  429.                     $READER = New-Object System.IO.StreamReader($REQUEST.InputStream, $REQUEST.ContentEncoding)
  430.                     $DATA = $READER.ReadToEnd()
  431.                     $READER.Close()
  432.                     $REQUEST.InputStream.Close()
  433.  
  434.                     # get headers into hash table
  435.                     $HEADER = @{}
  436.                     $DATA.Split('&') | % { $HEADER.Add([URI]::UnescapeDataString(($_.Split('=')[0] -replace "\+"," ")), [URI]::UnescapeDataString(($_.Split('=')[1] -replace "\+"," "))) }
  437.  
  438.                     # read header 'filepath'
  439.                     $FORMFIELD = $HEADER.Item('filepath')
  440.                     # remove leading and trailing double quotes since Test-Path does not like them
  441.                     $FORMFIELD = $FORMFIELD -replace "^`"","" -replace "`"$",""
  442.                 }
  443.                 else
  444.                 { # GET request
  445.  
  446.                     # retrieve GET query string
  447.                     $FORMFIELD = ''
  448.                     $FORMFIELD = [URI]::UnescapeDataString(($REQUEST.Url.Query -replace "\+"," "))
  449.                     # remove fixed form fields out of query string
  450.                     $FORMFIELD = $FORMFIELD -replace "\?filepath=","" -replace "\?button=download","" -replace "&filepath=","" -replace "&button=download",""
  451.                     # remove leading and trailing double quotes since Test-Path does not like them
  452.                     $FORMFIELD = $FORMFIELD -replace "^`"","" -replace "`"$",""
  453.                 }
  454.  
  455.                 # when path is given...
  456.                 if (![STRING]::IsNullOrEmpty($FORMFIELD))
  457.                 { # check if file exists
  458.                     if (Test-Path $FORMFIELD -PathType Leaf)
  459.                     {
  460.                         try {
  461.                             # ... download file
  462.                             $BUFFER = [System.IO.File]::ReadAllBytes($FORMFIELD)
  463.                             $RESPONSE.ContentLength64 = $BUFFER.Length
  464.                             $RESPONSE.SendChunked = $FALSE
  465.                             $RESPONSE.ContentType = "application/octet-stream"
  466.                             $FILENAME = Split-Path -Leaf $FORMFIELD
  467.                             $RESPONSE.AddHeader("Content-Disposition", "attachment; filename=$FILENAME")
  468.                             $RESPONSE.AddHeader("Last-Modified", [IO.File]::GetLastWriteTime($FORMFIELD).ToString('r'))
  469.                             $RESPONSE.AddHeader("Server", "Powershell Webserver/1.1 on ")
  470.                             $RESPONSE.OutputStream.Write($BUFFER, 0, $BUFFER.Length)
  471.                             # mark response as already given
  472.                             $RESPONSEWRITTEN = $TRUE
  473.                         }
  474.                         catch   {}
  475.                         if ($Error.Count -gt 0)
  476.                         { # retrieve error message on error
  477.                             $RESULT += "`nError while downloading '$FORMFIELD'`n`n"
  478.                             $RESULT += $Error[0]
  479.                             $Error.Clear()
  480.                         }
  481.                     }
  482.                     else
  483.                     {
  484.                         # ... file not found
  485.                         $RESULT = "File $FORMFIELD not found"
  486.                     }
  487.                 }
  488.                 # preset form value with file path for the caller's convenience
  489.                 $HTMLRESPONSE = $HTMLRESPONSE -replace '!FORMFIELD', $FORMFIELD
  490.                 break
  491.             }
  492.  
  493.             "GET /upload"
  494.             { # present upload form, nothing to do here
  495.                 break
  496.             }
  497.  
  498.             "POST /upload"
  499.             { # upload file
  500.  
  501.                 # only if there is body data in the request
  502.                 if ($REQUEST.HasEntityBody)
  503.                 {
  504.                     # set default message to error message (since we just stop processing on error)
  505.                     $RESULT = "Received corrupt or incomplete form data"
  506.  
  507.                     # check content type
  508.                     if ($REQUEST.ContentType)
  509.                     {
  510.                         # retrieve boundary marker for header separation
  511.                         $BOUNDARY = $NULL
  512.                         if ($REQUEST.ContentType -match "boundary=(.*);")
  513.                         {   $BOUNDARY = "--" + $MATCHES[1] }
  514.                         else
  515.                         { # marker might be at the end of the line
  516.                             if ($REQUEST.ContentType -match "boundary=(.*)$")
  517.                             { $BOUNDARY = "--" + $MATCHES[1] }
  518.                         }
  519.  
  520.                         if ($BOUNDARY)
  521.                         { # only if header separator was found
  522.  
  523.                             # read complete header (inkl. file data) into string
  524.                             $READER = New-Object System.IO.StreamReader($REQUEST.InputStream, $REQUEST.ContentEncoding)
  525.                             $DATA = $READER.ReadToEnd()
  526.                             $READER.Close()
  527.                             $REQUEST.InputStream.Close()
  528.  
  529.                             # variables for filenames
  530.                             $FILENAME = ""
  531.                             $SOURCENAME = ""
  532.  
  533.                             # separate headers by boundary string
  534.                             $DATA -replace "$BOUNDARY--\r\n", "$BOUNDARY`r`n--" -split "$BOUNDARY\r\n" | % {
  535.                                 # omit leading empty header and end marker header
  536.                                 if (($_ -ne "") -and ($_ -ne "--"))
  537.                                 {
  538.                                     # only if well defined header (seperation between meta data and data)
  539.                                     if ($_.IndexOf("`r`n`r`n") -gt 0)
  540.                                     {
  541.                                         # header data before two CRs is meta data
  542.                                         # first look for the file in header "filedata"
  543.                                         if ($_.Substring(0, $_.IndexOf("`r`n`r`n")) -match "Content-Disposition: form-data; name=(.*);")
  544.                                         {
  545.                                             $HEADERNAME = $MATCHES[1] -replace '\"'
  546.                                             # headername "filedata"?
  547.                                             if ($HEADERNAME -eq "filedata")
  548.                                             { # yes, look for source filename
  549.                                                 if ($_.Substring(0, $_.IndexOf("`r`n`r`n")) -match "filename=(.*)")
  550.                                                 { # source filename found
  551.                                                     $SOURCENAME = $MATCHES[1] -replace "`r`n$" -replace "`r$" -replace '\"'
  552.                                                     # store content of file in variable
  553.                                                     $FILEDATA = $_.Substring($_.IndexOf("`r`n`r`n") + 4) -replace "`r`n$"
  554.                                                 }
  555.                                             }
  556.                                         }
  557.                                         else
  558.                                         { # look for other headers (we need "filepath" to know where to store the file)
  559.                                             if ($_.Substring(0, $_.IndexOf("`r`n`r`n")) -match "Content-Disposition: form-data; name=(.*)")
  560.                                             { # header found
  561.                                                 $HEADERNAME = $MATCHES[1] -replace '\"'
  562.                                                 # headername "filepath"?
  563.                                                 if ($HEADERNAME -eq "filepath")
  564.                                                 { # yes, look for target filename
  565.                                                     $FILENAME = $_.Substring($_.IndexOf("`r`n`r`n") + 4) -replace "`r`n$" -replace "`r$" -replace '\"'
  566.                                                 }
  567.                                             }
  568.                                         }
  569.                                     }
  570.                                 }
  571.                             }
  572.  
  573.                             if ($FILENAME -ne "")
  574.                             { # upload only if a targetname is given
  575.                                 if ($SOURCENAME -ne "")
  576.                                 { # only upload if source file exists
  577.  
  578.                                     # check or construct a valid filename to store
  579.                                     $TARGETNAME = ""
  580.                                     # if filename is a container name, add source filename to it
  581.                                     if (Test-Path $FILENAME -PathType Container)
  582.                                     {
  583.                                         $TARGETNAME = Join-Path $FILENAME -ChildPath $(Split-Path $SOURCENAME -Leaf)
  584.                                     } else {
  585.                                         # try name in the header
  586.                                         $TARGETNAME = $FILENAME
  587.                                     }
  588.  
  589.                                     try {
  590.                                         # ... save file with the same encoding as received
  591.                                         [IO.File]::WriteAllText($TARGETNAME, $FILEDATA, $REQUEST.ContentEncoding)
  592.                                     }
  593.                                     catch   {}
  594.                                     if ($Error.Count -gt 0)
  595.                                     { # retrieve error message on error
  596.                                         $RESULT += "`nError saving '$TARGETNAME'`n`n"
  597.                                         $RESULT += $Error[0]
  598.                                         $Error.Clear()
  599.                                     }
  600.                                     else
  601.                                     { # success
  602.                                         $RESULT = "File $SOURCENAME successfully uploaded as $TARGETNAME"
  603.                                     }
  604.                                 }
  605.                                 else
  606.                                 {
  607.                                     $RESULT = "No file data received"
  608.                                 }
  609.                             }
  610.                             else
  611.                             {
  612.                                 $RESULT = "Missing target file name"
  613.                             }
  614.                         }
  615.                     }
  616.                 }
  617.                 else
  618.                 {
  619.                     $RESULT = "No client data received"
  620.                 }
  621.                 break
  622.             }
  623.  
  624.             "GET /log"
  625.             { # return the webserver log (stored in log variable)
  626.                 $RESULT = $WEBLOG
  627.                 break
  628.             }
  629.  
  630.             "GET /time"
  631.             { # return current time
  632.                 $RESULT = Get-Date -Format s
  633.                 break
  634.             }
  635.  
  636.             "GET /starttime"
  637.             { # return start time of the powershell webserver (already contained in $HTMLRESPONSE, nothing to do here)
  638.                 break
  639.             }
  640.  
  641.             "GET /beep"
  642.             { # Beep
  643.                 [CONSOLE]::beep(800, 300) # or "`a" or [char]7
  644.                 break
  645.             }
  646.  
  647.             "GET /quit"
  648.             { # stop powershell webserver, nothing to do here
  649.                 break
  650.             }
  651.  
  652.             "GET /exit"
  653.             { # stop powershell webserver, nothing to do here
  654.                 break
  655.             }
  656.  
  657.             default
  658.             {   # unknown command, check if path to file
  659.  
  660.                 # create physical path based upon the base dir and url
  661.                 $CHECKDIR = $BASEDIR.TrimEnd("/\") + $REQUEST.Url.LocalPath
  662.                 $CHECKFILE = ""
  663.                 if (Test-Path $CHECKDIR -PathType Container)
  664.                 { # physical path is a directory
  665.                     $IDXLIST = "/index.htm", "/index.html", "/default.htm", "/default.html"
  666.                     foreach ($IDXNAME in $IDXLIST)
  667.                     { # check if an index file is present
  668.                         $CHECKFILE = $CHECKDIR.TrimEnd("/\") + $IDXNAME
  669.                         if (Test-Path $CHECKFILE -PathType Leaf)
  670.                         { # index file found, path now in $CHECKFILE
  671.                             break
  672.                         }
  673.                         $CHECKFILE = ""
  674.                     }
  675.                 }
  676.                 else
  677.                     { # no directory, check for file
  678.                         if (Test-Path $CHECKDIR -PathType Leaf)
  679.                         { # file found, path now in $CHECKFILE
  680.                             $CHECKFILE = $CHECKDIR
  681.                         }
  682.                     }
  683.  
  684.                 if ($CHECKFILE -ne "")
  685.                 { # static content available
  686.                     try {
  687.                         # ... serve static content
  688.                         $BUFFER = [System.IO.File]::ReadAllBytes($CHECKFILE)
  689.                         $RESPONSE.ContentLength64 = $BUFFER.Length
  690.                         $RESPONSE.SendChunked = $FALSE
  691.                         $EXTENSION = [IO.Path]::GetExtension($CHECKFILE)
  692.                         if ($MIMEHASH.ContainsKey($EXTENSION))
  693.                         { # known mime type for this file's extension available
  694.                             $RESPONSE.ContentType = $MIMEHASH.Item($EXTENSION)
  695.                         }
  696.                         else
  697.                         { # no, serve as binary download
  698.                             $RESPONSE.ContentType = "application/octet-stream"
  699.                             $FILENAME = Split-Path -Leaf $CHECKFILE
  700.                             $RESPONSE.AddHeader("Content-Disposition", "attachment; filename=$FILENAME")
  701.                         }
  702.                         $RESPONSE.AddHeader("Last-Modified", [IO.File]::GetLastWriteTime($CHECKFILE).ToString('r'))
  703.                         $RESPONSE.AddHeader("Server", "Powershell Webserver/1.1 on ")
  704.                         $RESPONSE.OutputStream.Write($BUFFER, 0, $BUFFER.Length)
  705.                         # mark response as already given
  706.                         $RESPONSEWRITTEN = $TRUE
  707.                     }
  708.                     catch   {}
  709.                     if ($Error.Count -gt 0)
  710.                     { # retrieve error message on error
  711.                         $RESULT += "`nError while downloading '$CHECKFILE'`n`n"
  712.                         $RESULT += $Error[0]
  713.                         $Error.Clear()
  714.                     }
  715.                 }
  716.                 else
  717.                 {   # no file to serve found, return error
  718.                     $RESPONSE.StatusCode = 404
  719.                     $HTMLRESPONSE = '<html><body>Page not found</body></html>'
  720.                 }
  721.             }
  722.  
  723.         }
  724.  
  725.         # only send response if not already done
  726.         if (!$RESPONSEWRITTEN)
  727.         {
  728.             # insert header line string into HTML template
  729.             $HTMLRESPONSE = $HTMLRESPONSE -replace '!HEADERLINE', $HEADERLINE
  730.  
  731.             # insert result string into HTML template
  732.             $HTMLRESPONSE = $HTMLRESPONSE -replace '!RESULT', $RESULT
  733.  
  734.             # return HTML answer to caller
  735.             $BUFFER = [Text.Encoding]::UTF8.GetBytes($HTMLRESPONSE)
  736.             $RESPONSE.ContentLength64 = $BUFFER.Length
  737.             $RESPONSE.AddHeader("Last-Modified", [DATETIME]::Now.ToString('r'))
  738.             $RESPONSE.AddHeader("Server", "Powershell Webserver/1.1 on ")
  739.             $RESPONSE.OutputStream.Write($BUFFER, 0, $BUFFER.Length)
  740.         }
  741.  
  742.         # and finish answer to client
  743.         $RESPONSE.Close()
  744.  
  745.         # received command to stop webserver?
  746.         if ($RECEIVED -eq 'GET /exit' -or $RECEIVED -eq 'GET /quit')
  747.         { # then break out of while loop
  748.             "$(Get-Date -Format s) Stopping powershell webserver..."
  749.             break;
  750.         }
  751.     }
  752. }
  753. finally
  754. {
  755.     # Stop powershell webserver
  756.     $LISTENER.Stop()
  757.     $LISTENER.Close()
  758.     "$(Get-Date -Format s) Powershell webserver stopped."
  759. }
  760.  
  761.  
  762.     }#End of code block.
  763. $PSinstance = [powershell]::Create().AddScript($Code)
  764. $PSinstance.Runspace = $Runspace
  765. $job = $PSinstance.BeginInvoke()
  766.  
  767. }#End of WebServer Function
  768.  
  769. #Functions are here so I can cleanly put them into my button clicks for later.
  770. Function StartCaching {
  771. $syncHash.Host = $host
  772. $Runspace = [runspacefactory]::CreateRunspace()
  773. $Runspace.ApartmentState = "STA"
  774. $Runspace.ThreadOptions = "ReuseThread"
  775. $Runspace.Open()
  776. $Runspace.SessionStateProxy.SetVariable("syncHash",$syncHash)
  777.  
  778.  
  779. $code = {
  780.     #$syncHash.Window.Dispatcher.invoke([action]{})
  781.     $syncHash.TextBlock_SyncStatus.Dispatcher.invoke([action]{
  782.         If ((Get-Service -Name Server).Status -Eq "Running"){$syncHash.TextBlock_SyncStatus.text = "Halting any conflicting services."}
  783.         $syncHash.Rectangle_Status.Fill = "Red"
  784.     })
  785.     $syncHash.TextBlock_SyncStatus.Dispatcher.invoke([action]{
  786.         If ((Get-Service -Name Server).Status -Eq "Running") {Stop-Service Server}
  787.         Start-Sleep 1
  788.     })
  789.     $syncHash.TextBlock_SyncStatus.Dispatcher.invoke([action]{
  790.         $syncHash.TextBlock_SyncStatus.text = "Syncing Files"
  791.         $syncHash.Rectangle_Status.Fill = "Yellow"
  792.     })
  793.  
  794.     #Image Dependancies
  795.     robocopy "\\sadmzpr04.admin.com\Wim\OEM" "C:\Wim\OEM" /MIR /R:0 /w:0
  796.     robocopy "\\sadmzpr04.admin.com\Wim\Images" "C:\Wim\Images" /MIR /R:0 /w:0
  797.     robocopy "\\sadmzpr04.admin.com\Production Base Apps\Production" "C:\Production Base Apps\Production" /MIR /R:0 /w:0
  798.     #Drivers
  799.     robocopy "\\sadmzpr04.admin.com\Wim\Drivers\Windows10\HPStreamG2" "C:\Wim\Drivers\Windows10\HPStreamG2" /MIR /R:0 /w:0
  800.     robocopy "\\sadmzpr04.admin.com\Wim\Drivers\Windows10\HPStreamG3" "C:\Wim\Drivers\Windows10\HPStreamG3" /MIR /R:0 /w:0
  801.     robocopy "\\sadmzpr04.admin.com\Wim\Drivers\Windows10\DellLatitude3390" "C:\Wim\Drivers\Windows10\DellLatitude3390" /MIR /R:0 /w:0
  802.     robocopy "\\sadmzpr04.admin.com\Wim\Drivers\Windows10\HPProBook640G3" "C:\Wim\Drivers\Windows10\HPProBook640G3" /MIR /R:0 /w:0
  803.     robocopy "\\sadmzpr04.admin.com\Wim\Drivers\Windows10\HPProbook645G2" "C:\Wim\Drivers\Windows10\HPProbook645G2" /MIR /R:0 /w:0
  804.     robocopy "\\sadmzpr04.admin.com\Wim\Drivers\Windows10\HPProbook645G2" "C:\Wim\Drivers\Windows10\HPProbook645G2" /MIR /R:0 /w:0
  805.     robocopy "\\sadmzpr04.admin.com\Wim\Drivers\Windows10\HPProBook11G2" "C:\Wim\Drivers\Windows10\HPProBook11G2" /MIR /R:0 /w:0
  806.     robocopy "\\sadmzpr04.admin.com\Wim\Drivers\Windows10\DellLatitude3189" "C:\Wim\Drivers\Windows10\DellLatitude3189" /MIR /R:0 /w:0  
  807.  
  808.     $syncHash.TextBlock_SyncStatus.Dispatcher.invoke([action]{
  809.         $syncHash.TextBlock_SyncStatus.text = "Syncronization complete, starting Satelite Server Services."
  810.     })
  811.  
  812.         Start-Service Server
  813.         Start-Sleep 4
  814.  
  815.         If ((Get-Service -Name Server).Status -Eq "Running"){
  816.             $syncHash.TextBlock_SyncStatus.Dispatcher.invoke([action]{
  817.                 $syncHash.TextBlock_SyncStatus.text = "Services started sucessfully. This device is now a functioning imaging caching device."
  818.                 })
  819.                 $syncHash.Rectangle_Status.Dispatcher.invoke([action]{
  820.                     $syncHash.Rectangle_Status.Fill = "Green"
  821.                 })
  822.          
  823.         }
  824.         ElseIf ((Get-Service -Name Server).Status -Ne "Running"){
  825.             $syncHash.TextBlock_SyncStatus.Dispatcher.invoke([action]{
  826.                 $syncHash.TextBlock_SyncStatus.text = "I have no idea what went wrong, but I couldn't start the server services.";
  827.             })
  828.             $syncHash.Rectangle_Status.Dispatcher.invoke([action]{
  829.                 $syncHash.Rectangle_Status.Fill = "Red"
  830.             })
  831.         }
  832.         Else {
  833.             $syncHash.TextBlock_SyncStatus.Dispatcher.invoke([action]{
  834.             $syncHash.TextBlock_SyncStatus.text = "The satelite services could not be started. This machine is not currently working as a caching device."
  835.         })
  836.         $syncHash.Rectangle_Status.Dispatcher.invoke([action]{
  837.             $syncHash.Rectangle_Status.Fill = "Red"
  838.         })
  839.         }
  840.    
  841. }#end of code block.
  842. $PSinstance = [powershell]::Create().AddScript($Code)
  843. $PSinstance.Runspace = $Runspace
  844. $job = $PSinstance.BeginInvoke()
  845. }
  846.  
  847.  
  848. Function ShutDown {
  849.     $syncHash.Host = $host
  850.     $Runspace = [runspacefactory]::CreateRunspace()
  851.     $Runspace.ApartmentState = "STA"
  852.     $Runspace.ThreadOptions = "ReuseThread"
  853.     $Runspace.Open()
  854.     $Runspace.SessionStateProxy.SetVariable("syncHash",$syncHash)
  855.    
  856.    
  857.     $code = {
  858.         #$syncHash.Window.Dispatcher.invoke([action]{})
  859.         $syncHash.Window.Dispatcher.invoke([action]{
  860.             taskkill /im powershell.exe /f
  861.         })
  862.     }
  863.     $PSinstance = [powershell]::Create().AddScript($Code)
  864.     $PSinstance.Runspace = $Runspace
  865.     $job = $PSinstance.BeginInvoke()
  866.     }
  867.  
  868.  Function CountConnections {
  869.  
  870. $runspace = [runspacefactory]::CreateRunspace()
  871. $powerShell = [powershell]::Create()
  872. $powerShell.runspace = $runspace
  873. $runspace.Open()
  874. $runspace.SessionStateProxy.SetVariable("syncHash",$syncHash)
  875.  
  876.  
  877. $code = {
  878.     Improt-Module SMBShare
  879.     Do {
  880.     $smb = Get-SMBSession | Where-Object {$_.ClientComputerName -Like "10.*"}
  881.     $Global:SessionCount = ($smb.clientcomputername).count
  882.     #Check if the variable is NULL.
  883.     IF (!($Global:SessionCount)) {$Global:SessionCount = "0"}
  884.     #Change content of TextBlock to the active number of connections
  885.     $syncHash.TextBlock_ActiveConnections.Dispatcher.invoke([action]{
  886.         $syncHash.TextBlock_ActiveConnections.Text = "Number of clients connected:
  887.        $Global:SessionCount (Maximum of 20)"
  888.     })
  889.     Start-Sleep3
  890.     }Until ($Stop -eq "2")
  891. }
  892. $PSinstance = [powershell]::Create().AddScript($Code)
  893. $PSinstance.Runspace = $Runspace
  894. $job = $PSinstance.BeginInvoke()
  895.     }
  896.  
  897. #########################Map WPF controls into variable contained int he hash tables.
  898.  
  899. #Easy copy and paste template for future mappings.
  900. #$syncHash. = $syncHash.Window.FindName("")
  901. #Buttons
  902. $syncHash.Button_ShutDown = $syncHash.Window.FindName("Button_ShutDown")
  903. $syncHash.Button_StartCachingServices = $syncHash.Window.FindName("Button_StartCachingServices")
  904. $syncHash.CountSessions = $syncHash.Window.FindName("CountSessions")
  905.  
  906. #TextBlocks
  907. $syncHash.TextBlock_SyncStatus = $syncHash.Window.FindName("TextBlock_SyncStatus")
  908. $syncHash.TextBlock_ActiveConnections = $syncHash.Window.FindName("TextBlock_ActiveConnections")
  909.  
  910. #Rectangles
  911. $syncHash.Rectangle_Status = $syncHash.Window.FindName("Rectangle_Status")
  912.  
  913. #Button Click Actions.
  914. $syncHash.Button_ShutDown.Add_Click({ShutDown})
  915. $syncHash.Button_StartCachingServices.Add_Click({
  916.     StartCaching
  917.  
  918.     WebServer
  919. })
  920. $syncHash.CountSessions.Add_Click({CountConnections})
  921.  
  922.  
  923. #Launch GUI
  924. $syncHash.Window.ShowDialog()
  925. $Runspace.Close()
  926. $Runspace.Dispose()
  927.  
  928.  
  929.  
  930.  
  931. }
  932.  
  933. $PSinstance1 = [powershell]::Create().AddScript($Code)
  934. $PSinstance1.Runspace = $Runspace
  935. $job = $PSinstance1.BeginInvoke()
  936.  
  937.  
  938.  
  939. Start-Sleep 10
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement