Its a shame you should spend time to make some sense out of this rather foolish output, but of course it can be done.
Basically, all you want to do is find out if the string starts with a number followed by the word 'day' or 'days' and cut off all the rest. If this is not the case, the returned value should be 'Today'.
The easiest way to do that I think is by using switch -Regex.
Try
$inputFile = "C:\Data\expPasswords\expPasswords.csv"
$outputFile = "C:\Data\expPasswords\expPasswordsUp.csv"
$result = Import-Csv $inputFile | ForEach-Object {
$daysLeft = switch -Regex ($_.'time until password expires') {
'^(\d+ days?)' { $matches[1] }
default { 'Today' }
}
[PsCustomObject]@{
'Account' = $_.Account
'Days until Expiry' = $daysLeft
'Email address' = $_.'email address'
}
} | Sort-Object -Property 'Days until Expiry'
# output on screen
$result | Format-Table -AutoSize
# output to csv
$result | Export-Csv -Path $outputFile -NoTypeInformation
Regex details:
^ Assert position at the beginning of the string
\d Match a single character that is a “digit” (any decimal number in any Unicode script)
+ Between one and unlimited times, as many times as possible, giving back as needed (greedy)
\ day Match the character string “ day” literally (case sensitive)
s Match the character “s” literally (case sensitive)
? Between zero and one times, as many times as possible, giving back as needed (greedy)
Seeing your comment, I would suggest adding a real DateTime object to sort on.
Something like this:
$today = (Get-Date).Date
$result = Import-Csv 'D:\test.csv' | ForEach-Object {
$expiryString = $_.'time until password expires'
$expiryDate = $today
if ($expiryString -match '(\d+)\s*day') { $expiryDate = $expiryDate.AddDays([int]$matches[1]) }
if ($expiryString -match '(\d+)\s*hour') { $expiryDate = $expiryDate.AddHours([int]$matches[1]) }
if ($expiryString -match '(\d+)\s*minute') { $expiryDate = $expiryDate.AddMinutes([int]$matches[1]) }
if ($expiryString -match '(\d+)\s*second') { $expiryDate = $expiryDate.AddSeconds([int]$matches[1]) }
$daysLeft = if ($expiryDate.Date -eq $today) { 'Today' } else { ($expiryDate - $today).Days}
[PsCustomObject]@{
'Account' = $_.Account
'Email address' = $_.'email address'
'Days until Expiry' = $daysLeft
'Expiration Date' = $expiryDate
}
} | Sort-Object -Property 'Expiration Date'
# output on screen
$result
Output:
Account Email address Days until Expiry Expiration Date
------- ------------- ----------------- ---------------
User1 [email protected] Today 6-4-2020 0:00:00
User6 [email protected] Today 6-4-2020 0:03:00
User8 [email protected] Today 6-4-2020 13:00:00
User4 [email protected] Today 6-4-2020 20:00:00
User9 [email protected] 1 7-4-2020 2:00:00
User2 [email protected] 1 7-4-2020 19:00:00
User5 [email protected] 1 7-4-2020 20:00:00
User7 [email protected] 1 7-4-2020 23:00:00
User3 [email protected] 2 8-4-2020 0:00:00
If you don't want that new property 'Expiration Date' in your output, simply filter it away with:
$result | Select-Object * -ExcludeProperty 'Expiration Date'