How to error check in "while" loop?

Tagged: , ,

This topic contains 6 replies, has 5 voices, and was last updated by Profile photo of Istvan Szarka Istvan Szarka 2 years, 3 months ago.

  • Author
    Posts
  • #18226
    Profile photo of Jay Jones
    Jay Jones
    Participant

    Hello,

    I am creating a script that creates user accounts from information input by the user. I have added some validation to the variables and want the script to force the user to input a valid value before they continue to the next stage input prompt. How would i do this?

    $error.clear()
    
    while ($error.count -eq 0)
    {
    
    $Username = Read-Host "Enter Full name of new staff member (e.g. John Smith, Lady Grey, George Bush)"
    $FirstName = Read-Host "Enter First name of new staff member"
    $Surname = Read-Host "Enter Surname of new staff member"
    $DispName = $Username
    $Desc = Read-Host "Enter Job title of new staff member"
    #$Title = Read-Host "Enter Title of new staff member (Mr, Mrs, Miss etc)"
    $Depar = Read-Host "Enter Department of new staff member"
    $telnumber = Read-Host "Enter staff members telephone extension (e.g 1754)"
    
    if($error.count -eq 1)
    	    {
            Write-Host -BackgroundColor Red -ForegroundColor Black "An error occured during user input. Please try again"
            continue
            }
        else
        {
    
    $SamName = Read-Host "Enter Username name of new staff member in the format first initial and surname (e.g jsmith, lgrey, gbush)"
    
    $UserArray = ("{0},{1},{2},{3},{4},{5},{6},{7}" -f $Username,$FirstName,$Surname,$DispName,$Desc,$Depar,$Telnumber,$SamName)
    
    
    # Add input to csv file.               
    Add-Content -Path $Path -Value $UserArray
    
    Write-Host -BackgroundColor Green -ForegroundColor Black "User succesfully Input"

    In this example i have placed the "if "statement after the $telnumber value as i have only added the validation to this variable.At present if you input an incorrect value it simply shows an error message and my error message and exits the script. I want it so that the input has to be correct before they can continue (to the $Samname variable). I would also appreciate some help with how i could do error checking after every variable without having to put an "if" statement in between every variable input!

    Thanks in advance.

  • #18230
    Profile photo of Tim Pringle
    Tim Pringle
    Participant

    I'm not sure if i follow you 100%, but if im right, sounds like you want to use a Try..Catch block with error raising

    Something like this?

    while (!($continue))
    {
        $continue = $true
        
        Try
        {
            $Username = Read-Host "Enter Full name of new staff member (e.g. John Smith, Lady Grey, George Bush)"
            $FirstName = Read-Host "Enter First name of new staff member"
            $Surname = Read-Host "Enter Surname of new staff member"
            $DispName = $Username
            $Desc = Read-Host "Enter Job title of new staff member"
            #$Title = Read-Host "Enter Title of new staff member (Mr, Mrs, Miss etc)"
            $Depar = Read-Host "Enter Department of new staff member"
            $telnumber = Read-Host "Enter staff members telephone extension (e.g 1754)"
            
            #put your validation here.
            # If one is invalid use the following to push it into the catch section
            throw "An error occured during user input. Please try again"
            
        }
        Catch
        {
            $continue = $false
        }
    }
    
    
    {
        
        $SamName = Read-Host "Enter Username name of new staff member in the format first initial and surname (e.g jsmith, lgrey, gbush)"
        
        $UserArray = ("{0},{1},{2},{3},{4},{5},{6},{7}" -f $Username, $FirstName, $Surname, $DispName, $Desc, $Depar, $Telnumber, $SamName)
        
        
        # Add input to csv file.
        Add-Content -Path $Path -Value $UserArray
        
        Write-Host -BackgroundColor Green -ForegroundColor Black "User succesfully Input"
    }
    
  • #18239
    Profile photo of Adnan Rashid
    Adnan Rashid
    Participant

    Hello,

    Perhaps you could parameterise your script so something like this.

    
    Function New-User {
    
    param (
    
    [Parameter (Mandatory=$true)]
    Username, 
    
    #Perhaps this one is not mandatory 
    [[Parameter (Mandatory=$false)]
    Surname 
    )
    
    #Here you can validate too 
    [ValidateRange(18,50)]
    [int] $age 
    
    #Code.... 
    
    } 
    
    

    For Error handling try using -ErrorVariable and -ErrorAction and then you can output those to a file and log it for future reference rather than not knowing what caused the script to error out.

    For example

    
    try {
    Test-Connection ftvman03 -ErrorAction Stop -ErrorVariable ConnectionError 
    }
    catch {
    $connectionError | out-file c:\temp\error.txt -Append
    Write-Warning "you have a error"
    }
    
    
    
  • #18240
    Profile photo of Rob Simmers
    Rob Simmers
    Participant

    The amount of information you are asking for and validating required, you really should consider a form versus a prompt-based approach. Additionally, you can provide dropdowns for items like Department and can check $telNumber with a regex pattern to ensure it's actually a properly formatted phone number. You have the power of .NET forms at your finger tips. Check out these articles:

    http://blogs.technet.com/b/heyscriptingguy/archive/2014/08/01/i-39-ve-got-a-powershell-secret-adding-a-gui-to-scripts.aspx
    http://blogs.technet.com/b/heyscriptingguy/archive/2014/08/02/weekend-scripter-fixing-powershell-gui-examples.aspx

    To answer the question, here is is basically what you would need to do, which...again...would get ugly quickly:

    $goodAnswer = $False
    while ($goodAnswer -eq $false){
    
        $question1 = Read-Host "What is your name?"
    
        if ($question1 -eq "Rob") {
            $goodAnswer = $true
        }
        else {
            "That is not your name!!  Answer correctly!!"
            $goodAnswer = $false
        }
            
    }
    
    $null = [reflection.assembly]::LoadWithPartialName("'Microsoft.VisualBasic")
    
    $goodAnswer = $False
    while ($goodAnswer -eq $false){
    
        $question2 = Read-Host "What is your age?"
    
        $isNumber = [Microsoft.VisualBasic.Information]::isnumeric($question2)
    
        if ($isNumber -eq $true) {
            $goodAnswer = $true
        }
        else {
            "That is not even a number!"
            $goodAnswer = $false
        }
            
    }
    
  • #18245
    Profile photo of Jay Jones
    Jay Jones
    Participant

    Hi Tim,

    I think the Try..Catch block looks like the method i should be using to achieve what i want. Sorry for the late reply i have been busy and not had much time to look at this I will have a look at the help for try..catch tomorrow and get back to you.

    Thanks for your help so far.

  • #18261
    Profile photo of Jay Jones
    Jay Jones
    Participant

    Thanks everyone for your help with this. I cant get it to work with the try..catch method.

    The example Rob has given seems the only way i can get what i want out of this, as i feared i have to have a "while" and "if" statement in between each "question". I suppose it doesn't matter now i have put it all in.

    I'll read into the powershell to gui info you have provided Rob.

    Adnan – i have parametrised my script but i didnt want to put the whole thing in 😉 thanks all the same. Here it is incase you were interested!

    Function Input-UserDetail {
    [CmdletBinding()]
    Param(
    
    [Parameter()][string]$Username,
    
    [Parameter()][string]$FirstName, 
    
    [Parameter()][string]$Surname, 
    
    [Parameter()][string]$DispName, 
    
    [Parameter()][string]$Desc, 
    
    [Parameter()][string]$Depar,
    
    [Parameter()][string]$SamName,
    
    [ValidatePattern("\d{4}")][Parameter()][int]$telnumber,
    
    [Parameter()][String]$Path = "C:\Holding\Scripts\Starter&LeaverScripts\NewADUser.csv",
    
    [Parameter()][string]$Proceed
    
         )
    
    # Clear error count.
    $error.clear()
    
    while ($error.count -eq 0)
    {
    
    $Username = Read-Host "Enter Full name of new staff member (e.g. John Smith, Lady Grey, George Bush)"
    
        if ($error.count -eq 1)
        {
        Write-Host -BackgroundColor Red -ForegroundColor Black "Invalid entry, please try again"
        $error.clear()
        }
        else
        {
        break
        }
    }
    
    while ($error.count -eq 0)
    {
    
    $FirstName = Read-Host "Enter First name of new staff member"
    
        if ($error.count -eq 1)
        {
        Write-Host -BackgroundColor Red -ForegroundColor Black "Invalid entry, please try again"
        $error.clear()
        }
        else
        {
        break
        }
    }
    
    while ($error.count -eq 0)
    {
    
    $Surname = Read-Host "Enter Surname of new staff member"
    
       if ($error.count -eq 1)
        {
        Write-Host -BackgroundColor Red -ForegroundColor Black "Invalid entry, please try again"
        $error.clear()
        }
        else
        {
        break
        }
    }
    
    
    $DispName = $Username
    
    while ($error.count -eq 0)
    {
    
    $Desc = Read-Host "Enter Job title of new staff member"
    
    if ($error.count -eq 1)
        {
        Write-Host -BackgroundColor Red -ForegroundColor Black "Invalid entry, please try again"
        $error.clear()
        }
        else
        {
        break
        }
    }
    
    while ($error.count -eq 0)
    {
    
    $Depar = Read-Host "Enter Department of new staff member"
    
    if ($error.count -eq 1)
        {
        Write-Host -BackgroundColor Red -ForegroundColor Black "Invalid entry, please try again"
        $error.clear()
        }
        else
        {
        break
        }
    }
    
    while ($error.count -eq 0)
    {
    
    $telnumber = Read-Host "Enter staff members telephone extension (e.g 1754)"
    
    if ($error.count -eq 1)
        {
        Write-Host -BackgroundColor Red -ForegroundColor Black "Invalid entry, please try again"
        $error.clear()
        }
        else
        {
        break
        }
    }
    
    while ($error.count -eq 0)
    {
    
    $SamName = Read-Host "Enter Username name of new staff member in the format first initial and surname (e.g jsmith, lgrey, gbush)"
    
    if ($error.count -eq 1)
        {
        Write-Host -BackgroundColor Red -ForegroundColor Black "Invalid entry, please try again"
        $error.clear()
        }
        else
        {
        break
        }
    }
     
    
    
    $UserArray = ("{0},{1},{2},{3},{4},{5},{6},{7}" -f $Username,$FirstName,$Surname,$DispName,$Desc,$Depar,$Telnumber,$SamName)
    
    
    # Add input to csv file.               
    Add-Content -Path $Path -Value $UserArray
    
    Write-Host -BackgroundColor Green -ForegroundColor Black "User succesfully Input"

    I may be back for some help with the validation for my other variables!

  • #18282
    Profile photo of Istvan Szarka
    Istvan Szarka
    Participant

    Hello Jay,

    If you want to generate an error message, I suggest you use Write-Error instead of Write-Host, since it takes care of the styling for you. Or you can use throw to cause a terminating error.
    Also, if it fits your solution, validating imput with ValidateScript or ValidatePattern (for regex) in the Param block may simplify your script, like below.
    Please mind that I used some pseudocode because I can't find out the real cmdlets for getting an AD department objest right now, although I gues you do it with Get-ADObject.

    [Parameter()]
    [ValidateScript( { if ( Get-ADDepartment -Name $_) { $true } else { throw " $($_) is invalid department name" } } ) ] #PARTLY PSEUDOCODE!!!
    [string]$Depar,
    

    This takes care of the validation and the error message at once.

You must be logged in to reply to this topic.