Date / Time condition in powershell - SharePoint - LastItemModifiedDate - LastRunTime - date

I'm making a script that collect two dates from the system. One from when the scheduling task has last run and the date a list has last been modified. Problem is that the datetime format isn't correct .
LastItemModifiedDate from a SPList - output format 04/09/2015 12:48:48
LastRunTime from a scheduling task - output format 09.04.2015 10:50:03
What I want to do is to check if the list has been changed since the last time the scheduling task has run.
$scheduledTask = Get-ScheduledTask -TaskName "SharePoint scheduling" | Get-ScheduledTaskInfo
$scheduledTaskLastRunTime = $scheduledTask.LastRunTime
$listExist = $spSourceWeb.Lists | where{$_.Title -eq $listName}
if($listExist)
{
$spSourceList = $spSourceWeb.Lists[$listName]
if ($scheduledTaskLastRunTime -le $spSourceList.LastItemModifiedDate)
{
Write-Host " Changes found" -ForegroundColor Green
SetListColumnToCopy($listName)
}
Do I do the IF correct ? What magic do I have to do to check the datetime?
I've read that "don't need a special format to compare dates in Powershell" but is it true in this situation?

You should use ParseExact static method from DateTime class.
$dateToCompare = [datetime]::ParseExact("09.04.2015 10:50:03","MM.dd.yyyy hh:mm:ss", $null)

Related

How do I use "DO... Until" for a script date prompt

I am trying to use "DO...Until" in a script to require a user to enter a date. I want to ensure that the date is valid and that the script is able to use that date. I'm fairly new to PS and I'm not certain what I'm doing wrong. It keeps looping even if I put in a valid date.
Do #Start Get Effective Date#
{
$StartDate = Read-Host ' What is the effective date? Format: MM/DD/YYYY '
if ($StartDate -ge 1)
{ Write-Host " You Entered an Effective date of: $StartDate "
}
else
{ Write-Host " Please enter the effective date " -ForegroundColor:Green }
} Until ($StartDate -ge 1)
#End Get Effective Date#
I'm not certain if I am using the wrong '-ge' or not. Once I am able to get a valid date from the user I want the script to move to the next step.
you were close to ;-)
Do{
[string]$StartDate = Read-Host 'What is the effective date? Format: MM/DD/YYYY'
try {
[datetime]$StartDate = [datetime]::ParseExact($startdate, 'MM/dd/yyyy', [cultureinfo]::InvariantCulture)
}
Catch {
}
}
Until ($StartDate -is [DateTime])
The TryParseExact method seems a good fit for what you're looking to achieve, no need for error handling:
[ref] $date = [datetime]::new(0)
do {
$startdate = Read-Host 'What is the effective date? Format: MM/DD/YYYY'
$parsed = [datetime]::TryParseExact($startdate, 'MM/dd/yyyy', [cultureinfo]::InvariantCulture, [Globalization.DateTimeStyles]::None, $date)
} until($parsed)
$date.Value
To offer a concise alternative that relies on the fact that casting a string to [datetime] in PowerShell by default recognizes date strings such as '12/24/2022' (representing 24 December 2022), irrespective of the current culture, because PowerShell's casts, among other contexts, use the invariant culture:
$prompt = 'What is the effective date? Format: MM/DD/YYYY'
# Keep prompting until a valid date is entered.
while (-not ($startDate = try { [datetime] (Read-Host $prompt) } catch {})) {}
"Date entered: "; $startDate
Note: A [datetime] cast also recognizes other string formats, such as '2022-12-24'
Another option would be to create a PowerShell function and accept the date as a parameter. Functions can use a variety of approaches for parameter validation, including script.
https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_functions_advanced_parameters?view=powershell-7.2

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

Duration of tasks with Windows Task scheduler

Is it possible to know the duration of a certain task to calculate from "Created Task Process" to "Task completed"?
Task scheduler only show the Last Run Time but not the duration of all execution.
You can do something like the following:
$TaskName = '\Task Name'
$StartTime = (Get-Date).Adddays(-7)
$EndTime = Get-Date
$filter = #{ LogName = 'Microsoft-Windows-TaskScheduler/Operational'
ID = 129,102
StartTime = $StartTime
EndTime = $EndTime
Data = $TaskName
}
Get-WinEvent -FilterHashTable $filter | Select-Object TimeCreated,#{n='Action';e={$_.TaskDisplayName}}
Explanation:
For $TaskName, you must enter the task name exactly as it would show in (Get-WinEvent).Properties. You can also see this exact name in the task history messages. It will likely contain the backslash in the name.
You can set $StartTime and $EndTime to whatever you like here. Having a time interval speeds up the query retrieval time.
$filter is where the magic happens. It will ultimately be pushed into the parameter -FilterHashTable. Since the ID key can accept an array of [int], we can just comma separate the values. 129 is Created Task Process. 102 is Task Completed. Data does not accept wildcards so we must be exact with the task name as it would show in a System.Diagnostics.Eventing.Reader.EventProperty property. If you do not use Data, you will have to rely on Where-Object to further filter your task data by the task name, which will be significantly slower.

PowerShell Comparing Date issue

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.

Output the date/time in PowerShell

I want to output the date time in various places in my script for logging so I am doing this:
$b = Get-Date
Write-Output "Backups complete at $b"
# more code here
$c = Get-Date
Write-Output "Backups complete at $c"
I am having to use multiple letters of the alphabet to get the most current date/time.
Is there an easier way of doing this or do I have to reestablish the date each time I want to use it again?
Once you assign the current datetime to a variable, you are capturing the date and time at the moment you ran Get-Date.
Every time you want a new date and time, you need to run it again. You could avoid using a variable:
Write-Output "Backups complete at $(Get-Date)"
Another way to do this is using a format string and since you are using this for logging purpose I would recommend you to write a function because this will allow you to change the format of all log messages in a single place:
function Log-Message
{
[CmdletBinding()]
Param
(
[Parameter(Mandatory=$true, Position=0)]
[string]$LogMessage
)
Write-Output ("{0} - {1}" -f (Get-Date), $LogMessage)
}
Now you can simple log using:
Log-Message "Starting Backups"
Log-Message "Backups Completed"
Output:
22.07.2016 08:31:15 - Starting Backups
22.07.2016 08:31:15 - Backups Completed
Here is simple 1 which allow you format date time in your desire format
$currentTime = Get-Date -format "dd-MMM-yyyy HH:mm:ss"
Write-Host $currentTime " Other log string message "
OUTPUT
17-Aug-2020 10:06:19 other log string message