Skip to content

Instantly share code, notes, and snippets.

@Sonic853
Last active January 6, 2021 02:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Sonic853/50a2001a9aee47bf280ff5c3430c9ea2 to your computer and use it in GitHub Desktop.
Save Sonic853/50a2001a9aee47bf280ff5c3430c9ea2 to your computer and use it in GitHub Desktop.
Simple web server built with PowerShell.
# This is a super **SIMPLE** example of how to create a very basic powershell webserver
# 2019-05-18 UPDATE — Created by @19WAS85 and and evalued by @jakobii and the comunity.
# 2021-01-05 UPDATE — Edited by @Sonic853.
param(
$ip = "localhost",
$Port = 8080,
$parentPath = [IO.Path]::Combine([IO.Path]::GetDirectoryName($MyInvocation.MyCommand.Path), "web")
)
# Http Server
$http = [System.Net.HttpListener]::new()
$DefaultPage = , 'index.html', 'index.htm'
$PSV = $PSVersionTable.PSVersion.ToString()
# Hostname and port to listen on
$http.Prefixes.Add("http://" + $ip + ":$Port/")
# Start the Http Server
$http.Start()
# Log ready message to terminal
if ($http.IsListening) {
write-host " HTTP Server Ready! " -f 'black' -b 'gre'
write-host "now try going to $($http.Prefixes)" -f 'y'
# write-host "then try going to $($http.Prefixes)other/path" -f 'y'
}
# INFINTE LOOP
# Used to listen for requests
while ($http.IsListening) {
# Get Request Url
# When a request is made in a web browser the GetContext() method will return a request object
# Our route examples below will use the request object properties to decide how to respond
$context = $http.GetContext()
# $url = $context.Request.RawUrl
# $h = $context.Request.Url.Host
# $path = $url.TrimStart('/').split("?")[0]
$path = $context.Request.Url.AbsolutePath.TrimStart('/')
if ($context.Request.HttpMethod -eq 'GET') {
# We can log the request to the terminal
write-host "$($context.Request.UserHostAddress) => $($context.Request.Url)" -f 'mag'
# if ($path -eq "exit") {
# [string]$html = "bye!"
# $buffer = [System.Text.Encoding]::UTF8.GetBytes($html)
# $context.Response.AddHeader("Server", "PowerShell " + $PSV)
# $context.Response.ContentLength64 = $buffer.Length
# $context.Response.OutputStream.Write($buffer, 0, $buffer.Length) #stream to broswer
# $context.Response.OutputStream.Close() # close the response
# break
# }
if ([IO.File]::Exists([IO.Path]::Combine($parentPath, $path))) {
$fullPath = [IO.Path]::Combine($parentPath, $path)
}
else {
$fullPath = ""
for ($i = 0; $i -lt $DefaultPage.Count; $i++) {
$fullPath = [IO.Path]::Combine($parentPath, $path, $DefaultPage[$i])
if ([IO.File]::Exists($fullPath)) {
break
}
}
}
# the html/data you want to send to the browser
if ([IO.File]::Exists($fullPath)) {
[string]$html = Get-Content $fullPath -Raw
}
else {
$context.Response.StatusCode = 404
[string]$html = "<h1>404 - File Not Found</h1><address>Powershell/$PSV Server at $ip Port $Port</address>"
}
#resposed to the request
try {
$buffer = [System.Text.Encoding]::UTF8.GetBytes($html) # convert htmtl to bytes
}
catch {
$buffer = [System.Text.Encoding]::UTF8.GetBytes(" ")
}
$context.Response.AddHeader("Server", "PowerShell " + $PSV)
$context.Response.ContentLength64 = $buffer.Length
$context.Response.OutputStream.Write($buffer, 0, $buffer.Length) #stream to broswer
$context.Response.OutputStream.Close() # close the response
}
}
$http.Stop()
# Note:
# To end the loop you have to kill the powershell terminal. ctrl-c wont work :/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment