Prompt user for date with default of today

Hi all.
I am a bit stuck. I am attempting to prompt users for a date (easy), but would like to get todays date with a given format as a default if the user fails to enter anything and just hits Enter.
I am performing the basic date prompting for a date and formatting it is like this;

$today = Get-Date (Read-Host -Prompt 'Enter the start time and date of the patch window. Format: 01/17/2019') -Format "M/d/yyyy"

I attempted to add a default option like this (and a number of other formats), but no good;

$DefaultDay = Get-Date -Format "M/d/yyyy"
$today = Get-Date (Read-Host -Prompt 'Enter the start time and date of the patch window. Format: 01/17/2019') -Format "M/d/yyyy"
    if ([string]::IsNullOrWhiteSpace($today)) {$today = $DefaultDay}

I keep getting an error about “Cannot convert value” to type “System.DateTime”. Error: String is not recognized as a valid DateTime."
Pretty clear error, but I am unsure how to get around it.

Any help would be appreciated. Thanks.

Not sure that M/d/yyyy is valid date format as there could be two-digit month and day. Recommend parsing after the Read-Host to do error handling:

do {
    $date = $null
    $today = Read-Host -Prompt ('Enter the date of the patch window. Format MM/dd/yyyy (e.g. {0}) ' -f (Get-Date -Format "MM/dd/yyyy"))

    try {
        $date = Get-Date -Date $today -Format "MM/dd/yyyy" -ErrorAction Stop
        '{0} is a valid date' -f $date
    }
    catch {
        '{0} is an invalid date' -f $today
    }
}
until ($date)

Output:

PS C:\Users\rasim\Desktop> c:\Users\rasim\Desktop\temp.ps1
Enter the date of the patch window. Format MM/dd/yyyy (e.g. 03/18/2021) : 4
4 is an invalid date
Enter the date of the patch window. Format MM/dd/yyyy (e.g. 03/18/2021) : g
g is an invalid date
Enter the date of the patch window. Format MM/dd/yyyy (e.g. 03/18/2021) : 3/14/2021
03/14/2021 is a valid date

Thanks for the quick reply Rob. I will take a look in the AM.

A few comments:

  1. What you want to save is the start of a patch window NOT today’s date. I strongly suggest you name the variable something appropriate like $PatchWindowStart
  2. See the function Read-HostWithDefault in my module PoshFunctions on PSGallery. You can pass a default value to the function (in this case the output of Get-Date), and if the person hits Enter without typing any data the default value is returned.
  3. See the function Test-IsValidDate in the same module to ensure what saved in $PatchWindowStart is indeed a valid date string.

You are correct Bill, but the verbiage in the sample code that I provided is from another script, so I am not actually looking for a patch window in this use-case. In this instance I am just attempting to get a date prompt sent to the user/console and if they just hit Enter without entering a date, it puts that current days date in as a default.
The sample that Rob provided is actually returning ‘is an invalid date’ instead of todays date, and I am at the level of PoSH where I know just enough to be dangerous. So I am seeing if there are enough bread crumbs for me to get today’s date as a default. If history is any guide, I just need to increase my understanding slightly to get my final answer.
Thank you for taking the time to reply, and I will be looking at your function. I have a feeling that it will come in handy in future.

Not familiar with the script you are executing, but there are many blogs and articles on Powershell menus. While you can default with Enter (which would be $null) to using a date, typically you want to ask for a choice.

$choice = Read-Host -Prompt ('Enter T for (T)oday or C for (C)ustom and Enter to default to next year')

switch ($choice.ToUpper()) {
    'T' {$date = (Get-Date -Format "MM/dd/yyyy")}
    'C' {$date = $null
        do {
            $today = Read-Host -Prompt ('Enter the date of the patch window. Format MM/dd/yyyy (e.g. {0}) ' -f (Get-Date -Format "MM/dd/yyyy"))
        
            try {
                $date = Get-Date -Date $today -Format "MM/dd/yyyy" -ErrorAction Stop
                '{0} is a valid date' -f $date
            }
            catch {
                '{0} is an invalid date' -f $today
            }
        }
        until ($date)
    
    }
    '' {$date = Get-Date 1/1/2022 -Format "MM/dd/yyyy"}
    default {Exit}
}
    
"Using date {0}" -f $date

For anyone looking facing the same issue, this is what I ended up with;

$today = Read-Host -Prompt ('Enter the date of the patch window. Format M/d/yyyy (e.g. {0}) ' -f (Get-Date -Format "M/d/yyyy"))
 If (!$today) {$today = Get-Date -Format "M/d/yyyy"}

The variable $today is populated with the date that the user enters. If the user just hits Enter, the variable is populated with todays date (whatever today is at that time).

Thank you both for helping me find the answer.
And the single ‘M’ and ‘d’ are to remove leading zeros in the dates. The dates that $today will eventually need to match don’t have leading zeros.