简体   繁体   English

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

[英]Working with unusual date formats in Powershell?

I am working on a GUI-based Powershell tool to help users easily find out when their AD password is going to expire.我正在开发基于 GUI 的 Powershell 工具,以帮助用户轻松找出他们的 AD 密码何时到期。 Due to Covid restrictions, most users and not on-site and rely on VPN to connect to AD.由于 Covid 的限制,大多数用户并没有在现场,而是依靠 VPN 连接到 AD。 A by-product of this is that many do not see the automatic pop-up in Windows to remind them of them to set a new password soon.这样做的一个副产品是,许多人没有看到 Windows 中的自动弹出窗口提醒他们尽快设置新密码。 Those that are on-site see the notification OK.那些在现场的人看到通知 OK。 It's a not a group-policy problem.这不是一个组策略问题。 The tool will be will be rolled-out in two different languages - one representing the 'mothership' (where is English is not normally spoken) and English for all other countries.该工具将以两种不同的语言推出——一种代表“母语”(通常不说英语)和所有其他国家的英语。

Some of the (mostly) Eastern European countries use a short date format that reads like 'dMyyyy.'一些(大部分)东欧国家使用类似“dMyyyy”的短日期格式。 - according to settings menu when one changes the 'Region' setting in Windows. - 根据设置菜单更改 Windows 中的“区域”设置。

The tool calculates the difference between today and the expiry data and outputs the number of days to a text field.该工具计算今天和到期数据之间的差异,并将天数输出到文本字段。 The actual expiry is display correctly in its own text field.实际到期时间在其自己的文本字段中正确显示。

Some of the source code behind it all...这一切背后的一些源代码......

$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. 

When executed the script will throw several errors.执行脚本时会抛出几个错误。

The first is...第一个是...

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

Others will follow such as其他人将遵循,例如

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

As the difference between today and the expiry date cannot be calulated.由于无法计算今天与到期日之间的差异。

Is there any easy fix for this?有什么简单的解决方法吗? I'd rather avoid having to write a long list of 'if' statments for each country/culture.我宁愿避免为每个国家/文化写一长串“如果”陈述。 Thanks!谢谢!

I'm sure the code could be a little bit more elegant, and that will be addressed in a later version.我确信代码可以更优雅一点,这将在以后的版本中解决。 Right now, getting it to work some of the more obscure date formats is my priority.现在,让它在一些更晦涩的日期格式上工作是我的首要任务。

Something else that I should stress is that this tool works in a 'read only' capacity.我应该强调的其他一点是,该工具以“只读”能力工作。 No 'Set-Item' commands are used.不使用“Set-Item”命令。

Regards,问候,

WL WL

You have 2 problems:你有2个问题:

  • Multiple date formats used interchangeably可互换使用的多种日期格式
  • Trailing dots on some strings一些字符串上的尾随点

The first problem can be solved by passing multiple format strings to ParseExact() - it'll try each in order until it successfully parses the input string (or reaches the end of the list):第一个问题可以通过将多个格式字符串传递给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)

The second problem can be solved by trimming trailing dots:第二个问题可以通过修剪尾随点来解决:

[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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM