Перший робить усе з нуля: перемикає профіль мережі, вмикає правило брандмауера, створює ресурс і роздає дозволи NTFS. Другий нічого не змінює — перевіряє шість типових причин «доступ заборонено» і друкує, що саме виправити. Обидва перевірені на Windows 11 Pro 26200.
Запускати від імені адміністратора. Без цих прав скрипт зупиниться сам і нічого не змінить.
# Налаштування спільної папки з нуля: профіль мережі, брандмауер,
# спільний ресурс і дозволи NTFS. Запускати в PowerShell ВІД ІМЕНІ АДМІНІСТРАТОРА.
#
# Приклад:
# .\Set-SharedFolder.ps1 -Path "D:\Shared\Documents" -ShareName "Documents"
#
# Права даються локальній групі «Користувачі» (SID S-1-5-32-545) — вона є
# в будь-якій локалізації Windows. Щоб роздати вужче, підставте свою групу
# в параметр -GroupSid.
param(
[Parameter(Mandatory = $true)] [string] $Path,
[Parameter(Mandatory = $true)] [string] $ShareName,
[string] $GroupSid = 'S-1-5-32-545',
[ValidateSet('Read', 'Change')] [string] $Access = 'Change'
)
$ErrorActionPreference = 'Stop'
# 0. Права адміністратора — без них не створити ні ресурс, ні правило
$isAdmin = ([Security.Principal.WindowsPrincipal] `
[Security.Principal.WindowsIdentity]::GetCurrent()
).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
if (-not $isAdmin) {
Write-Host 'Потрібні права адміністратора. Запустіть PowerShell від імені адміністратора.' -ForegroundColor Red
exit 1
}
# 1. Профіль мережі: на загальнодоступній вхідні підключення заблоковані
Get-NetConnectionProfile | Where-Object { $_.NetworkCategory -eq 'Public' } | ForEach-Object {
Write-Host "Мережу «$($_.Name)» перемикаю на Private" -ForegroundColor Cyan
Set-NetConnectionProfile -InterfaceIndex $_.InterfaceIndex -NetworkCategory Private
}
# 2. Брандмауер: вмикаємо правило за внутрішнім іменем, а не за назвою —
# назви перекладені мовою системи, імена однакові скрізь
foreach ($rule in 'FPS-SMB-In-TCP', 'FPS-NB_Session-In-TCP') {
$r = Get-NetFirewallRule -Name $rule -ErrorAction SilentlyContinue
# Enabled — enum, де False дорівнює 2, тож [bool] завжди дав би True
if ($r -and $r.Enabled -ne 'True') {
Enable-NetFirewallRule -Name $rule
Write-Host "Правило брандмауера $rule увімкнено" -ForegroundColor Cyan
}
}
# 3. Тека
if (-not (Test-Path $Path)) {
New-Item -ItemType Directory -Path $Path -Force | Out-Null
Write-Host "Створено теку $Path" -ForegroundColor Cyan
}
# 4. Спільний ресурс. Широкі права на рівні ресурсу, точне розмежування — у NTFS
if (Get-SmbShare -Name $ShareName -ErrorAction SilentlyContinue) {
Write-Host "Ресурс $ShareName уже існує — лишаю як є" -ForegroundColor Yellow
} else {
New-SmbShare -Name $ShareName -Path $Path -FullAccess 'Everyone' | Out-Null
Write-Host "Створено спільний ресурс $ShareName" -ForegroundColor Cyan
}
# 5. Дозволи NTFS для групи за SID
$rights = if ($Access -eq 'Read') { 'RX' } else { 'M' }
icacls $Path /grant "*${GroupSid}:(OI)(CI)$rights" | Out-Null
Write-Host "Дозволи NTFS ($Access) видані групі $GroupSid" -ForegroundColor Cyan
# 6. Служба, яка публікує комп’ютер у розділі «Мережа»
$svc = Get-Service FDResPub -ErrorAction SilentlyContinue
if ($svc -and $svc.Status -ne 'Running') {
Set-Service FDResPub -StartupType Automatic
Start-Service FDResPub
Write-Host 'Службу публікації в мережі увімкнено' -ForegroundColor Cyan
}
Write-Host ''
Write-Host 'Готово. Шлях для колег:' -ForegroundColor Green
Write-Host (" \\{0}\{1}" -f $env:COMPUTERNAME, $ShareName) -ForegroundColor Green
Write-Host ''
Write-Host 'Перевірте права:' -ForegroundColor DarkGray
Get-SmbShareAccess -Name $ShareName | Format-Table AccountName, AccessRight -AutoSize
icacls $Path
.\Set-SharedFolder.ps1 -Path "D:\Shared\Documents" -ShareName "Documents" -Access Change
Тільки читає. Можна запускати і без прав адміністратора — частина перевірок тоді буде неповною.
# Діагностика спільної папки: перевіряє шість причин «доступ заборонено».
# Нічого не змінює — тільки читає. Запускати можна без прав адміністратора,
# але частина перевірок тоді буде неповною.
$ErrorActionPreference = 'SilentlyContinue'
$issues = @()
function Show([string]$name, [bool]$ok, [string]$detail) {
$mark = if ($ok) { ' OK ' } else { ' УВАГА' }
Write-Host ("[{0}] {1}" -f $mark, $name) -ForegroundColor $(if ($ok) { 'Green' } else { 'Yellow' })
if ($detail) { Write-Host (" {0}" -f $detail) -ForegroundColor DarkGray }
}
Write-Host "`n=== Діагностика спільного доступу ===`n" -ForegroundColor Cyan
# 1. Профіль мережі: на загальнодоступній Windows блокує вхідні підключення
$profiles = Get-NetConnectionProfile
foreach ($p in $profiles) {
$ok = $p.NetworkCategory -ne 'Public'
Show "Профіль мережі «$($p.Name)»" $ok "категорія: $($p.NetworkCategory)"
if (-not $ok) { $issues += "Мережу «$($p.Name)» перемкнути на Private" }
}
# 2. Правило брандмауера для файлового доступу
$fw = Get-NetFirewallRule -Name 'FPS-SMB-In-TCP'
if ($fw) {
# Enabled — це enum, де False дорівнює 2, тож [bool] дав би True завжди.
# Порівнюємо з рядком: єдиний надійний спосіб.
$ok = ($fw.Enabled -eq 'True')
Show 'Брандмауер: спільний доступ до файлів' $ok "правило FPS-SMB-In-TCP: $($fw.Enabled)"
if (-not $ok) { $issues += 'Enable-NetFirewallRule -Name "FPS-SMB-In-TCP"' }
} else {
Show 'Брандмауер: спільний доступ до файлів' $false 'правило FPS-SMB-In-TCP не знайдено'
}
# 3. Служба, яка публікує комп’ютер у розділі «Мережа»
$svc = Get-Service FDResPub
if ($svc) {
$ok = $svc.Status -eq 'Running'
Show 'Служба публікації в мережі (FDResPub)' $ok "стан: $($svc.Status), запуск: $($svc.StartType)"
if (-not $ok) { $issues += 'Set-Service FDResPub -StartupType Automatic -Status Running' }
}
# 4. Порожні паролі: обліковий запис без пароля мережею не пустить
$lbp = (Get-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\Lsa' -Name LimitBlankPasswordUse).LimitBlankPasswordUse
Show 'Порожні паролі заборонені мережею' $true "LimitBlankPasswordUse = $lbp (1 — заборонено, це типово)"
if ($lbp -eq 1) { $issues += 'Перевірити, що в облікового запису для доступу заданий пароль' }
# 5. Що змінилось у 24H2: підпис SMB і гостьовий доступ
$cli = Get-SmbClientConfiguration
$srv = Get-SmbServerConfiguration
Show 'Підпис SMB (клієнт/сервер)' $true "RequireSecuritySignature: $($cli.RequireSecuritySignature) / $($srv.RequireSecuritySignature)"
Show 'Гостьовий доступ' $true "EnableInsecureGuestLogons: $($cli.EnableInsecureGuestLogons) — для старих NAS доведеться завести обліковий запис"
Show 'SMB 1 вимкнений' (-not $srv.EnableSMB1Protocol) "EnableSMB1Protocol: $($srv.EnableSMB1Protocol)"
# 6. Самі ресурси та права на них
$shares = Get-SmbShare | Where-Object { $_.Name -notlike '*$' }
if (-not $shares) {
Show 'Спільні ресурси' $false 'власних спільних ресурсів немає (лише службові з $)'
} else {
foreach ($s in $shares) {
Write-Host "`n--- Ресурс: $($s.Name) → $($s.Path) ---" -ForegroundColor Cyan
Get-SmbShareAccess -Name $s.Name | Format-Table AccountName, AccessRight, AccessControlType -AutoSize | Out-String | Write-Host
Write-Host ' Дозволи NTFS:' -ForegroundColor DarkGray
icacls $s.Path | ForEach-Object { Write-Host " $_" -ForegroundColor DarkGray }
}
}
Write-Host "`n=== Підсумок ===" -ForegroundColor Cyan
if ($issues) {
Write-Host 'Перевірте по черзі:' -ForegroundColor Yellow
$issues | ForEach-Object { Write-Host " - $_" }
} else {
Write-Host 'Явних причин «доступ заборонено» не знайдено.' -ForegroundColor Green
}
Write-Host ''
powershell -ExecutionPolicy Bypass -File .\Test-SharedFolder.ps1.
Це не змінює налаштування системи.
Get-NetFirewallRule
властивість Enabled — це перелічення, де False дорівнює 2, тому
[bool]$rule.Enabled завжди дає True. Порівнюйте з рядком:
$rule.Enabled -eq 'True'.