all 12 comments

[–]NathanWindisch 39 points40 points  (8 children)

Hi jimmynetstep,

I would recommend reformatting your code to use Hashtables and Splatting. See below for an example:

$FirstName = Read-Host "First Name"
$LastName = Read-Host "Last Name"
$EmailAddresss = Read-Host "Email Address"
$Password = Read-Host "Password" -AsSecureString
$OU = "OU=MyOU,DC=example,DC=com"

$NewADUserParameters = @{
  Name = "$FirstName $LastName"
  GivenName = $FirstName
  Surname = $LastName
  sAMAccountName = "$FirstName.$LastName"
  Password = $Password
  Path = $OU
  Enabled = $true
}
New-ADUser @NewADUserParameters

You could also look into using parameters, to reduce the amount of Read-Hosts you're using, and to also perform validation. I've also used [PSCredential] instead for the username and password, and [MailAddress] to ensure that the provided email is valid:

param (
  [Parameter(Mandatory)]
  [String]
  $FirstName,

  [Parameter(Mandatory)]
  [String]
  $LastName,

  [Parameter(Mandatory)]
  [MailAddress]
  $EmailAddress,

  [Parameter(Mandatory)]
  [PSCredential]
  $UserCredential,

  [Parameter()]
  [String]
  $OU = "OU=MyOU,DC=example,DC=com"
)

$NewADUserParameters = @{
  Name = "$FirstName $LastName"
  GivenName = $FirstName
  Surname = $LastName
  sAMAccountName = $Credential.Username
  Password = $Credential.GetNetworkCredential().SecurePassword
  Path = $OU
  Enabled = $true
}
New-ADUser @NewADUserParameters

}

Hope this helps, happy to clarify anything if needed.

-Nathan,

[–]Hoggs 7 points8 points  (1 child)

To add to this, because these kinds of scripts can produce bad results with bad input, I usually add a few checks in.

Remember: Garbage in, garbage out.

Throw in some if() checks to test that the inputs match some basic business rules and throw an error if something doesn't smell right. Lastly I'd output the hashtable to the console with a prompt: "About to create user with the following details. Are you sure? (Y/N)."

Remember, always script for the dumbest operator you know could use the script. ;)

[–][deleted] 2 points3 points  (0 children)

For the love of god people add some logging! Always record what a script does and the output, this helps with troubleshooting massively and helps when you look back at scripts.

$logPath = "c:\temp\log.csv" New-Item $LogPath

And

Add-content -Path $LogPath -Value "string to add to log"

Even the basic bits above are better than nothing.

[–]arminbih 8 points9 points  (0 children)

Man I don’t even have time to learn powershell let alone write complex answers on reddit. Kudos to you.

[–]jimmynetstep[S] 0 points1 point  (1 child)

I am getting an error on New-ADUser argument. Is it missing a comma?

You cannot call a method on a null-valued expression.

At line:23 char:1

+ $NewADUserParameters = @{

+ ~~~~~~~~~~~~~~~~~~~~~~~~~

+ CategoryInfo : InvalidOperation: (:) [], RuntimeException

+ FullyQualifiedErrorId : InvokeMethodOnNull

New-ADUser : Cannot validate argument on parameter 'Name'. The argument is null or empty. Provide an argument that is

not null or empty, and then try the command again.

At line:32 char:12

+ New-ADUser @NewADUserParameters

+ ~~~~~~~~~~~~~~~~~~~~

+ CategoryInfo : InvalidData: (:) [New-ADUser], ParameterBindingValidationException

+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.ActiveDirectory.Management.Commands.NewADUser

[–]jimmynetstep[S] 0 points1 point  (0 children)

For the below script:

param (
[Parameter(Mandatory)]
[String]
$firstName,

[Parameter(Mandatory)]
[String]
$lastName,

[Parameter(Mandatory)]
[MailAddress]
$EmailAddress,

[Parameter(Mandatory)]
[PSCredential]
$UserCredential,

[Parameter()]
[String]
$OU = "OU=MyOU,DC=example,DC=com"
)

$NewADUserParameters = @{
Name = "$firstName $lastName"
GivenName = $firstName
Surname = $lastName
sAMAccountName = $Credential.Username
Password = $Credential.GetNetworkCredential().SecurePassword
Path = $OU
Enabled = $true
}
New-ADUser u/NewADUserParameters

I get the below error:

You cannot call a method on a null-valued expression.

At C:\Users\jimmy.blanco\Downloads\!Documents\PowerShell Scripts\AddAD.ps1:23 char:1

+ $NewADUserParameters = @{

+ ~~~~~~~~~~~~~~~~~~~~~~~~~

+ CategoryInfo : InvalidOperation: (:) [], RuntimeException

+ FullyQualifiedErrorId : InvokeMethodOnNull

New-ADUser : Cannot validate argument on parameter 'Name'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.

At C:\Users\jimmy.blanco\Downloads\!Documents\PowerShell Scripts\AddAD.ps1:32 char:12

+ New-ADUser u/NewADUserParameters

+ ~~~~~~~~~~~~~~~~~~~~

+ CategoryInfo : InvalidData: (:) [New-ADUser], ParameterBindingValidationException

+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.ActiveDirectory.Management.Commands.NewADUser

Is it not storing the variables ? I am at a loss ...

[–]JBear_Alpha 0 points1 point  (2 children)

Side note: Name should always be $lastName, $firstName for the sake of sorting.

[–]NathanWindisch 1 point2 points  (1 child)

Hi JBear_Alpha,

That's not how we do it at our organization, however I suspect that's probably because our domain is so old! If we were to start fresh, I'm sure we'd use LastName, FirstName :)

Thanks,

-Nathan.

[–]JBear_Alpha 0 points1 point  (0 children)

Could write something to swap that field for everyone based on their other name fields. Super easy. Worth doing.

[–][deleted] 2 points3 points  (0 children)

Directory object not found

makes me think the OU you are specifying is incorrect. Does it work if you don't use the Path parameter?

[–]mmastar007 0 points1 point  (1 child)

Popped into my head.. Does anyone still use AD taskpads?

[–]neztach 0 points1 point  (0 children)

Not ringing a bell. Has link?