怎样用脚本批量卸载SMB共享?

wen 实用脚本 2

如何用脚本高效批量卸载Windows SMB共享(附自动化方案)

目录导读

  1. 为什么要批量卸载SMB共享?常见场景与痛点
  2. 核心方法一:PowerShell脚本批量卸载SMB共享
  3. 核心方法二:批处理(batch)脚本快速清理
  4. 核心方法三:远程批量卸载企业级SMB映射
  5. 问答环节:高频问题与避坑指南
  6. 脚本安全验证与权限配置提醒

为什么要批量卸载SMB共享?常见场景与痛点

许多IT管理员在维护Windows服务器或终端时,会遇到以下情况:

怎样用脚本批量卸载SMB共享?

  • 冗余共享残留:当NFS共享、Samba服务或Windows文件服务器变更后,旧的SMB映射仍留在客户端,导致盘符冲突或路径失效。
  • 安全合规需求:某些内网审计要求定期清理未授权的SMB连接,特别是遗留的IPC$、C$管理共享。
  • 批量迁移场景:从旧NAS迁移到新存储后,需要一键卸载所有用户的旧SMB映射,再重新挂载新路径。

核心痛点:手动右键“断开网络驱动器”对于几十台甚至上百台机器不现实,且无法记录卸载状态,脚本化批量卸载是唯一高效、可审计的方案。


核心方法一:PowerShell脚本批量卸载SMB共享

1 脚本代码详解(适用于Windows 10/11/Server 2016+)

# 批量卸载所有映射的SMB共享(保留系统特殊共享如ADMIN$)
$mappedShares = Get-SmbMapping | Where-Object {$_.Status -eq "OK" -and $_.LocalPath -ne $null}
foreach ($share in $mappedShares) {
    try {
        Remove-SmbMapping -LocalPath $share.LocalPath -Force -ErrorAction Stop
        Write-Host "已卸载: $($share.LocalPath) -> $($share.RemotePath)" -ForegroundColor Green
    } catch {
        Write-Warning "卸载失败: $($share.LocalPath) - $_"
    }
}

脚本说明

  • Get-SmbMapping 获取当前所有SMB映射,通过Where-Object过滤状态为“OK”的映射(避免操作断开的残留记录)。
  • Remove-SmbMapping 执行卸载,-Force跳过确认弹窗。
  • 通过try-catch捕获异常,防止一个失败中断整个循环。

进阶:按远程路径筛选
如果只想卸载特定文件服务器(\oldnas\)的共享,可修改筛选条件:

Get-SmbMapping | Where-Object {$_.RemotePath -like "*oldnas*"} | Remove-SmbMapping -Force

核心方法二:批处理(batch)脚本快速清理

1 传统cmd命令方案(兼容Win7/Server 2008+)

@echo off
setlocal enabledelayedexpansion
echo 正在批量卸载SMB映射...
for /f "skip=1 tokens=1-3" %%a in ('net use ^| findstr /i "OK"') do (
    if /i not "%%a"=="OK" (
        set "drive=%%a"
        if not "!drive!"=="" (
            echo 卸载 !drive! ...
            net use !drive! /delete /y
        )
    )
)
echo 卸载完成。
pause

脚本逻辑

  • net use 显示所有映射,findstr "OK" 提取状态正常的行。
  • for循环解析每一行,提取盘符(例如Z:),然后用net use /delete卸载。
  • 注意skip=1跳过第一行表头,/y自动确认。

局限性
批处理无法像PowerShell那样按远程路径筛选,且net use在卸载某些系统隐藏共享(如IPC$)时可能报错,更适合快速清理普通用户映射。


核心方法三:远程批量卸载企业级SMB映射

1 使用Invoke-Command跨多台计算机执行

适用于域环境或已配置WinRM的计算机组:

$computers = Get-Content "C:\list\computers.txt" # 每行一个计算机名
$cred = Get-Credential # 管理员凭据
foreach ($computer in $computers) {
    Invoke-Command -ComputerName $computer -Credential $cred -ScriptBlock {
        Get-SmbMapping | Where-Object {$_.Status -eq "OK"} | Remove-SmbMapping -Force
        Write-Host "已清理 $env:COMPUTERNAME 上的SMB映射"
    } -ErrorAction SilentlyContinue
}

注意事项

  • 目标计算机必须开启PowerShell远程处理 (Enable-PSRemoting)。
  • 卸载操作会断开当前用户的映射,但不会影响其他用户(除非使用-Force时映射被某用户独占)。

2 替代方案:使用wmic命令(不带PowerShell)

wmic /node:@computers.txt path Win32_NetworkConnection where "Status='OK'" delete

限制
wmic已在Windows 10 21H2及Server 2022中弃用,长期维护建议迁移到PowerShell。


问答环节:高频问题与避坑指南

Q1:卸载SMB共享时,遇到“该设备正在使用中”怎么办?
A:PowerShell脚本已添加-Force参数,通常能强制断开,如果仍失败,需先关闭占用文件的程序(如资源管理器窗口、已有文件打开),可加入检测脚本:

$process = Get-SmbOpenFile -SmbInstance $share.SmbInstance
if ($process) { Stop-Process -Id $process.ClientProcessId -Force }

Q2:如何区分“系统共享”和“用户映射”?
A:系统共享(如C$、ADMIN$)通常没有映射盘符(LocalPath为空或为“None”),脚本中通过$_.LocalPath -ne $null可过滤掉,若需保留系统共享,则不要使用Get-SmbMapping删除所有映射,而是按RemotePath筛选。

Q3:卸载后自动刷新资源管理器,如何实现?
A:PowerShell脚本执行后,Windows会立即更新,但资源管理器窗口可能未刷新,可在脚本末尾添加:

(New-Object -ComObject Shell.Application).Windows() | ForEach-Object { $_.Refresh() }

Q4:有没有脚本能同时导出卸载前的清单供审计?
A:可以,在卸载前运行:

Get-SmbMapping | Export-Csv "C:\logs\smb_backup_$(Get-Date -Format yyyyMMdd).csv" -NoTypeInformation

然后将导出文件与卸载脚本结合,实现“先备份、后卸载”的规范流程。


脚本安全验证与权限配置提醒

关键注意事项

  1. 执行权限:PowerShell脚本需要以管理员身份运行(右键→以管理员身份运行),否则可能无法卸载系统共享或跨用户映射。
  2. 测试环境先行:建议先在3-5台测试机运行脚本,确认无不良影响后再推广到生产环境。
  3. 日志记录:为便于排错,强烈建议将脚本输出重定向到文件:
    powershell -ExecutionPolicy Bypass -File uninstall_smb.ps1 > uninstall_log.txt
  4. 组策略限制:如果域控制器禁用了Remove-SmbMapping,可尝试使用net use * /delete(需加/y参数)作为备选。

版权与合规声明

本文所有脚本示例均为原创,参考自微软官方文档(learn.microsoft.com)及社区最佳实践,使用时请遵守所在组织的安全策略,未授权扫描或清除系统共享可能违反网络安全法规,文中涉及的Get-SmbMappingRemove-SmbMapping为Windows原生cmdlet,无需额外安装模块。


批量卸载SMB共享的核心是精准筛选(按状态/路径/类型)和强制解除,PowerShell脚本具有最高灵活性和可扩展性,适合现代IT环境;批处理方案兼容旧系统,适合快速应急,无论选择哪种方法,务必先备份映射列表,并在小范围内验证,您的IT运维效率将从手动点鼠标变为一键执行。

抱歉,评论功能暂时关闭!