Author Posts

August 21, 2014 at 3:53 am

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.

August 21, 2014 at 5:29 am

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"
}

August 21, 2014 at 5:52 am

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"
}


August 21, 2014 at 5:53 am

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
    }
        
}

August 21, 2014 at 8:01 am

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.

August 22, 2014 at 4:01 am

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!

August 24, 2014 at 5:43 am

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.