PowerShell 筛选当月入职员工数组并发送培训部门邮件问题
解决方案
问题原因
你之前的代码未得到正确结果主要是几个核心问题:
- 字符串类型的
start_date直接和DateTime类型的Get-Date()对比,类型不匹配,逻辑完全失效 - 把日期转成字符串做大小对比是按字符ASCII码排序,不是实际日期的时间先后逻辑,比如
"28/11/2023"字符串会比"01/12/2023"大,和实际日期先后完全相反 - 额外小问题:你之前写的
$date.toString少了方法调用的括号,应该是$date.toString(),且变量名可能拼写错误(你的数组是$employees,代码里写的是$employee)
实现步骤
核心思路:把所有start_date字符串统一转换成日期类型,再和当月的时间范围对比,不会受格式和类型影响。
步骤1:定义当月时间范围
# 获取当月1号零点的日期对象 $currentMonthStart = Get-Date -Day 1 -Hour 0 -Minute 0 -Second 0 # 获取下一个月1号零点的日期对象,作为判断边界 $nextMonthStart = $currentMonthStart.AddMonths(1)
步骤2:筛选当月入职员工
方法1:用Where-Object实现(更简洁,推荐新手使用)
$newEmployees = $employees | Where-Object { # 指定start_date的格式为日/月/年,强制转换为日期对象,避免系统区域格式影响 $startDate = [DateTime]::ParseExact($_.start_date, 'dd/MM/yyyy', $null) # 判断入职时间在当月范围内 $startDate -ge $currentMonthStart -and $startDate -lt $nextMonthStart }
方法2:用ForEach-Object实现(你同事提到的写法)
$newEmployees = $employees | ForEach-Object { $startDate = [DateTime]::ParseExact($_.start_date, 'dd/MM/yyyy', $null) # 符合条件就返回当前员工对象 if ($startDate -ge $currentMonthStart -and $startDate -lt $nextMonthStart) { $_ } }
步骤3:验证筛选结果
执行下面代码输出筛选出的员工姓名和入职日期,确认结果是否正确:
$newEmployees | Select-Object preferred_name, surname, start_date | Format-Table
注意事项
- 确认所有员工的
start_date都是严格的dd/MM/yyyy格式,日、月不足两位时补0,若格式有差异可调整ParseExact方法的第二个参数(格式字符串) - 不要直接用
[DateTime]$_.start_date做转换,很容易受操作系统的区域时间格式影响报错,用ParseExact指定格式最稳妥
内容的提问来源于stack exchange,提问作者user4935507
相关产品推荐
相关产品推荐

