jz9
jz9

Reputation: 63

ValidateLength Powershell

This is my first script so don't beat me up to bad!

I'm working on a script that creates a network directory & AD group based on user input. The following is what I've gotten so far. It works but I would like to make a few enhancements.

I would like to Validate length for user inputs. I was able to find an article (PowerShell ValidateLength with Read-Host) that explains how to use the ValidateLength string to check a user's input. This works great, however, I would like to include it in a loop. Example if user does not input exactly X characters - then retry. Right now it just errors out.

Any help would be greatly appreciated!

[ValidateLength(2,2)]$Division = [string](Read-Host -Prompt 'Please enter the TWO digit division number ')
[ValidateLength(4,4)]$Matter = [string](Read-Host -Prompt 'Please enter the FOUR digit matter number ')
[ValidateLength(4,4)]$Client = [string](Read-Host -Prompt 'Please enter the FOUR digit client number ')

Upvotes: 3

Views: 4043

Answers (3)

Ansgar Wiechers
Ansgar Wiechers

Reputation: 200313

As @briantist already pointed out, validation functions were made for a different purpose (parameter validation). You have a different scenario, since you want to keep prompting the user until a valid value is entered. Validation functions just don't work well in this scenario for a number of reasons:

  • they throw an error instead of returning a boolean value, which is fine for a function call, but not for validating a value.
  • they don't repeat, so you need additional code anyway,
  • their parameters can't be variables.

I would probably put the input/validation loop in a function and use numeric comparisons instead of checking the length of a string, since you're asking the user to input numbers anyway.

function Get-Number {
  [CmdletBinding()]
  Param(
    [Parameter(Mandatory=$true)]
    [string]$Prompt,
    [Parameter(Mandatory=$false)]
    [int]$Min = 0,
    [Parameter(Mandatory=$false)]
    [int]$Max = 9999
  )

  # prevent infinite loop due to impossible condition
  if ($Min -gt $Max) { throw 'Min cannot be greater than max.' }

  $ErrorActionPreference = 'SilentlyContinue'
  do {
    $num = Read-Host -Prompt $Prompt
    $valid = $Min -le $num -and $Max -ge $num
    if (-not $valid) { Write-Host "Invalid value: $num" }
  } until ($valid)

  return [int]$num
}

$Division = Get-Number -Prompt 'Please enter the TWO digit division number' -Min 10 -Max 99
$Matter   = Get-Number -Prompt 'Please enter the FOUR digit matter number' -Min 1000 -Max 9999
$Client   = Get-Number -Prompt 'Please enter the FOUR digit client number' -Min 1000 -Max 9999

Upvotes: 3

briantist
briantist

Reputation: 47802

Although the various [Validate... attributes work on variables, it's a non-standard usage (and few people know about them). It works best when you do want to error out.

If you don't, just check it yourself and decide and what to do in the event that it's not what you want:

do {
    $Division = [string](Read-Host -Prompt 'Please enter the TWO digit division number ')
    if ($Divison.Length -ne 2) {
        continue
    }

    $Matter = [string](Read-Host -Prompt 'Please enter the FOUR digit matter number ')
    if ($Matter.Length -ne 4) {
        continue
    }

    $Client = [string](Read-Host -Prompt 'Please enter the FOUR digit client number ')
    if ($Client.Length -ne 4) {
        continue
    }

    break
} while ($true)

Upvotes: 3

BenH
BenH

Reputation: 10044

You could utilize a while loop:

$Division = $null
while ($null -eq $Division) {
    [ValidateLength(2,2)]$Division = [string](Read-Host -Prompt 'Please enter the TWO digit division number ')
}

Upvotes: 0

Related Questions