Kick hole in firewall
New-NetFirewallRule -DisplayName "Open Port 8081" -Direction Inbound -Protocol TCP -LocalPort 8081 -Action AllowPowerShell Http Server
# Define the directory to serve
$directoryToServe = Get-Location
# Create a new HttpListener object
$httpListener = New-Object System.Net.HttpListener
# Add a prefix to listen on localhost:8081
$httpListener.Prefixes.Add("http://+:8081/")
# Start the listener
$httpListener.Start()
Write-Output "File server started at http://localhost:8081/"
# Function to generate directory listing
function Get-DirectoryListingHtml {
param ($directoryPath)
$html = @"
<!DOCTYPE html>
<html>
<head>
<title>Directory Listing</title>
<style>
table {
width: 100%;
border-collapse: collapse;
}
th, td {
border: 1px solid black;
padding: 8px;
text-align: left;
}
th {
background-color: #f2f2f2;
}
</style>
</head>
<body>
<h1>Directory Listing for $directoryPath</h1>
<table>
<tr>
<th>File Name</th>
<th>Size (bytes)</th>
<th>Last Modified</th>
</tr>
"@
$files = Get-ChildItem -Path $directoryPath
foreach ($file in $files) {
$fileName = $file.Name
$fileSize = $file.Length
$lastModified = $file.LastWriteTime
$html += "<tr><td><a href='/$fileName'>$fileName</a></td><td>$fileSize</td><td>$lastModified</td></tr>"
}
$html += @"
</table>
</body>
</html>
"@
return $html
}
# Infinite loop to handle requests
while ($httpListener.IsListening) {
$context = $httpListener.GetContext()
$request = $context.Request
$response = $context.Response
$filePath = Join-Path -Path $directoryToServe -ChildPath $request.Url.LocalPath.TrimStart('/')
if ($request.Url.LocalPath -eq "/") {
# Serve directory listing
$directoryListingHtml = Get-DirectoryListingHtml -directoryPath $directoryToServe
$buffer = [System.Text.Encoding]::UTF8.GetBytes($directoryListingHtml)
$response.ContentType = "text/html"
$response.OutputStream.Write($buffer, 0, $buffer.Length)
} elseif (Test-Path -Path $filePath -PathType Leaf) {
# Serve the requested file
$fileBytes = [System.IO.File]::ReadAllBytes($filePath)
$response.ContentType = "application/octet-stream"
$response.StatusCode = 200
$response.OutputStream.Write($fileBytes, 0, $fileBytes.Length)
} else {
# Return 404 if file not found
$response.StatusCode = 404
$errorBytes = [System.Text.Encoding]::UTF8.GetBytes("File not found")
$response.OutputStream.Write($errorBytes, 0, $errorBytes.Length)
}
$response.Close()
}