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

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

Related

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 from a string in PowerShell [duplicate]

This question already has answers here:
Compare Get-Date to Date as String
(1 answer)
How to parse (French) full month into datetime object in PowerShell?
(1 answer)
Closed 4 years ago.
$Deldate = "19-06-2018"
$Newdate = "04-06-2018"
I need to check which date is bigger.
if ($Deldate -ge $NewDate) {
write-host "NewDate is bigger"
}
else {
write-host "Deldate is bigger"
}
This is not working for me, and it looks like the format is not "System.DateTime". I'm getting the date values are from an external CSV file. How do I find a solution for this?
You should be able to cast the strings that you have created to the "datetime" type like so:
$Deldate = "19-06-2018"
$Newdate = "04-06-2018"
$Deldate = [datetime]::ParseExact("$Deldate", 'dd-MM-yyyy', $null)
$Newdate = [datetime]::ParseExact("$Newdate", 'dd-MM-yyyy', $null)
if ($Deldate -ge $NewDate) {
write-output "NewDate is bigger than or equal to"
}
else {
write-output "Deldate is bigger"
}
This returns the correct result. You can't simply use the Get-Date cmdlet, since the -Date required parameter also requires that the parameter be of type "DateTime", so you first have to cast the strings to the DateTime type.
Originally Proposed...
I am going to change the format of your date just a hair from DD-MM-YYYY to MM-DD-YYYY:
$Deldate = Get-Date "06-19-2018"
$Newdate = Get-Date "06-04-2018"
if ($Deldate -gt $Newdate) {
'Deldate is larger'
}
else {
'Newdate is larger or equal'
}
I'm creating two date objects based on the respective dates you gave. I'm comparing the two objects; PowerShell knows how to do the date math.
It works fine for U.S. style dates.
After much discussion...
However, for non-US style dates, consider calling datetime's constructor:
$Deldate = New-object 'datetime' -ArgumentList 2018, 6, 19, $null, $null, $null
$Newdate = New-object 'datetime' -ArgumentList 2018, 6, 4, $null, $null, $null
if ($Deldate -gt $Newdate) { 'Deldate is larger' } else { 'Newdate is larger or equal' }
Or, as proposed the [datetime]::ParseExact() method; documented here.
PowerShell is good with dates; it just has to know it's a date...
$Deldate = get-date "19-06-2018"
$Newdate = get-date "04-06-2018"
if ($Deldate -ge $NewDate) {
write-host "NewDate is bigger"
}
else {
write-host "Deldate is bigger"
}
Note: You could cast [datetime]$Deldate ="19-06-2018", but as explained in comments to PowerTip: Convert String into DateTime Object, it's valid only for US date format.

Use Get-Date "time" in an "if" statement PowerShell

$WshShell = New-Object -ComObject wscript.shell
$Time = (Get-Date).hour
$Time2 = Get-Date -DisplayHint Time
$Message ="Test for $Env:username at: " + $Time2
$fail = "ERROR:It is $Time2, which is past 12PM"
$PopUp = $WshShell.popup("$Message",0,"Task Scheduler Pop-up",1)
if ($Time2 > 12)
{
$PopUp = $wshShell.popup("$Message",0,"Task Scheduler Pop-up",1)
}
else {
$PopUp = $wshShell.popup("$fail",2,"Task Scheduler Pop-up",1)
}
Hi guys, I'm practicing a little bit of my PowerShell and have run across something I'm not quite sure how to Google for, or what method I need to use to get this to work correctly.
What I'm attempting to accomplish is have my box display only, the hour and minute like "12:31".
As you can see in the script I'm calling the
Hour, but I can't quite figure out how to have it display the time by itself the right way. I'm using the "Time" operator, but when you compare that in the "IF" statement, it doesn't recognize it as something it can compare itself to since it's not a real integer. I understand why, but I would like to be able to compare the .Hour to $Time2
I'm new to this and appreciate any help you can provide!
Thank you!
Don't think in terms of output strings before you actually need to.
> won't work for comparisons, you need to use -lt (less than) and -gt (greater than)
If you want to compare the time of two DateTime objects (regardless of the date), you can compare the TimeOfDay property:
$DateTimeNow = Get-Date
$DateTimeEarly = Get-Date -Hour 1 -Minute 5
if($DateTimeNow.TimeOfDay -lt $DateTimeEarly.TimeOfDay){
"It is very early right now!"
} else {
"It is at least past 01:05"
}
If you want to show the time in output, you have multiple options for formatting a DateTime string:
You can use the ToString() method with a formatting string:
PS C:\> (Get-Date).ToString('HH:mm')
20:41
The format operator -f:
PS C:\> '{0:HH:mm}' -f (Get-Date)
20:41
Or have Get-Date return a formatted string itself:
PS C:\> Get-Date -Format 'HH:mm'
20:41
If you want 12-hour style time, use hh:mm
If you need to display the time you could use one of several methods. Those would all convert the result to string. I think you need to save $time2 as just a [datetime] object. That way you can format it for display and use .Hour for comparison logic.
$Time2 = Get-Date
$Message ="Test for $Env:username at: " + $Time2.ToString("HH:mm")
$PopUp = $WshShell.popup("$Message",0,"Task Scheduler Pop-up",1)
if ($Time2.Hour -gt 12){
#Do Stuff
}
This logic would only work for 24hr time though. 1(pm) is less than 12 but later in the day. Which is what HH:mm represents.

Formatting Dates in PowerShell

I am currently trying to convert a date from the one displayed in regedit to a readable datetime format. But I do not know how to do this, I'm working with the following:
.GetValue('InstallDate')
And in the .csv file, it display it as this: 20150914
How would I go about converting that into a readable date?
try
[datetime]::Parseexact("20150914","yyyyMMdd", $null )
I'm not sure why you down voted the other answer because he is right on the money with [Datetime]::ParseExact you will have to deal with the null values though
$Regbase = Get-ChildItem HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\
foreach ($entry in $regBase)
{
$date = (Get-ItemProperty HKLM:\$entry | select installdate).installdate
try
{
[DateTime]::ParseExact($date, "yyyyMMdd", [CultureInfo]::InvariantCulture)
}
catch [exception]
{
"Date Value: $date"
}
}
PowerShell Date is just .NET DateTime. Check DateTime.ParseExact.
[DateTime]::ParseExact("20151010", "yyyyMMdd", [CultureInfo]::InvariantCulture)