如何用PowerShell统计列中值的数量?附10天用户登录记录函数
嘿,我来帮你搞定这两个PowerShell相关的问题!
一、用PowerShell统计某一列中各值的数量
这事儿其实很简单,最常用的就是Group-Object cmdlet,不管你是处理CSV数据、命令输出的对象数组都能用。给你举几个实用的例子:
例子1:统计CSV文件中某列的数值数量
假设你有个user_data.csv,里面有一列叫Department,想知道每个部门有多少人:
# 先导入CSV数据 $userList = Import-Csv -Path "C:\files\user_data.csv" # 按Department分组,然后提取名称和数量 $userList | Group-Object -Property Department | Select-Object Name, Count
例子2:统计系统服务启动类型的分布
如果想看看系统里服务的StartType(自动、手动、禁用)各有多少个:
Get-Service | Group-Object -Property StartType | Select-Object Name, Count
自定义哈希表统计(更灵活)
要是你需要更灵活的统计逻辑,比如把结果存到哈希表里方便后续操作:
$countMap = @{} # 假设$data是你的对象数组,列名为"Status" $data | ForEach-Object { $statusValue = $_.Status # 要是哈希表里没有这个值,就初始化为0,然后加1 $countMap[$statusValue] = ($countMap[$statusValue] ?? 0) + 1 } # 输出统计结果 $countMap.GetEnumerator() | Sort-Object Name
二、解析
get-logonhistory函数 你贴的这个函数是用来获取指定远程计算机过去N天(默认10天)的用户登录记录的,不过原代码里User =...的部分没写完,我先把完整可用的版本补出来,再给你拆解逻辑:
完整可运行的函数版本
# Function to get all user logons in the past 10 days function get-logonhistory{ Param ( [string]$Computer = (Read-Host Remote computer name), [int]$Days = 10 ) cls $Result = @() # 拉取指定时间范围内的WinLogon系统日志 $ELogs = Get-EventLog System -Source Microsoft-Windows-WinLogon -After (Get-Date).AddDays(-$Days) -ComputerName $Computer If ($ELogs) { ForEach ($Log in $ELogs) { # 只保留登录事件(InstanceId 7001对应用户成功登录) If ($Log.InstanceId -eq 7001) { $ET = "Logon" } Else { Continue } # 从事件消息里提取用户名(WinLogon事件的消息会包含用户信息) $User = ($Log.Message -split "`n")[1].Split(":")[1].Trim() # 把每条记录封装成自定义对象 $Result += New-Object PSObject -Property @{ Time = $Log.TimeWritten 'Event Type' = $ET User = $User ComputerName = $Computer } } # 按时间倒序输出结果 $Result | Select-Object Time, 'Event Type', User, ComputerName | Sort-Object Time -Descending } Else { Write-Host "No logon events found in the past $Days days on $Computer." } }
函数逻辑拆解
- 参数设置:
$Computer:要查询的远程计算机名,默认会弹出提示让你输入$Days:查询的时间范围,默认是过去10天
- 核心操作:
- 用
Get-EventLog读取目标计算机的系统日志,只筛选来源为Microsoft-Windows-WinLogon、且在指定时间范围内的事件 - 过滤出
InstanceId为7001的事件——这个ID是Windows用来标记用户成功登录的事件 - 从事件的
Message字段里提取用户名(因为WinLogon事件的消息文本里会有一行类似“用户: 张三”的内容,通过拆分字符串拿到用户名) - 把每条有效记录打包成包含登录时间、事件类型、用户名、计算机名的自定义对象,最后按时间从新到旧排序输出
- 用
小提醒:Get-EventLog是比较传统的cmdlet,现在微软更推荐用Get-WinEvent,不过原函数用的是Get-EventLog,所以我保持了原有逻辑~
内容的提问来源于stack exchange,提问作者Pickle
相关产品推荐
相关产品推荐

