PowerShell中Get-SmbShare用-or筛选排除项失效及批量优化需求
问题与解决方案
问题重现
运行以下PowerShell v5代码尝试排除默认共享C$、ADMIN$、IPC$:
$shares = Get-SmbShare | where {$_.Name -ne "IPC$" -or $_.name -ne "C$" -or $_.name -ne "ADMIN$"} $shares
输出结果仍包含这三个默认共享:
Name ScopeName Path Description ---- --------- ---- ----------- ADMIN$ * C:\WINDOWS Remote Admin C$ * C:\ Default share IPC$ * Remote IPC share2 * C:\Temp\share2 Sharetest * C:\Temp\Share
虽然通过多次管道筛选能解决问题:
$shares = Get-SmbShare | where {$_.Name -ne "IPC$"} | where {$_.name -ne "C$"} | where {$_.name -ne "ADMIN$"} $shares
得到预期结果:
Name ScopeName Path Description ---- --------- ---- ----------- share2 * C:\Temp\share2 Sharetest * C:\Temp\Share
但需要更优雅高效的方式处理更大的排除列表。
错误原因
原代码逻辑错误:使用-or运算符时,只要其中一个条件成立(比如ADMIN$的名称不等于IPC$),就会保留该共享。正确的逻辑应该是共享名称同时不等于所有排除项,需要用-and替代-or:
$shares = Get-SmbShare | where {$_.Name -ne "IPC$" -and $_.name -ne "C$" -and $_.name -ne "ADMIN$"}
优雅处理大排除列表的方案
当排除列表较长时,建议先定义排除数组,再用-contains(PowerShell v5原生支持)进行判断,代码更简洁易维护:
# 定义排除的共享名称数组 $excludedShares = @("IPC$", "C$", "ADMIN$") # 过滤掉排除列表中的共享 $shares = Get-SmbShare | where { -not ($excludedShares -contains $_.Name) } $shares
如果是PowerShell v6及以上版本,还可以更简洁地用-notin运算符:
$excludedShares = @("IPC$", "C$", "ADMIN$") $shares = Get-SmbShare | where { $_.Name -notin $excludedShares }
内容的提问来源于stack exchange,提问作者Jamie GF
相关产品推荐
相关产品推荐

