在Powershell中使用不寻常的日期格式



我正在开发一个基于GUI的Powershell工具,帮助用户轻松发现他们的AD密码何时到期。由于新冠肺炎限制,大多数用户(不在现场(都依赖VPN连接到AD。其副产品是,许多用户没有在Windows中看到自动弹出窗口,提醒他们尽快设置新密码。现场人员可以看到通知。这不是组策略问题。该工具将以两种不同的语言推出——一种代表"母舰"(通常不说英语(,另一种代表所有其他国家的英语。

一些(主要是(东欧国家使用的短日期格式读起来像"d.M.yyyy"——根据设置菜单,当在Windows中更改"Region"设置时。

该工具计算今天和到期数据之间的差异,并将天数输出到文本字段。实际有效期将正确显示在其自己的文本字段中。

这一切背后的一些源代码。。。

$thisUser = [Environment]::UserName
#make string
"net user " + $thisUser + " /domain"
#make cmd string
$fetch_net_user = "net user " + $thisUser + " /domain"
#execute command and store to variable
$net_user_data_array = Invoke-Expression $fetch_net_user
#Gets password expiry date (with header)
$password_expiry_with_header = $net_user_data_array[11]
#extracts only the date and assigns to new variable (the hours and minutes) can be ignored)
$password_expiry_as_string = $password_expiry_with_header.Split(' ')[-2]
# Home countries - works OK
try{
$password_expiry_as_dateTime = [datetime]::ParseExact($password_expiry_as_string, 'dd.MM.yyyy', $null)
}
# Others - works OK
catch{
$password_expiry_as_dateTime = [datetime]::ParseExact($password_expiry_as_string, 'dd/MM/yyyy', $null)
# where problem occurs
catch{
$password_expiry_as_dateTime = [datetime]::ParseExact($password_expiry_as_string, 'd.M.yyyy.', $null)
}
finally{
#show GUI error window...
}
#fetch date... converted to yesterday to fix an off-by-one bug!
$today = Get-Date
$rightNow = $today.AddDays(-1)
#calc days left
$daysRemaining = (New-TimeSpan -Start $rightNow -End $password_expiry_as_dateTime).Day
# some other code follows, manipulating date values etc. Works with most date formats. 

执行时,脚本将抛出几个错误。

第一个是…

Exception calling "ParseExact" with "3" argument(s): "String was not recognized as a valid  DateTime."

其他将紧随其后,如

You cannot call a method on a null-valued expression.

由于今天和到期日之间的差额无法计算。

有什么简单的解决办法吗?我宁愿避免为每个国家/文化写一长串"如果"的陈述。谢谢

我相信代码可以更优雅一点,这将在稍后的版本中解决。现在,让它适用于一些更模糊的日期格式是我的首要任务。

我应该强调的另一点是,这个工具以"只读"的方式工作。未使用"Set Item"命令。

问候,

WL-

您有两个问题:

  • 可交换使用的多种日期格式
  • 某些字符串上的尾随点

第一个问题可以通过将多个格式字符串传递给ParseExact()来解决-它将按顺序尝试每个字符串,直到成功解析输入字符串(或到达列表末尾(:

[datetime]::ParseExact($password_expiry_as_string, [string[]]@('dd.MM.yyyy', 'dd/MM/yyyy', 'dd.M.yyyy', 'd.M.yyyy'), $null, [System.Globalization.DateTimeStyles]::None)

第二个问题可以通过修剪拖尾点来解决:

[datetime]::ParseExact($password_expiry_as_string.TrimEnd('.'), [string[]]@('dd.MM.yyyy', 'dd/MM/yyyy', 'dd.M.yyyy', 'd.M.yyyy'), $null, [System.Globalization.DateTimeStyles]::None)

最新更新