PowerShell Where-Object -NotContains过滤已登录用户不生效问题
过滤失效核心原因
代码不生效是PowerShell比较运算符用法错误,共两个问题:
-NotContains的逻辑是校验单个元素是否存在于集合中,你写反了操作数方向:拿单个用户文件夹的Name字符串,判断它「不包含」$currentlyLoggedInUsers这个自定义对象数组。字符串不可能包含一整个对象集合,这个判断永远返回$true,自然不会过滤掉任何项。$currentlyLoggedInUsers里存的是带Name属性的PSCustomObject,不是纯用户名字符串,就算运算符方向写对,对象和字符串直接对比也无法匹配。
修复代码
先把已登录用户提取为纯字符串数组,再用-NotIn运算符做过滤(逻辑是判断当前遍历到的用户名,不在已登录用户列表中才保留),修改后完整代码:
# 直接提取已登录用户名为纯字符串数组,去重 $currentlyLoggedInUsernames = .\Get-LoggedOnUser.ps1 | Select-Object -ExpandProperty UserName -Unique $useraccounts = Get-ChildItem -Path "\\$env:COMPUTERNAME\c$\users\" -Exclude 'public', 'Administrator' | Where-Object Name -ne $env:USERNAME # 正确过滤逻辑 $useraccounts = $useraccounts | Where-Object Name -NotIn $currentlyLoggedInUsernames $useraccounts
补充说明
- 要是习惯用
-NotContains,把判断逻辑反过来写也能实现一样的效果:Where-Object { $currentlyLoggedInUsernames -NotContains $_.Name },和-NotIn只是操作数左右顺序的区别。 - 之前把
UserName转成Name属性的计算表达式完全多余,用-ExpandProperty直接把属性值拆成纯字符串即可,少一层对象转换能避免很多类型匹配的坑。 - 给已登录用户名加
-Unique去重,避免同一用户多会话产生重复值,不影响结果还能稍微提升判断效率。 - 过滤当前执行脚本的用户时用
-ne比-notcontains更合适,因为$env:USERNAME是单个字符串,不是集合。
内容的提问来源于stack exchange,提问作者Travis Bennett
相关产品推荐
相关产品推荐

