PowerShell Comparing Date issue - powershell

I created a small scrip that have do to a couple of thinks.
get string from description field from user in specific container
take part of this string (substring method) that holds date information
convert this string to date format
compare this formated string with a current date - 30 days and do sth
The problem is that comparing is not working correctly. I tried do recognise date that is older than 30 days and do something but i see that comparison not always work. sometimes it does not recognize that date is less then - 30 days from current day
Script below
$DateMaxTime = (Get-date).AddDays(-30)
$DateFormatMaxTime = Get-Date $DateMaxTime -Format dd/MM/yyyy
$getData = get-ADUser -Filter * -Properties * -SearchBase "OU=Disabled,OU=Control,OU=x,OU=x,DC=x,DC=x,DC=x" `
|where {$_.Description -like "LEFT*"} |select name,samaccountname,description
Foreach ($Data IN $getData){
$DataPart = $null
$DataPart=$Data.description
$DatePart= $DataPart.substring(5,10)
$FinalDate = [datetime]::ParseExact($DatePart,'dd/MM/yyyy',$null)
$FinalDateFormat = Get-Date $FinalDate -Format dd/MM/yyyy
If ($FinalDateFormat -lt $DateFormatMaxTime ){ Write-Host "$($Data.samaccountname), $($Data.description) moved to deleteMe" }
else{ Write-Host "$($Data.samaccountname), $($Data.description) still in disabled" }
}
Below output shows me the wrong results (as example i did it for one user - >
Based on this logic the value $FinalDateFormat that hold date -> 31-12-2018 is less then value $DateFormatMaxTime that hold this date -> 25-06-2019 but it still applies else statement ...
I am not sure why, i did something wrong with date conversion ?

I put the comments as the answer:
I would compare the datetime versions of the dates rather than the string versions.
If ($FinalDate -lt $DateMaxTime)
Running
get-date -format
makes them strings.
$finaldate.gettype(); $datemaxtime.gettype()
shows the types. They are [datetime], not [string] like the other two.

Related

DateTime casting works for CSV field "If Statement" logic, but not when used in second "If Statement"

I am working on automating tests a DumpSec report that runs a few logical tests and displays the solution. The DumpSec is a CSV file that I use ConvertFrom-Csv and then pull dates out of each user's field. However, I need to cast the date as DateTime so that I can compare multiple DateTime fields together properly.
Casting date time works and returns the correct answers on the first "If statement" but doesn't work on the second or third "if statements" even though I'm using the same casted variable DateTime as the first.
The error I'm getting is "Exception calling "ParseExact" with "3" argument(s): "String was not recognized as a valid DateTime.""
$PasswordExpiresDateFormat = [datetime]::ParseExact($person.P
Function AutomateCSVFileFunction($DumpSecFilePath)
{
#Variable to store the path of the passed file path
$ImportedFile = Get-Content -LiteralPath $DumpSecFilePath | Select-Object -skip 1 | ConvertFrom-Csv
#Variables for dates to do the correct math
$ThirtyDays = (Get-Date).AddDays(-30)
$SixMonthsAgo = (Get-Date).AddDays(-180)
$Message = "How often does the organizations user's change their password? (Enter number of days): "
$Title = "Organization's Password Age Limit"
$PasswordAgeLimitDays = [Microsoft.VisualBasic.Interaction]::InputBox($Message, $Title)
#Arrays for information to be stored
$DisabledAccounts = #()
$LastLogonAccounts = #()
$NeverExpireAccounts = #()
$AccountsWherePasswordsNotRequired = #()
$PasswordLastChangedGreaterThanAgeLimit = #()
#For each loop to check disabled accounts greater than 6 months, 30 days inactive, accounts without an expiration date, accounts where passwords do not expire, and
foreach ($person in $ImportedFile)
{
$LastLogonDateFormat = [datetime]::ParseExact(($person.LastLogonTime).trim(), "MM/dd/yyyy HH:mm", $null)
$PasswordLastSetDateFormat = [datetime]::ParseExact($person.PswdLastSetTime, "MM/dd/yyyy HH:mm", $null)
$PasswordExpiresDateFormat = [datetime]::ParseExact($person.PswdExpiresTime, "MM/dd/yyyy HH:mm", $null)
#If statement checking each row for a disabled account greater than 6 months
if ((($LastLogonDateFormat -lt $SixMonthsAgo) -and ($person.AcctDisabled -contains "Yes")) -or ($LastLogonDateFormat -contains "Never"))
{
#Add persons info to array
$DisabledAccounts += $person
}
#If statement checking to see enabled accounts who haven't logged on in more than 30 days
if (($LastLogonDateFormat -gt $ThirtyDays) -and ($person.AcctDisabled -like "No"))
{
#Add persons info to array
$LastLogonAccounts += $person
}
}
I've tried casting using only [DateTime]$VariableName, but that doesn't work either. Using the .Trim() method doesn't work either.

Writing Foldernames in a Array Powershell

I would like to write the directory names of several folders in an array. However, only all directory names with a date <today should be read. The directory names contain a date in this form * YYYYMMDD *
So I would have to do the following:
Borrow the date
Write the date in the form of YYYYMMDD in a variable
Read out directory names and check against the variable
Write data to an array ... do something ...
Can someone tell me how I can solve this with Powershell please?
Thank you
Start by retrieving all the candidate directories, then use Where-Object to extract the date part and test that it describes a date prior to today:
# Define threshold
$Today = (Get-Date).Date
# Go through all candidate directories
$oldDirectories = Get-ChildItem .\path\to\root\folder -Directory |Where-Object {
$dt = 0
# Test if directory name contains 8 consecutive digits describing a valid date
if($_.Name -match '(\d{8})' -and [datetime]::TryParseExact($Matches[1], 'yyyyMMdd', , $null, 'None', [ref]$dt)){
# We only want the ones with a date prior to today
$dt.Date -lt $today
}
else{
# Not containing a properly formatted date, we're not interested
$false
}
}
# Now we can extract the names
$oldDirectoryNames = #($oldDirectories.Name) # or #($oldDirectories |Select -Expand Name)
Do these directorynames start with the date?
yes
What do you mean by Borrow the date? Is that the date of today or what?
Determine the Date, Yes of today.
I read out the date accordingly and wrote it in a variable:
$Timestamp = ([datetime]::now).tostring("yyyyMMdd")
Now I want to read out all directory names which have got a Date < 1 Day and would like to process it in a foreach for further processing
Understandable?

compare line to string variable in powershell

I have txt file with date value, line by line
I try to compare them to today date in powershell but its not working
$DateTimeNow = (Get-Date).ToString('dd/MM/yyyy')
$data2 = get-content "output.txt"
$z= #()
foreach($line2 in $data2)
{
if($line2 -match $DateTimeNow){
write-host "same date"
}
}
the compare with "match" not work, I have try -eq and = but nothing better.
Have you any idea what I am doing wrong ?
The input dates all use 2-digit notation for the year (20 for 2020), but your string representing today's date uses 4-digits. Change to the appropriate format and it will work:
$DateTimeNow = Get-Date -Format 'dd/MM/yy'

Powershell keep looping until condition is true then proceed

I have written a script that so far is able to check a file "latest.json" for the "created_at" object which shows the last date that a commit has occurred for software.
$websiteJson = Invoke-WebRequest "https://website/latest.json" | ConvertFrom-Json | select created_at
$todaysDate = Get-Date -Format "yyyy-MM-dd HH:mm"
if($websitejson.created_at | where {$_.created_at -eq $todaysDate}){
Write-Output "Today's date matches"
} else {
Write-Output "has not yet been updated"
}
How part of latest.json looks like
"created_at":"2020-03-23 17:32:48"
How do I change this to keep looping until the date pull from latest.json matches then proceed to next step (would download and install software). Also, since "created at" has "17:32:48" will this cause the date check to fail since the time does not match?
. I want it to keep checking if dates match.
Thank you!
Right now, I'm not going to bother converting dates to match to make sure they're the same format, but what you need for your specific questions is just a do until loop. I might update this to check the date formats if you supply an example layout of the returned JSON.
Do{
$websiteJson = Invoke-WebRequest "https://website/latest.json" | ConvertFrom-Json | select created_at
$todaysDate = Get-Date -Format "yyyy-MM-dd HH:mm"
if($websitejson.created_at | where {$_.created_at -eq $todaysDate}){
Write-Output "Today's date matches"
} else {
Write-Output "has not yet been updated"
}
start-sleep -s 60
}until($websiteJson -eq $todaysDate)
I believe this wont work right off the bat. You'll have to get the JSON date and $todaysDate to be the same format, then you can do this and it will work.
if you want to compare the date and/or time, use datetime objects instead of datetime strings. something like this ...
if you want to test for the actual time difference between two time objects ...
((Get-Date -Date '2020-03-23 18:11:22') - [datetime]'2020-03-23 17:32:48').TotalHours
# result = 0.642777777777778
you keep mentioning date as if you don't want the time, so this method would work for comparing the date parts of two timestamps ...
# the date at the time the code was run = 2020 April 03, Friday 4:30:34 PM
$Today = (Get-Date).Date
$Created_At = '2020-04-03 15:15:15'
$Today -eq ([datetime]$Created_At).Date
result = True

Compare Dates in loop

I have a requirement where I need to read a date from a CSV file and compare it to a date variable within the script. However, my code doesn't work when some of the date entries in the CSV file are blank. Any idea how I can store a blank date in [datetime] variable?
Here's the part of my code:
#This is my date variable in script
$InactivityDate = (Get-Date).AddDays(-62).Date
Import-Csv $MyCSV | ForEach {
#This is the date variable i'm reading from csv file
$whenCreated = $_.whenCreated
#This converts value in string variable $whenCreated to [DateTime] format
$ConvertWhenCreated = ([datetime]::ParseExact($whenCreated,"dd/MM/yyyy",$null))
#Comparing dates
if($ConvertWhenCreated -le $InactivityDate)
{
"Account is dormant"
}
Above code works fine when $whenCreated contains some value, but when it's blank PowerShell obviously cannot compare a date variable with blank value :(
The only solution I can see now is to check if $whenCreated is blank and save a very old date like it happens in Excel, e.g.:
if($whenCreated -eq "")
{
$whenCreated = "01/01/1900 00:00:00"
}
Should this be OK or is there another logical solution?
Your problem most likely isn't with the comparison, but with the conversion of the blank value to a date via ParseExact(). If you want accounts with no date treated as dormant you could simply do something like this:
$whenCreated = $_.whenCreated
if ($whenCreated) {
$whenCreated = [DateTime]::ParseExact($whenCreated, 'dd/MM/yyyy', $null)
}
if ($whenCreated -le $InactivityDate) {
'Account is dormant'
}
Checking if an empty string (or $null) is lesser or equal to $InactivityDate will return $true as long as $InactivityDate contains a date.
You already test if the string is empty, which is good. But there is no need to assign a fake old date, you can simply assign $null:
$InactivityDate = (Get-Date).AddDays(-62)
$dateString = "2014-11-01"
if ($dateString) {
$date = Get-Date $dateString
} else {
$date = $null
}
if ($date -le $InactivityDate) {
"Account is dormant"
}