使用 PowerShell 按列表过滤输出
Filtering output by a list with PowerShell
我想做的是获取超过 90 天的登录名,并将它们与 Get-WmiObject Win32_UserProfile
输出中的当前配置文件列表进行比较。我已经尝试了几个小时,但仍然无法弄清楚为什么它没有按照(我认为)应该的方式处理名称列表。
Invoke-Command -ComputerName wsci201oit -ScriptBlock {
$AllUsers = Get-WmiObject Win32_UserProfile | Where-Object -FilterScript {
$_.LocalPath -notlike 'c:\windows*' -and
$_.LocalPath -notlike '*ADMINISTRATOR' -and
$_.LocalPath -notlike '*Public' -and
$_.LocalPath -notlike '*Temp'
} | Select-Object -Property LocalPath, SID
$Over90 = Get-ChildItem C:\Users | where {
$_.LastWriteTime -lt (Get-Date).AddDays(-30) -and
$_.Name -notlike 'ADMINISTRATOR' -and
$_.Name -notlike 'Public' -and
$_.Name -notlike 'TEMP'
} | Select-Object Name
$Over90 | Select-Object Name | Out-File C:\Windows\Temp\Over90.txt
$List = Get-Content -Path C:\Windows\Temp\Over90.txt
$AllUsers | Where-Object { $_.LocalPath -like "*$List" }
}
$AllUsers
的输出包含像 C:\Users\adm-thomas 这样的路径和 SID。 $List
的输出只包含 adm-thomas。我正在尝试将 $List
中的 "adm-thomas" 匹配到 "C:\Users\adm-thomas" LocalPath 并针对 $List
.
中的每个名称进行测试
您可以使用 Get-ChildItem
中的 FullPath
属性,但从 LastUseTime
属性 中获取相同的信息似乎效率更高Win32_UserProfile
然后整个命令可以只是过滤的远程 WMI 查找。
Get-CimInstance Win32_UserProfile -ComputerName wsci201oit |
Where-Object {
$_.Special -eq $False -and
$_.SID -notmatch '-500$' -and
$_.LastUseTime -lt (Get-Date).AddDays(-30)
} |
Select-Object -ExpandProperty LocalPath, SID
注意:我使用了默认情况下在 WSMAN 上运行的 CIM cmdlet。有一个 Special
属性 可以删除除本地管理员之外的所有特殊用户。如果 Administrator 已重命名,则匹配 SID 会更安全。
您可能要调整的第一件事是 C:\Users
的子文件夹的处理。将子文件夹名称列表写入文件,然后在下一条指令中读取该文件,这是完全没有意义的。更糟糕的是,由于您没有删除 table header,如果您恰好拥有用户帐户 "name",则可能会出现误报。只需展开 Name
属性 即可获得文件夹名称列表。您还可以通过对照要排除的名称列表检查名称来简化过滤。
$excludes = 'ADMINISTRATOR', 'Public', 'TEMP'
$threshold = (Get-Date).AddDays(-30)
...
$List = Get-ChildItem C:\Users | Where-Object {
$_.PSIsContainer -and
$_.LastWriteTime -lt $threshold -and
$exclude -notcontains $_.Name
} | Select-Object -Expand Name
然后您需要调整从 Win32_UserProfile
class 检索的数据。由于只有路径的叶部分与以后的比较相关,因此使用 calculated property 仅提取该信息:
... | Select-Object @{n='Username';e={Split-Path -Leaf $_.LocalPath}}, SID | ...
这样你就可以根据上面的 $List
过滤结果:
Get-WmiObject Win32_UserProfile | Where-Object {
$_.LocalPath -notlike 'c:\windows*'
} | Select-Object @{n='Username';e={Split-Path -Leaf $_.LocalPath}}, SID | Where-Object {
$List -contains $_.Username
}
我想做的是获取超过 90 天的登录名,并将它们与 Get-WmiObject Win32_UserProfile
输出中的当前配置文件列表进行比较。我已经尝试了几个小时,但仍然无法弄清楚为什么它没有按照(我认为)应该的方式处理名称列表。
Invoke-Command -ComputerName wsci201oit -ScriptBlock {
$AllUsers = Get-WmiObject Win32_UserProfile | Where-Object -FilterScript {
$_.LocalPath -notlike 'c:\windows*' -and
$_.LocalPath -notlike '*ADMINISTRATOR' -and
$_.LocalPath -notlike '*Public' -and
$_.LocalPath -notlike '*Temp'
} | Select-Object -Property LocalPath, SID
$Over90 = Get-ChildItem C:\Users | where {
$_.LastWriteTime -lt (Get-Date).AddDays(-30) -and
$_.Name -notlike 'ADMINISTRATOR' -and
$_.Name -notlike 'Public' -and
$_.Name -notlike 'TEMP'
} | Select-Object Name
$Over90 | Select-Object Name | Out-File C:\Windows\Temp\Over90.txt
$List = Get-Content -Path C:\Windows\Temp\Over90.txt
$AllUsers | Where-Object { $_.LocalPath -like "*$List" }
}
$AllUsers
的输出包含像 C:\Users\adm-thomas 这样的路径和 SID。 $List
的输出只包含 adm-thomas。我正在尝试将 $List
中的 "adm-thomas" 匹配到 "C:\Users\adm-thomas" LocalPath 并针对 $List
.
您可以使用 Get-ChildItem
中的 FullPath
属性,但从 LastUseTime
属性 中获取相同的信息似乎效率更高Win32_UserProfile
然后整个命令可以只是过滤的远程 WMI 查找。
Get-CimInstance Win32_UserProfile -ComputerName wsci201oit |
Where-Object {
$_.Special -eq $False -and
$_.SID -notmatch '-500$' -and
$_.LastUseTime -lt (Get-Date).AddDays(-30)
} |
Select-Object -ExpandProperty LocalPath, SID
注意:我使用了默认情况下在 WSMAN 上运行的 CIM cmdlet。有一个 Special
属性 可以删除除本地管理员之外的所有特殊用户。如果 Administrator 已重命名,则匹配 SID 会更安全。
您可能要调整的第一件事是 C:\Users
的子文件夹的处理。将子文件夹名称列表写入文件,然后在下一条指令中读取该文件,这是完全没有意义的。更糟糕的是,由于您没有删除 table header,如果您恰好拥有用户帐户 "name",则可能会出现误报。只需展开 Name
属性 即可获得文件夹名称列表。您还可以通过对照要排除的名称列表检查名称来简化过滤。
$excludes = 'ADMINISTRATOR', 'Public', 'TEMP'
$threshold = (Get-Date).AddDays(-30)
...
$List = Get-ChildItem C:\Users | Where-Object {
$_.PSIsContainer -and
$_.LastWriteTime -lt $threshold -and
$exclude -notcontains $_.Name
} | Select-Object -Expand Name
然后您需要调整从 Win32_UserProfile
class 检索的数据。由于只有路径的叶部分与以后的比较相关,因此使用 calculated property 仅提取该信息:
... | Select-Object @{n='Username';e={Split-Path -Leaf $_.LocalPath}}, SID | ...
这样你就可以根据上面的 $List
过滤结果:
Get-WmiObject Win32_UserProfile | Where-Object {
$_.LocalPath -notlike 'c:\windows*'
} | Select-Object @{n='Username';e={Split-Path -Leaf $_.LocalPath}}, SID | Where-Object {
$List -contains $_.Username
}