How to Treat an incorrect inputed date?

PauloJosMartinsCosta-9915 41 Reputation points
2020-11-21T16:02:16.987+00:00

I developed a Powershell script where a IT Support must populating many fields, like Name, Surname, Description, E-mail, password and Account expires (dd/mm/yyyy)

A part the script is this:

$Date = Read-Host -Prompt 'Enter the end of contract date - dd/mm/yyyy'
Set-ADAccountExpiration -Identity $SamAccountName -DateTime $Date -Server (Get-ADDomain).PDCEmulator

If the date is entered correctly, the script works. But if a non-existent date is entered, example 31/02/2020, it gives an error:

Set-ADAccountExpiration: Cannot bind parameter 'DateTime'. Cannot convert value "31/02/2020" to type "System.DateTime". Error: "String was not recognized as a valid DateTime. "

How best to treat/manipulate this?

Thanks.

Windows for business | Windows Server | User experience | PowerShell
Microsoft Security | Microsoft Entra | Other
0 comments No comments
{count} votes

Accepted answer
  1. Andreas Baumgarten 123.5K Reputation points MVP Volunteer Moderator
    2020-11-21T17:09:19.55+00:00

    Maybe this is helpful:

    $expirationDate = ""
     $Date = Read-Host -Prompt 'Enter the end of contract date - dd/mm/yyyy'
     try{
          $expirationDate = [DateTime]::ParseExact($date,'dd/MM/yyyy',$null)
     }
     catch{
              Write-Output "$date is not a valid date"
              break
    }
    Set-ADAccountExpiration -Identity $SamAccountName -DateTime $expirationDate -Server (Get-ADDomain).PDCEmulator
    

    First the input is converted in a datetime format. This way it's easier to validate the date. If a valid date is entered $expirationDate contains the date. If no valid date is entered the $expirationDate is empty and the scripts stops.


    (If the reply was helpful please don't forget to upvote and/or accept as answer, thank you)

    Regards
    Andreas Baumgarten

    2 people found this answer helpful.
    0 comments No comments

3 additional answers

Sort by: Most helpful
  1. Andreas Baumgarten 123.5K Reputation points MVP Volunteer Moderator
    2020-11-21T19:57:55.267+00:00

    Maybe this is helpful to verify the password:

    https://www.checkyourlogs.net/active-directory-password-complexity-check-powershell-mvphour/

    https://gallery.technet.microsoft.com/scriptcenter/Verify-password-complexity-c9e6f42f

    It looks like you are creating a new AD user. This eliminates the "password history" criteria in my opinion. There should be no password history for a new created user.

    Another option might be to generate a random password instead of a password input.

    https://activedirectoryfaq.com/2017/08/creating-individual-random-passwords/


    (If the reply was helpful please don't forget to upvote and/or accept as answer, thank you)

    Regards
    Andreas Baumgarten

    1 person found this answer helpful.
    0 comments No comments

  2. PauloJosMartinsCosta-9915 41 Reputation points
    2020-11-21T19:23:01.027+00:00

    @Andreas Baumgarten

    Thanks a lot. It's works perfectly. I searched for this for 2 days.

    Can I ask for one more favor?

    I was now debugging, and I found an issue in the password. Here how I treat the password:

    do {  
    $secpass = Read-Host "Type your password" -AsSecureString  
    $secpass2 = Read-Host "Confirm password" -AsSecureString  
    $secpass_text = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($secpass))  
    $secpass2_text = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($secpass2))  
    }  
    while ($secpass_text -cne $secpass2_text)  
    Write-Host "Passwords match." -F green  
    

    The script works fine, but if you enter the password with few characters, null or from the history, it gives an error:

    "New-ADUser : The password does not meet the length, complexity, or history requirement of the domain. ADPasswordComplexityException"

    How best to treat/manipulate this?

    Thanks.

    0 comments No comments

  3. PauloJosMartinsCosta-9915 41 Reputation points
    2020-12-22T18:54:55.747+00:00

    @Andreas Baumgarten Sorry for the late reply.
    Yes, I am creating a script for IT Support create new AD user.
    I created a Function TestPasswordComplexy.

    This script works almost perfectly. Function TestPasswordComplexy gives error on screen:

    New-ADUser: The password does not meet the length, complexity, or history requirement of the domain.
    At C: \ Users \ Administrator \ Documents \ scripts \ tests \ Versions \ Create_user_user_v.1.4 - test.ps1: 123 char: 1

    • New-ADUser -SamAccountName $ SamAccountName -Name $ DisplayName -Displa ...

    The script still prints the outputs below before displaying the above error:

    Passwords match.
    .........
    Valid password.

    But it does not create the user.

    Function TestPasswordComplexy {  
       do {  
      
    $secpass = Read-Host "Type password" -AsSecureString  
    $secpass2 = Read-Host "Retype password" -AsSecureString  
    $secpass_text = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($secpass))  
    $secpass2_text = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($secpass2))  
    }  
    while ($secpass_text -cne $secpass2_text)  
    Write-Host "Passwords match." -F green  
    Write-Host "........." -F green  
      
      
    if ($null -eq (Get-Module -listavailable activedirectory))  
    {  
        # handle problem, next step required AD module.  
    }  
    $policy = Get-ADDefaultDomainPasswordPolicy  
      
    $complexityRulesMet = 0  
    if ($policy.ComplexityEnabled)  
    {  
        # assume 3 in 4 complexity  
        if ($secpass -cmatch '[a-z]') { $complexityRulesMet += 1 }    
        if ($secpass -cmatch '[A-Z]') { $complexityRulesMet += 1 }    
        if ($secpass -match '\d') { $complexityRulesMet += 1 }        
        if ($secpass -match '[`~!@#$%^&*()_+-=\\{}|;'''':",./<>?\[\]]') { $complexityRulesMet += 1 }    
    }  
    else  
    {  
        # domain doesn't enforce complexity requirement  
        $complexityRulesMet = 4  
    }  
      
    if($secpass.Length -ge $policy.MinPasswordLength -and $complexityRulesMet -ge 3)  
    {  
        Write-Host "Valid password." -ForegroundColor Green  
        Write-Host "...." -F green  
        Write-Host "........." -F green  
    }  
    else  
    {  
        Write-Host "Password not valid! Password must meet complexity requirements." -ForegroundColor Red  
        Write-Host ""  
        Write-Host ""  
        TestPasswordComplexy  
          
    }  
    }  
    TestPasswordComplexy  
    

    If I remove / comment on Function, it works. However, if password failed, the script returns from the beginning of the Menu. I would like you to return in the step of entering the password after the failure.

    If you want the complete code, tell me, I will insert it here.

    Please give me a helping hand or a way forward.

    Thanks!


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.