Загрузка данных
$ErrorActionPreference = 'Stop'
$port = 8765
$ruleName = 'TEMP_Report_Share_8765'
$desktop = [Environment]::GetFolderPath('Desktop')
$reportNames = @('NETWORK_DIAG.txt', 'NETWORK_WFP_STATE.xml')
$isAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(
[Security.Principal.WindowsBuiltInRole]::Administrator
)
if (-not $isAdmin) {
$arguments = "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`""
Start-Process powershell.exe -Verb RunAs -ArgumentList $arguments
exit
}
$availableFiles = @{}
foreach ($name in $reportNames) {
$path = Join-Path $desktop $name
if (Test-Path -LiteralPath $path -PathType Leaf) {
$availableFiles[$name] = $path
}
}
if ($availableFiles.Count -eq 0) {
Write-Host 'No report files were found on the Desktop.' -ForegroundColor Red
Write-Host 'Expected: NETWORK_DIAG.txt or NETWORK_WFP_STATE.xml'
Read-Host 'Press Enter to close'
exit 1
}
function Send-Bytes {
param(
[Parameter(Mandatory)] $Context,
[Parameter(Mandatory)] [byte[]] $Bytes,
[Parameter(Mandatory)] [string] $ContentType,
[string] $DownloadName
)
$Context.Response.StatusCode = 200
$Context.Response.ContentType = $ContentType
$Context.Response.ContentLength64 = $Bytes.Length
$Context.Response.Headers.Add('Cache-Control', 'no-store')
if ($DownloadName) {
$Context.Response.Headers.Add('Content-Disposition', "attachment; filename=`"$DownloadName`"")
}
$Context.Response.OutputStream.Write($Bytes, 0, $Bytes.Length)
$Context.Response.OutputStream.Close()
}
function Send-Text {
param(
[Parameter(Mandatory)] $Context,
[Parameter(Mandatory)] [string] $Text,
[string] $ContentType = 'text/html; charset=utf-8',
[int] $StatusCode = 200
)
$bytes = [Text.Encoding]::UTF8.GetBytes($Text)
$Context.Response.StatusCode = $StatusCode
$Context.Response.ContentType = $ContentType
$Context.Response.ContentLength64 = $bytes.Length
$Context.Response.Headers.Add('Cache-Control', 'no-store')
$Context.Response.OutputStream.Write($bytes, 0, $bytes.Length)
$Context.Response.OutputStream.Close()
}
$links = foreach ($name in $reportNames) {
if ($availableFiles.ContainsKey($name)) {
$size = (Get-Item -LiteralPath $availableFiles[$name]).Length
"<p><a class='button' href='/$name'>Download $name</a><br><small>$size bytes</small></p>"
}
}
$indexHtml = @"
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Windows reports</title>
<style>
body{font-family:-apple-system,system-ui,sans-serif;max-width:650px;margin:40px auto;padding:0 20px;background:#f5f5f7;color:#111}
.card{background:white;border-radius:18px;padding:24px;box-shadow:0 4px 24px #0001}
.button{display:inline-block;background:#1677ff;color:white;padding:13px 17px;border-radius:11px;text-decoration:none;font-weight:600}
.stop{color:#b00020} small{color:#666}
</style>
</head>
<body><div class="card">
<h2>Windows diagnostic reports</h2>
<p>Tap a button to save the file on the iPhone.</p>
$($links -join "`n")
<hr>
<p><a class="stop" href="/stop">Stop server and close access</a></p>
</div></body></html>
"@
$listener = [Net.HttpListener]::new()
$listener.Prefixes.Add("http://+:$port/")
try {
& netsh advfirewall firewall delete rule name="$ruleName" | Out-Null
& netsh advfirewall firewall add rule name="$ruleName" dir=in action=allow protocol=TCP localport=$port profile=any | Out-Null
$listener.Start()
$addresses = Get-NetIPConfiguration -ErrorAction SilentlyContinue |
Where-Object { $_.IPv4DefaultGateway -and $_.NetAdapter.Status -eq 'Up' } |
ForEach-Object { $_.IPv4Address.IPAddress } |
Where-Object { $_ -and $_ -notlike '169.254.*' } |
Select-Object -Unique
Clear-Host
Write-Host 'LOCAL FILE SERVER IS RUNNING' -ForegroundColor Green
Write-Host 'Connect the iPhone to the same Wi-Fi network.'
Write-Host 'Open one of these addresses in Safari:' -ForegroundColor Cyan
foreach ($address in $addresses) {
Write-Host " http://${address}:$port/" -ForegroundColor Yellow
}
Write-Host ''
Write-Host 'After downloading, tap Stop server on the web page.'
Write-Host 'You can also stop it with Ctrl+C.'
while ($listener.IsListening) {
$context = $listener.GetContext()
$requestPath = [Uri]::UnescapeDataString($context.Request.Url.AbsolutePath.TrimStart('/'))
if ([string]::IsNullOrWhiteSpace($requestPath)) {
Send-Text -Context $context -Text $indexHtml
continue
}
if ($requestPath -eq 'stop') {
Send-Text -Context $context -Text '<h2>Server stopped. The files are no longer shared.</h2>'
$listener.Stop()
break
}
if ($availableFiles.ContainsKey($requestPath)) {
$bytes = [IO.File]::ReadAllBytes($availableFiles[$requestPath])
$contentType = if ($requestPath.EndsWith('.xml')) { 'application/xml' } else { 'text/plain; charset=utf-8' }
Send-Bytes -Context $context -Bytes $bytes -ContentType $contentType -DownloadName $requestPath
Write-Host "Downloaded: $requestPath" -ForegroundColor Green
continue
}
Send-Text -Context $context -Text 'Not found' -ContentType 'text/plain; charset=utf-8' -StatusCode 404
}
}
catch {
Write-Host ''
Write-Host "ERROR: $($_.Exception.Message)" -ForegroundColor Red
Read-Host 'Press Enter to close'
}
finally {
if ($listener.IsListening) {
$listener.Stop()
}
$listener.Close()
& netsh advfirewall firewall delete rule name="$ruleName" | Out-Null
Write-Host 'Server stopped and temporary firewall rule removed.' -ForegroundColor Cyan
}