Skip to content

Instantly share code, notes, and snippets.

@timsonner
Last active February 1, 2025 23:00
Show Gist options
  • Select an option

  • Save timsonner/8854dec55fc9ad3cc82553843aec79b5 to your computer and use it in GitHub Desktop.

Select an option

Save timsonner/8854dec55fc9ad3cc82553843aec79b5 to your computer and use it in GitHub Desktop.
Fileserver in PowerShell. Rough equivalent of python3 -m http.server...

PowerShell HTTP fileserver

Kick hole in firewall

New-NetFirewallRule -DisplayName "Open Port 8081" -Direction Inbound -Protocol TCP -LocalPort 8081 -Action Allow

PowerShell 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()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment