在 Powershell 中使用不寻常的日期格式?
Working with unusual date formats in Powershell?
我正在开发一个基于 GUI 的 Powershell 工具,以帮助用户轻松发现他们的 AD 密码何时到期。由于 Covid 限制,大多数用户不在现场,而是依靠 VPN 连接到 AD。这样做的一个副产品是,许多人没有看到 Windows 中的自动弹出窗口提醒他们尽快设置新密码。那些在现场的人会看到通知 OK。这不是一个组策略问题。该工具将以两种不同的语言推出 - 一种代表 'mothership'(通常不说英语的地方),另一种代表所有其他国家/地区的英语。
一些(大部分)东欧国家/地区使用短日期格式,读起来像 '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.
因为无法计算今天和到期日之间的差异
有什么简单的解决方法吗?我宁愿避免为每个 country/culture 编写一长串 'if' 语句。谢谢!
我相信代码可以更优雅一些,这将在以后的版本中解决。现在,让它处理一些更晦涩的日期格式是我的首要任务。
还有一点我要强调的是,此工具以 'read only' 的能力运行。未使用 'Set-Item' 命令。
此致,
WL
您有 2 个问题:
- 可互换使用的多种日期格式
- 一些 字符串上的尾随点
第一个问题可以通过将多个格式字符串传递给 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)
我正在开发一个基于 GUI 的 Powershell 工具,以帮助用户轻松发现他们的 AD 密码何时到期。由于 Covid 限制,大多数用户不在现场,而是依靠 VPN 连接到 AD。这样做的一个副产品是,许多人没有看到 Windows 中的自动弹出窗口提醒他们尽快设置新密码。那些在现场的人会看到通知 OK。这不是一个组策略问题。该工具将以两种不同的语言推出 - 一种代表 'mothership'(通常不说英语的地方),另一种代表所有其他国家/地区的英语。
一些(大部分)东欧国家/地区使用短日期格式,读起来像 '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.
因为无法计算今天和到期日之间的差异
有什么简单的解决方法吗?我宁愿避免为每个 country/culture 编写一长串 'if' 语句。谢谢!
我相信代码可以更优雅一些,这将在以后的版本中解决。现在,让它处理一些更晦涩的日期格式是我的首要任务。
还有一点我要强调的是,此工具以 'read only' 的能力运行。未使用 'Set-Item' 命令。
此致,
WL
您有 2 个问题:
- 可互换使用的多种日期格式
- 一些 字符串上的尾随点
第一个问题可以通过将多个格式字符串传递给 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)