본문 바로가기
걸어서 개발 속으로

SMB 사용,후 흔적 원복, 검증 스크립트

by puy0 2026. 6. 9.

+ 새로운 계정을 만들지 않고 기존 계정을 사용하는 방식으로 수정함.

 

SMB를 열고 사용 후 사용흔적을 제거해서 다른 작업에 간섭이나 충돌이 없도록 하는것이 목적이다

여는법, 정상 종료후 흔적 제거, 마지막으로 흔적 검토까지 총 3개의 스크립트를 공유 한다

 

시스템은 사람과 환경마다 다양하기에 부주의에 의한 손해는 당연히 내가 책임지지 않는다

그럼에도 우리의 작업에 참고가 될 수 있기에 공유함.

해당 스크립트는 AI를 사용했다

 

나의 경우약 1n0기가의 VM백업 파일을 우분투24에서 윈11pro로 이동 해야 한다

같은 네트워크에 있으며 보유중인 파일시스템을 사용시 서버 업로드, PC로다운로드 과정으로 적합하지 않다

윈PC를 SMB호스트로 둬서 한번에 대용량 파일 이동을 진행 하는 스크립트를 공유한다

 

각 작업당 주석이 있으며 실행시 출력으로 직접적인 확인이 가능하다

원상복구 전 SMB로 작업한 파일들을 이동하지 않으면 공유폴더가 정리되면서 같이 손실 된다

원상복구 스크립트를 돌렸다 해도 검증 스크립트로 확인 하는것을 권장한다

 

 

SMB 열기

 

# ==========================================================
# Simple Temporary SMB Open Script
# 목적:
# - 현재 Windows 로그인 계정을 사용하여 임시 SMB 공유를 생성한다.
# - 새 로컬 계정은 만들지 않는다.
# - 새 firewall rule은 만들지 않는다.
# - Windows 기본 SMB-In rule만 Private profile에서 활성화한다.
# - 기본 경로가 있는 현재 네트워크 인터페이스만 Private으로 설정한다.
# - SMBv1은 비활성화 상태로 유지한다.
# ==========================================================

$ShareName = "SMBUpload"
$SharePath = "C:\SMBUpload"

# 특정 인터페이스를 직접 지정하려면 예: "Wi-Fi", "Ethernet", "이더넷"
# 비워두면 기본 gateway가 있는 인터페이스를 자동 선택한다.
$TargetInterfaceAlias = ""

function OK($m)   { Write-Host "[OK]   $m" -ForegroundColor Green }
function FAIL($m) { Write-Host "[FAIL] $m" -ForegroundColor Red }
function SKIP($m) { Write-Host "[SKIP] $m" -ForegroundColor Yellow }
function INFO($m) { Write-Host "[INFO] $m" -ForegroundColor Cyan }

function STEP($name, $block) {
    try {
        & $block
        OK $name
    }
    catch {
        FAIL "$name - $($_.Exception.Message)"
        exit 1
    }
}

function IsTcp445Rule($rule) {
    try {
        $pf = $rule | Get-NetFirewallPortFilter
        if ($pf.Protocol -ne "TCP") { return $false }
        return (@($pf.LocalPort) -contains "445")
    }
    catch {
        return $false
    }
}

function IsDefaultSmbInRule($rule) {
    return (
        $rule.DisplayName -like "*SMB-In*" -or
        $rule.DisplayName -like "*파일 및 프린터 공유*SMB*" -or
        $rule.DisplayName -like "*File and Printer Sharing*SMB*"
    )
}

Write-Host ""
Write-Host "========== Simple Temporary SMB Open ==========" -ForegroundColor Cyan

# 관리자 권한 확인
$isAdmin = ([Security.Principal.WindowsPrincipal] `
    [Security.Principal.WindowsIdentity]::GetCurrent()
).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)

if (-not $isAdmin) {
    FAIL "관리자 권한 PowerShell이 아님"
    exit 1
}
else {
    OK "관리자 권한 확인"
}

# 현재 PowerShell 실행 계정 확인
$CurrentAccount = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name

if ([string]::IsNullOrWhiteSpace($CurrentAccount)) {
    FAIL "현재 Windows 계정 확인 실패"
    exit 1
}

OK "사용 계정: $CurrentAccount"

# SMB 접속에는 Windows 계정 비밀번호가 필요하다. PIN은 SMB 인증 비밀번호가 아니다.
INFO "SMB 접속 시 사용할 계정: $CurrentAccount"

# 대상 네트워크 인터페이스 선택
if ([string]::IsNullOrWhiteSpace($TargetInterfaceAlias)) {
    $defaultRoute = Get-NetRoute -DestinationPrefix "0.0.0.0/0" |
        Sort-Object RouteMetric, InterfaceMetric |
        Select-Object -First 1

    if (-not $defaultRoute) {
        FAIL "기본 gateway route를 찾지 못함"
        exit 1
    }

    $TargetInterfaceAlias = (Get-NetAdapter -InterfaceIndex $defaultRoute.InterfaceIndex).Name
}

$targetNet = Get-NetIPConfiguration -InterfaceAlias $TargetInterfaceAlias -ErrorAction SilentlyContinue

if (-not $targetNet) {
    FAIL "대상 인터페이스 확인 실패: $TargetInterfaceAlias"
    exit 1
}

$TargetIp = $targetNet.IPv4Address.IPAddress
$TargetPrefix = $targetNet.IPv4Address.PrefixLength
$TargetGateway = $targetNet.IPv4DefaultGateway.NextHop

if (-not $TargetIp -or -not $TargetGateway) {
    FAIL "대상 인터페이스에 IPv4 또는 Gateway가 없음: $TargetInterfaceAlias"
    exit 1
}

OK "대상 인터페이스: $TargetInterfaceAlias"
OK "대상 IP: $TargetIp/$TargetPrefix, Gateway $TargetGateway"

# 대상 네트워크만 Private으로 설정
STEP "대상 네트워크 Private 설정" {
    Set-NetConnectionProfile `
        -InterfaceAlias $TargetInterfaceAlias `
        -NetworkCategory Private `
        -ErrorAction Stop
}

# SMB Server 서비스 활성화
STEP "LanmanServer 서비스 활성화" {
    Set-Service -Name LanmanServer -StartupType Automatic -ErrorAction Stop
    Start-Service -Name LanmanServer -ErrorAction Stop
}

# SMBv1 비활성화
STEP "SMBv1 비활성화" {
    Set-SmbServerConfiguration `
        -EnableSMB1Protocol $false `
        -Force `
        -ErrorAction Stop
}

# 공유 폴더 생성
STEP "공유 폴더 생성 또는 확인: $SharePath" {
    if (-not (Test-Path $SharePath)) {
        New-Item -Path $SharePath -ItemType Directory -Force -ErrorAction Stop | Out-Null
    }
}

# 현재 계정에 NTFS Modify 권한 부여
STEP "NTFS Modify 권한 부여" {
    icacls $SharePath /grant "${CurrentAccount}:(OI)(CI)M" /T | Out-Null

    if ($LASTEXITCODE -ne 0) {
        throw "icacls 권한 부여 실패"
    }
}

# 기존 동일 공유명 확인
STEP "기존 SMB 공유 확인" {
    $oldShare = Get-SmbShare -Name $ShareName -ErrorAction SilentlyContinue

    if ($oldShare) {
        if ($oldShare.Path -ne $SharePath) {
            throw "동일한 공유명($ShareName)이 다른 경로($($oldShare.Path))에 이미 존재함"
        }

        SKIP "기존 공유가 같은 경로에 존재함"
    }
    else {
        SKIP "기존 공유 없음"
    }
}

# SMB 공유 생성 또는 권한 보장
STEP "SMB 공유 생성 또는 권한 보장" {
    $share = Get-SmbShare -Name $ShareName -ErrorAction SilentlyContinue

    if (-not $share) {
        New-SmbShare `
            -Name $ShareName `
            -Path $SharePath `
            -ChangeAccess $CurrentAccount `
            -CachingMode None `
            -ErrorAction Stop | Out-Null
    }
    else {
        Grant-SmbShareAccess `
            -Name $ShareName `
            -AccountName $CurrentAccount `
            -AccessRight Change `
            -Force `
            -ErrorAction Stop | Out-Null
    }
}

# 불필요한 익명/공용 공유 권한 제거
STEP "Everyone / Guest / Anonymous share permission 제거" {
    $badNames = @(
        "Everyone",
        "Guest",
        "Anonymous Logon",
        "ANONYMOUS LOGON"
    )

    foreach ($name in $badNames) {
        Revoke-SmbShareAccess `
            -Name $ShareName `
            -AccountName $name `
            -Force `
            -ErrorAction SilentlyContinue | Out-Null
    }
}

# Windows 기본 SMB-In rule 중 TCP 445 rule만 Private profile에서 활성화
STEP "Windows 기본 SMB-In rule 활성화" {
    $smbRules = Get-NetFirewallRule -Direction Inbound -Action Allow -ErrorAction SilentlyContinue |
        Where-Object {
            (IsDefaultSmbInRule $_) -and
            (IsTcp445Rule $_)
        }

    if (-not $smbRules) {
        throw "Windows 기본 SMB-In rule을 찾지 못함"
    }

    foreach ($rule in $smbRules) {
        Set-NetFirewallRule `
            -Name $rule.Name `
            -Enabled True `
            -Profile Private `
            -ErrorAction Stop

        OK "활성화: $($rule.DisplayName)"
    }
}

Write-Host ""
Write-Host "========== SMB Open Result ==========" -ForegroundColor Cyan

$share = Get-SmbShare -Name $ShareName -ErrorAction SilentlyContinue
$enabled445 = Get-NetFirewallRule -Enabled True -Direction Inbound -Action Allow -ErrorAction SilentlyContinue |
    Where-Object { (IsDefaultSmbInRule $_) -and (IsTcp445Rule $_) }

if ($share -and $enabled445) {
    OK "SMB 임시 공유 생성 완료"
    OK "접속 경로: \\$TargetIp\$ShareName"
    OK "접속 계정: $CurrentAccount"
}
else {
    FAIL "SMB 공유 또는 방화벽 설정 확인 필요"
}

Write-Host "=====================================" -ForegroundColor Cyan

 

 

SMB 원상 복구

# ==========================================================
# Simple SMB Rollback Script
# 목적:
# - 임시 SMB 공유와 공유 폴더를 제거한다.
# - 로컬 계정은 유지.
# - Windows 기본 SMB-In rule을 비활성화한다.
# - SMBv1은 비활성화 상태로 유지한다.
# - 목적 외 네트워크 어댑터는 건드리지 않는다.
# ==========================================================

$ShareName = "SMBUpload"
$SharePath = "C:\SMBUpload"

function OK($m)   { Write-Host "[OK]   $m" -ForegroundColor Green }
function FAIL($m) { Write-Host "[FAIL] $m" -ForegroundColor Red }
function SKIP($m) { Write-Host "[SKIP] $m" -ForegroundColor Yellow }
function INFO($m) { Write-Host "[INFO] $m" -ForegroundColor Cyan }

function STEP($name, $block) {
    try {
        & $block
        OK $name
    }
    catch {
        FAIL "$name - $($_.Exception.Message)"
        exit 1
    }
}

function IsTcp445Rule($rule) {
    try {
        $pf = $rule | Get-NetFirewallPortFilter
        if ($pf.Protocol -ne "TCP") { return $false }
        return (@($pf.LocalPort) -contains "445")
    }
    catch {
        return $false
    }
}

function IsDefaultSmbInRule($rule) {
    return (
        $rule.DisplayName -like "*SMB-In*" -or
        $rule.DisplayName -like "*파일 및 프린터 공유*SMB*" -or
        $rule.DisplayName -like "*File and Printer Sharing*SMB*"
    )
}

Write-Host ""
Write-Host "========== Simple SMB Rollback Start ==========" -ForegroundColor Cyan

# 관리자 권한 확인
$isAdmin = ([Security.Principal.WindowsPrincipal] `
    [Security.Principal.WindowsIdentity]::GetCurrent()
).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)

if (-not $isAdmin) {
    FAIL "관리자 권한 PowerShell이 아님"
    exit 1
}
else {
    OK "관리자 권한 확인"
}

# 현재 SMB 연결 상태 출력
STEP "현재 SMB session / open file 상태 출력" {
    $sessions = Get-SmbSession -ErrorAction SilentlyContinue
    $openFiles = Get-SmbOpenFile -ErrorAction SilentlyContinue

    if ($sessions) {
        INFO "현재 SMB session 존재"
        $sessions | Format-Table ClientComputerName,ClientUserName,NumOpens -AutoSize
    }
    else {
        SKIP "현재 SMB session 없음"
    }

    if ($openFiles) {
        INFO "현재 SMB open file 존재"
        $openFiles | Format-Table ClientComputerName,Path,SessionId -AutoSize
    }
    else {
        SKIP "현재 SMB open file 없음"
    }
}

# 임시 SMB 공유 제거
STEP "SMB 공유 제거: $ShareName" {
    $share = Get-SmbShare -Name $ShareName -ErrorAction SilentlyContinue

    if ($share) {
        Remove-SmbShare -Name $ShareName -Force -ErrorAction Stop
    }
    else {
        SKIP "공유 없음: $ShareName"
    }
}

# 임시 공유 폴더 제거
STEP "공유 폴더 제거: $SharePath" {
    if (Test-Path $SharePath) {
        Remove-Item -Path $SharePath -Recurse -Force -ErrorAction Stop
    }
    else {
        SKIP "공유 폴더 없음: $SharePath"
    }
}

# Windows 기본 SMB-In rule 비활성화
STEP "Windows 기본 SMB-In rule 비활성화" {
    $smbRules = Get-NetFirewallRule -Direction Inbound -Action Allow -ErrorAction SilentlyContinue |
        Where-Object {
            (IsDefaultSmbInRule $_) -and
            (IsTcp445Rule $_)
        }

    if (-not $smbRules) {
        SKIP "Windows 기본 SMB-In rule 없음"
        return
    }

    foreach ($rule in $smbRules) {
        Disable-NetFirewallRule -Name $rule.Name -ErrorAction Stop
        OK "비활성화: $($rule.DisplayName)"
    }
}

# SMBv1 비활성화 유지
STEP "SMBv1 비활성화 유지" {
    Set-SmbServerConfiguration `
        -EnableSMB1Protocol $false `
        -Force `
        -ErrorAction Stop
}

# LanmanServer는 Windows 기본 서비스이므로 상태만 출력
STEP "LanmanServer 상태 출력" {
    $svc = Get-Service -Name LanmanServer -ErrorAction Stop
    INFO "LanmanServer Status=$($svc.Status), StartType=$($svc.StartType)"
}

Write-Host ""
Write-Host "========== Rollback Result ==========" -ForegroundColor Cyan
OK "SMB 원복 작업 완료"
Write-Host "=====================================" -ForegroundColor Cyan

 

 

원복 검증 스크립트

# ==========================================================
# Simple SMB Rollback Verification Script
# 목적:
# - 임시 SMB 공유와 공유 폴더가 제거되었는지 확인한다.
# - Windows 기본 SMB-In rule이 비활성화되었는지 확인한다.
# - SMBv1이 비활성화 상태인지 확인한다.
# - 로컬 계정은 기존 계정을 사용하므로 삭제 여부를 검사하지 않는다.
# ==========================================================

$ShareName = "SMBUpload"
$SharePath = "C:\SMBUpload"

function OK($m)   { Write-Host "[OK]   $m" -ForegroundColor Green }
function FAIL($m) { Write-Host "[FAIL] $m" -ForegroundColor Red }
function INFO($m) { Write-Host "[INFO] $m" -ForegroundColor Cyan }

function IsTcp445Rule($rule) {
    try {
        $pf = $rule | Get-NetFirewallPortFilter
        if ($pf.Protocol -ne "TCP") { return $false }
        return (@($pf.LocalPort) -contains "445")
    }
    catch {
        return $false
    }
}

function IsDefaultSmbInRule($rule) {
    return (
        $rule.DisplayName -like "*SMB-In*" -or
        $rule.DisplayName -like "*파일 및 프린터 공유*SMB*" -or
        $rule.DisplayName -like "*File and Printer Sharing*SMB*"
    )
}

Write-Host ""
Write-Host "========== Simple SMB Rollback Verification ==========" -ForegroundColor Cyan

# 관리자 권한 확인
$isAdmin = ([Security.Principal.WindowsPrincipal] `
    [Security.Principal.WindowsIdentity]::GetCurrent()
).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)

if (-not $isAdmin) {
    FAIL "관리자 권한 PowerShell이 아님"
    exit 1
}
else {
    OK "관리자 권한 확인"
}

# SMB 공유 제거 확인
$share = Get-SmbShare -Name $ShareName -ErrorAction SilentlyContinue

if (-not $share) {
    OK "SMB 공유 제거 확인: $ShareName"
}
else {
    FAIL "SMB 공유가 아직 존재함: $ShareName"
}

# 공유 폴더 제거 확인
if (-not (Test-Path $SharePath)) {
    OK "공유 폴더 제거 확인: $SharePath"
}
else {
    FAIL "공유 폴더가 아직 존재함: $SharePath"
}

# Windows 기본 SMB-In rule 활성 여부 확인
$enabledSmbRules = Get-NetFirewallRule -Enabled True -Direction Inbound -Action Allow -ErrorAction SilentlyContinue |
    Where-Object {
        (IsDefaultSmbInRule $_) -and
        (IsTcp445Rule $_)
    }

if (-not $enabledSmbRules) {
    OK "활성화된 Windows 기본 SMB-In rule 없음"
}
else {
    FAIL "활성화된 Windows 기본 SMB-In rule 존재"
    $enabledSmbRules | Format-Table DisplayName,Enabled,Direction,Action,Profile -AutoSize
}

# SMBv1 비활성화 확인
$smbCfg = Get-SmbServerConfiguration

if ($smbCfg.EnableSMB1Protocol -eq $false) {
    OK "SMBv1 Disabled 확인"
}
else {
    FAIL "SMBv1 Enabled 상태"
}

# 현재 사용자 정의 SMB share 출력
Write-Host ""
Write-Host "========== Current Non-Special SMB Shares ==========" -ForegroundColor Cyan

$nonSpecialShares = Get-SmbShare |
Where-Object { $_.Special -eq $false }

if ($nonSpecialShares) {
    INFO "사용자 정의 SMB share 존재"
    $nonSpecialShares | Format-Table Name,Path,Description -AutoSize
}
else {
    OK "사용자 정의 SMB share 없음"
}

# 방화벽 profile 상태 출력
Write-Host ""
Write-Host "========== Firewall Profile Status ==========" -ForegroundColor Cyan

Get-NetFirewallProfile |
Select-Object Name,Enabled,DefaultInboundAction |
Format-Table -AutoSize

Write-Host ""
Write-Host "========== Verification Result ==========" -ForegroundColor Cyan
OK "SMB 원복 검증 완료"
Write-Host "=========================================" -ForegroundColor Cyan

댓글