none
Using Get-ADUser with ValidateScript RRS feed

  • Question

  • Hello, I'm trying to add parameter validation to a function that creates a new user using properties from a model user. Obviously the model user should exist, the new user should not. 

    I can't seem to get reliable results from the ValidateScript codeblock using Get-ADUser. Some methods will work if there is a user (no get-aduser cmdlet error) other will work if a no records are returned. In other words: I can't find a method that returns a validation error weather the user exists in AD or does not currently exist.  

    Here's my current Param block

    function Copy-UserFromModel { [CmdletBinding()] Param( #New Account Name [Parameter(Mandatory=$True,Position=1,HelpMessage="Enter a unique username for New User account")] [ValidateScript({if (-not(Get-ADUser -Filter 'SamAccountName -eq "$_"')){$true} else {throw "$_ is NOT a unique new username!"}})] [string]$accountName, #New Account First Name [Parameter(Mandatory=$True)] [ValidateNotNullOrEmpty()] [string]$fName, #New Account Last Name [Parameter(Mandatory=$True)] [ValidateNotNullOrEmpty()] [string]$lName, #Model After Username [Parameter(Mandatory=$True)] [ValidateScript({if (-not(Get-ADUser $_)) {throw "$_ is not a valid model user account!"} else {$true}})] [string]$modelUserStr, #Prompt for password [Parameter(Mandatory=$False)] [switch]$getpass )

    #...code


    Other methods I've tried:

    [ValidateScript({[bool](Get-ADUser $_))})]
    
    [ValidateScript({((Get-ADUser $_ -ErrorAction SilentlyContinue) -eq $true)})]
    
    [ValidateScript({(Get-ADUser -filter {SamAccountName -eq "$_"})})]
    
    [ValidateScript({(Get-ADUser $_).count) -gt 0})]

    ...and many other variations of above.

    Variables $ModelUserStr and $AccountName are both string values that represent a SAMAccountName.

    Typical issues with the Get-ADUser [-Identity] <ADUser> approach is it will return True or:

    Copy-UserFromModel : Cannot validate argument on parameter 'accountName'. Cannot find an object with identity: 'somenewname' under:

    'DC=domain,DC=com'.

    At line:1 char:29

    + Copy-UserFromModel -accountName somenewname -fName newfirst -lName newlast -modelUserStr somevaliduser ...

    +                             ~~~~~

        + CategoryInfo          : InvalidData: (:) [Copy-UserFromModel], ParameterBindingValidationException

        + FullyQualifiedErrorId : ParameterArgumentValidationError,Copy-UserFromModel

    ...get-aduser error

    Typical issues with the Get-ADUser [-Filter] <string> approach is it will return a false positive or false negative (depending on test)

    Anyone know why this is happening and how to correct?


    Thursday, January 30, 2014 6:27 PM

Answers

  • Doest it have to be done using a filter? Can you based it off of the -Identity parameter instead?

    [Parameter(Mandatory=$True,Position=1,HelpMessage="Enter a unique username for New User account")]
    [ValidateScript({
        Try {
            $account=$_
            (Get-ADUser -Identity $account -ErrorAction Stop)
            $True
        } Catch {
            throw "$account is NOT a unique new username!"
        }
    })] 
    [string]$accountName


    Boe Prox
    Blog | Twitter
    PoshWSUS | PoshPAIG | PoshChat | PoshEventUI
    PowerShell Deep Dives Book

    Thursday, January 30, 2014 8:52 PM
    Moderator
  • If you call Get-ADUser with the -Identity parameter and the user is not found, it throws a terminating error.  You'd need to have a try/catch block inside your ValidateScript code to handle that.

    -Filter, on the other hand, just returns nothing if the user is not found, and does not produce an error.  Either approach can work; it's up to you which you want to use.

    Thursday, January 30, 2014 8:56 PM

All replies

  • Could you use the following for validation logic?

    $Model = "modelaccount"
    
    If (dsquery user -samid $Model)
    	{
    		$Valid = $true
    	}
    Else 
    	{
    		$Valid = $false
    	}


    Thursday, January 30, 2014 6:55 PM
  • Thanks Bobby -- you're definitely thinking out of the box,

    I bet this will help others working as an admin from a server console but from support workstation...

    [ValidateScript({if (dsquery user -samid "$_"){$true} else {throw "$_ is not a valid model user account!"} })] 

    Copy-UserFromModel : Cannot validate argument on parameter 'modelUserStr'. The term 'dsquery' is not recognized as the name of a cmdlet,

    function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and

    try again.

    At line:1 char:89

    + ...  -modelUserStr validUsername -Verbose

    +                    ~~~~~~

        + CategoryInfo          : InvalidData: (:) [Copy-UserFromModel], ParameterBindingValidationException

        + FullyQualifiedErrorId : ParameterArgumentValidationError,Copy-UserFromModel

    I really need to accomplish this using the ActiveDirectory module or other common ps cmdlet.

    Thursday, January 30, 2014 7:51 PM
  • Doest it have to be done using a filter? Can you based it off of the -Identity parameter instead?

    [Parameter(Mandatory=$True,Position=1,HelpMessage="Enter a unique username for New User account")]
    [ValidateScript({
        Try {
            $account=$_
            (Get-ADUser -Identity $account -ErrorAction Stop)
            $True
        } Catch {
            throw "$account is NOT a unique new username!"
        }
    })] 
    [string]$accountName


    Boe Prox
    Blog | Twitter
    PoshWSUS | PoshPAIG | PoshChat | PoshEventUI
    PowerShell Deep Dives Book

    Thursday, January 30, 2014 8:52 PM
    Moderator
  • If you call Get-ADUser with the -Identity parameter and the user is not found, it throws a terminating error.  You'd need to have a try/catch block inside your ValidateScript code to handle that.

    -Filter, on the other hand, just returns nothing if the user is not found, and does not produce an error.  Either approach can work; it's up to you which you want to use.

    Thursday, January 30, 2014 8:56 PM
  • ... Get-ADUser ... -Identity...  need to have a try/catch block inside your ValidateScript code to handle...

    -Filter...returns nothing if the user is not found, and does not produce an error...

    Good explanation! I didn't think a try/catch would work due to scope limitations within ValidateScript, but it indeed is a solution.
    Friday, January 31, 2014 8:17 PM
  • Doest it have to be done using a filter? Can you based it off of the -Identity parameter instead?

    ...
        Try {
            $account=$_
            (Get-ADUser -Identity $account -ErrorAction Stop)
            $True
        } Catch {
            throw "$account is NOT a unique new username!"
    ...

    Thank You!

    The filter would be ideal since I can limit identity to samaccountname, but in this case -identity parameter will get the job done.

    I didn't know try/catch would work inside a ValidateScript block, but it did!  The throw messes with the try/catch and there's some other issues with the scope of the pipeline object (your example deals with this)

    Friday, January 31, 2014 8:35 PM
  • Based on suggestions and explanation of Get-ADUser behavior this code works:

    # ...
    Param(
    #New Account Name
        [Parameter(Mandatory=$True,Position=1,HelpMessage="Enter a unique username for New User account")]
        [ValidateScript({try{[bool](-not(Get-ADUser -Identity $_));Write-Warning "$_ account already exists!"} catch{$true} })] 
        [string]$accountName,
    #...
    #Model After Username
        [Parameter(Mandatory=$True)]
        [ValidateScript({try{[bool](Get-ADUser -Identity $_)} catch{Write-Warning 'Invalid model-after username!' $false}})]
        [string]$modelUserStr,
    # ...
    )
    # ...

    In retrospect i should have used -filter method with test for $true or .count -eq 0 -- but this passes the test and i'm moving on. 

    -jb

    Friday, January 31, 2014 8:43 PM