Hi All,
For some reasons, I can’t find the cause of this error. I’m trying to add new users into my AD Lab Environment. I tried this in the Production environment and it’s giving me the same error.
https://www.linkedin.com/groups/140856/140856-6162298147235299328?trk=hp-feed-group-discussion
See below:
PS C:\Users\Administrator> $Error[0].InvocationInfo
MyCommand :
BoundParameters : {}
UnboundArguments : {}
ScriptLineNumber : 661
OffsetInLine : 30
HistoryId : -1
ScriptName : C:\PowerShell\ADDS-SPRINT_v2.5.ps1
Line : New-ADUser -Path $agents `
PositionMessage : At C:\PowerShell\ADDS-SPRINT_v2.5.ps1:661 char:30
- New-ADUser -Path $agents `
-
PSScriptRoot : C:\PowerShell
PSCommandPath : C:\PowerShell\ADDS-SPRINT_v2.5.ps1
InvocationName :
PipelineLength : 0
PipelinePosition : 0
ExpectingInput : False
CommandOrigin : Internal
DisplayScriptPosition :
$Error[0].exception.Message
Unable to find type [System.Management.Automation.ParameterBindingValidationException]. Make sure that the assembly that contains this type is loaded.
PS C:\Users\Administrator> $agents
OU=Agents,OU=Marketing,DC=Adatum,DC=com
The link you placed in here is not working for me, LinkedIn tells me the conversation does not exist. It appears the New-ADUser account command doesn’t like something, but we’d need to be able to see the code to assist in troubleshooting.
Function Organizational-Unit
{
$script:csvPath = "C:\PowerShell\$CSVfilename2.csv"
#$script:agents="OU=Agents,OU=Marketing,DC=Adatum,DC=com"
#$script:officers="OU=Officers,OU=Marketing,DC=Adatum,DC=com"
cls
write-host " "`n `n
Write-Host "*****************************" -ForegroundColor Green
write-host `n
write-host " 1 : A G E N T S " -ForegroundColor Yellow #-BackgroundColor Gray
Write-host `n
write-host " 2 : O F F I C E R S " -ForegroundColor Red #-BackgroundColor White
Write-host `n
Write-Host "*****************************" -ForegroundColor Green
Write-host `n
write-host "Press [CTRL C] to exit." -BackgroundColor white -ForegroundColor black
Write-host `n
Write-host "CSV Filename: " -NoNewline
Write-host "$csvPath"
Write-host `n
write-host "Enter number to specify which OU" -NoNewline -ForegroundColor Cyan
$ou = Read-Host " "
Switch($ou)
{
1 { # FOR AGENTS OU
$NewUsers = import-csv $csvPath
if($? -eq $false) { Write-host `n `t "Error: Could not find CSV file 'C:\PowerShell\$CSVfilename2.CSV'" -ForegroundColor Red
Write-host `n `t "Please type in CSV filename CORRECTLY."
$error.clear()
CSV-File
Break;
}
else {
write-host "--------------------------------------"
write-host "| Adding New Users to AGENTS OU ] |" -ForegroundColor Yellow
write-host "--------------------------------------"
write-host `n
$script:ntpwd = NT-Password
$emailpassword = Email-Password
ForEach($user in $NewUsers)
{
$gn = ($user.GivenName)
$ln = ($user.SurName)
$n = ($user.name)
$dname = ($user.DisplayName)
$nt = ($user.SamAccountName)
$emailadd = ($user.EmailAddress)
$userPN = ($user.UserPrincipalName)
Try {
New-ADUser -Path $agents `
-GivenName $gn `
-Surname $ln `
-Name $n `
-DisplayName $dname `
-SamAccountName $nt `
-AccountPassword (ConvertTo-SecureString "$ntpwd" -AsPlainText -Force) `
-EmailAddress $emailadd `
-UserPrincipalName $userPN `
-Description $Description2 `
-Enabled $true -ChangePasswordAtLogon $true
$count++
continue; } #Try
Catch [Microsoft.ActiveDirectory.Management.ADIdentityAlreadyExistsException]
{
Write-host "----------------------------------------------------------------------"
Write-host " The specified account already exists. " -ForegroundColor Yellow
Write-host "----------------------------------------------------------------------"
Write-host " Duplicate name" -ForegroundColor Yellow -NoNewline
write-host " [$n]" -NoNewline
Write-host " cannot be added into the same OU. " -ForegroundColor Yellow
Write-host "----------------------------------------------------------------------"
#Write-host `n
Write-host "Please check your CSV file" -ForegroundColor Green
Write-host `n `n
if($count -gt 0) { $count-- }
else { continue; }
} #Catch
Catch [Microsoft.ActiveDirectory.Management.ADException]
{
$x = $error[$count].CategoryInfo.Targetname
Write-host "DUPLICATE ---> [ $x ]"`n -BackgroundColor black
Enter-Credentials-Agents
Retrieve-Users
Continue-Query
break; } #Catch
Catch [System.Management.Automation.ParameterBindingValidationException]
{
Write-Warning -Message
"The system has detected some empty fields on your CSV file.
Please open your CSV file with Notepad and delete the empty or white spaces with commas."
continue;
}
} #For
Retrieve-Users
Continue-Query
break;
} #Else
} #Switch AGENTS
2 { #FOR OFFICERS OU
$NewUsers = import-csv $csvPath
if($? -eq $false) { Write-host `n `t "Error: Could not find CSV file 'C:\PowerShell\$CSVfilename2.CSV'" -ForegroundColor Red
Write-host `n `t "Please type in CSV filename CORRECTLY."
$error.clear()
CSV-File
Break; }
else {
write-host "-------------------------------------" -ForegroundColor Yellow
write-host "| Adding New Users to OFFICERS OU |"
write-host "-------------------------------------" -ForegroundColor Yellow
write-host `n
$script:ntpwd = NT-Password
$emailpassword = Email-Password
ForEach($user in $NewUsers)
{
$gn2 = ($user.GivenName)
$ln2 = ($user.SurName)
$n2 = ($user.name)
$dname2 = ($user.DisplayName)
$nt2 = ($user.SamAccountName)
$emailadd2 = ($user.EmailAddress)
$userPN2 = ($user.UserPrincipalName)
Try {
New-ADUser -Path $officers `
-GivenName $gn2 `
-Surname $ln2 `
-Name $n2 `
-DisplayName $dname2 `
-SamAccountName $nt2 `
-AccountPassword (ConvertTo-SecureString "$ntpwd" -AsPlainText -Force) `
-EmailAddress $emailadd2 `
-UserPrincipalName $userPN2 `
-Description $Description2 `
-Enabled $true -ChangePasswordAtLogon $true
$count++
continue; }
Catch [Microsoft.ActiveDirectory.Management.ADIdentityAlreadyExistsException]
{
Write-host "------------------------------------------------------------"
Write-host " The specified account already exists. " -ForegroundColor Yellow
Write-host "------------------------------------------------------------"
Write-host " Duplicate name [$n] cannot be added into the same OU. " -ForegroundColor Yellow
Write-host "------------------------------------------------------------"
Write-host `n
Write-host "Please check your CSV file" -ForegroundColor Green
Write-host `n `n
if($count -gt 0) { $count-- }
else { continue; }
} #Catch
Catch [Microsoft.ActiveDirectory.Management.ADException]
{
$y = $error[$count].CategoryInfo.Targetname
Write-host "DUPLICATE ---> [ $y ]"`n -BackgroundColor black
Enter-Credentials-Agents
Retrieve-Users
Continue-Query
break; } #Catch
} #For
Retrieve-Users
Continue-Query
break;
} #Else
} #Switch Officers
#\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\#
Default
{
Write-host " "`n
Write-Warning "INVALID input."
Write-host `n "Try again? [y or n]" -ForegroundColor Yellow -NoNewline
$ans = read-host " "
if($ans -eq 'y')
{
Organizational-Unit
Continue-Query
}
elseif($ans -eq 'n')
{
Continue-Query
}
else
{
Write-host `n "ERROR: Invalid input again." -ForegroundColor DarkRed -BackgroundColor white `n
Continue-Query
}
} #Default
} #Switch Main
} #Function Organizational-Unit
Set-ExecutionPolicy Unrestricted -Force
Import-Module ActiveDirectory
Add-Type -AssemblyName System.String
Add-Type -AssemblyName System.Object
Add-Type -AssemblyName System.Management.Automation
Add-Type -AssemblyName Microsoft.ActiveDirectory.Management
Add-Type -AssemblyName Microsoft.ActiveDirectory.Management.Resources
#Remove-Variable * -ErrorAction SilentlyContinue
$error.Clear()
$ErrorActionPreference = 'SilentlyContinue'
#$agents = "OU=Sprint CBU Agents,OU=Sprint Operations,DC=sprint,DC=eperformax,DC=com" #Live Production environment
#$officers = "OU=Sprint CBU Officers,OU=Sprint Operations,DC=sprint,DC=eperformax,DC=com" #Live Production environment
$agents="OU=Agents,OU=Marketing,DC=Adatum,DC=com"
$officers="OU=Officers,OU=Marketing,DC=Adatum,DC=com"
#$live = "@sprint.eperformax.com"
#$live2 = "dc=sprint,dc=eperformax,dc=com"
$lab = "@adatum.com"
$lab2 = "dc=adatum,dc=com"
$count = 0
$path = Split-Path -Parent "C:\PowerShell\*.*"
$datetoday = get-date -Format MM-dd-yyyy
Only (Switch) 1 #Agents, is giving me that error message.
PS C:\Users\Administrator> $Error
Unable to find type [System.Management.Automation.ParameterBindingValidationException]. Make sure that the assembly that contains this type is
loaded.
At C:\PowerShell\ADDS-SPRINT_v2.5.ps1:674 char:30
=================================================================================================================
But, when I select (Switch) 2 #Officers, it’s working just fine. It does call the 3 Functions:
Enter-Credentials-Officers
Retrieve-Users
Continue-Query
#===========================================================================================================================================================================================================================================#
Function Enter-Credentials-Agents
{
Write-host "RE-ENTER CREDENTIALS TO GENERATE UNIQUE Forest-Wide Username:" -ForegroundColor Yellow
# Write-host " "`n
$script:agentFN = read-host "First Name "
$script:agentLN= read-host " Last Name "
$script:agentLN1 = $agentLN.Replace(' ','')
$script:agentFullName = $agentFN+" "+$agentLN
$script:agentDN = $agentFullName
$script:ntpwd = NT-Password
$script:emailpassword = Email-Password
#--------- GENERATE UNIQUE FOREST-WIDE USERNAME ----------#
$script:agentUN = $agentFN.Substring(0,2)+"."+$agentLN1
$script:agentUPN = $agentUN+$lab
$script:emailun = $agentFN.Substring(0,2)+$agentLN1
$script:agentmail = $emailun+$lab
#---------------------------------------------------------#
Write-host "Generating Unique Forest-wide Username..." -NoNewline -BackgroundColor DarkRed
Write-host "[ $agentUPN ]"`n `n
Try {
New-ADUser -Path $agents `
-GivenName $agentFN `
-Surname $agentLN `
-DisplayName $agentDN `
-Name $agentFullName `
-SamAccountName $agentUN `
-AccountPassword (ConvertTo-SecureString "$ntpwd" -AsPlainText -Force) `
-UserPrincipalName $agentUPN `
-Description $Description2 `
-EmailAddress $agentmail `
-Enabled $true `
-ChangePasswordAtLogon $true
$count++
continue;
} #Try
Catch [Microsoft.ActiveDirectory.Management.ADIdentityAlreadyExistsException]
{
Write-host "----------------------------------------------------------------------"
Write-host " The specified account already exists. " -ForegroundColor Yellow
Write-host "----------------------------------------------------------------------"
Write-host " Duplicate name" -ForegroundColor Yellow
Write-host " [$agentDN]" -NoNewline
Write-host " cannot be added into the same OU." -ForegroundColor Yellow
Write-host "----------------------------------------------------------------------"
Write-host "Please check your CSV file" -ForegroundColor Green
Write-hos `n `n
if($count -gt 0){ $count-- }
else { continue; }
} #Catch
} #Function
#======================================================================================================================================================================================================#
Function Enter-Credentials-Officers
{
Write-host "RE-ENTER CREDENTIALS TO GENERATE UNIQUE Forest-Wide Username:" -ForegroundColor Yellow
# Write-host " "`n
$script:firstName = read-host "First Name "
$script:lastName = read-host " Last Name "
$script:lastName1 = $Lastname.Replace(' ','')
$script:fullName = $firstName+" "+$lastName
$script:displayName = $fullName
$script:ntpwd = NT-Password
$script:emailpassword = Email-Password
#--------- GENERATE UNIQUE FOREST-WIDE USERNAME ----------#
$script:username1 = $firstName.Substring(0,2)+"."+$lastName1
$script:upn1 = $username1+$lab
$script:emailun = $firstName.Substring(0,2)+$lastName1
$script:email = $emailun+$lab
#---------------------------------------------------------#
Write-host "Generating Unique Forest-wide Username..." -NoNewline -BackgroundColor DarkRed
Write-host "[ $upn1 ]"`n `n
Try
{
New-ADUser -Path $officers `
-GivenName $firstname `
-Surname $LastName `
-DisplayName $displayName `
-Name $fullName `
-SamAccountName $Username1 `
-AccountPassword (ConvertTo-SecureString "$ntpwd" -AsPlainText -Force) `
-UserPrincipalName $upn1 `
-Description $Description2 `
-EmailAddress $email `
-Enabled $true `
-ChangePasswordAtLogon $true
$count++
continue; } #Try
Catch [Microsoft.ActiveDirectory.Management.ADIdentityAlreadyExistsException]
{
Write-host "----------------------------------------------------------------------"
Write-host " The specified account already exists. " -ForegroundColor Yellow
Write-host "----------------------------------------------------------------------"
Write-host " Duplicate name" -ForegroundColor Yellow
Write-host " [$displayName]" -NoNewline
Write-host " cannot be added into the same OU." -ForegroundColor Yellow
Write-host "----------------------------------------------------------------------"
Write-host "Please check your CSV file" -ForegroundColor Green
Write-hos `n `n
if($count -gt 0) { $count-- }
else { continue; }
}
}
#=================================================================================================================================#
# =========================================================================================================================================== #
Function Email-Password
{
#-----------------------------------------------------------------------#
$script:random = Get-date -Format MMMMddss
#------------------------------------------------------------------------#
#$chars = $array[(get-random -Maximum ([array]$array).count)]
#------------------------------------------------------------------------#
#$random = $chars+$date
#Write-host "New Password: " -ForegroundColor Green -NoNewline
return $random
}
#==================================================================================================================================#
Function CSV-File
{
Write-host `n
Write-host "------------------------------------"
Write-host "| Adding Multiple Users at Once... |"
Write-host "------------------------------------" `n
For([string]::IsNullOrWhiteSpace($CSVfilename) )
{
Write-host `n "Enter CSV file name " -NoNewline -ForegroundColor Green
$CSVfilename = Read-host " "
If([string]::IsNullOrWhiteSpace($CSVfilename) )
{
Write-host `t `n "Required: CSV filename." -ForegroundColor Red
$error.clear()
continue;
}
else
{
$script:CSVfilename2 = $CSVfilename.ToUpper()
Description
break;
}
}
}
#====================================================================================================================================#
Function Description
{
For([string]::IsNullOrWhiteSpace($Description))
{
Write-host `n "Enter Description (Batch number) " -NoNewline -ForegroundColor Green
$Description = Read-host " "
if([string]::IsNullOrWhiteSpace($Description))
{
Write-host `t `n "Required: Description or Batch number." -ForegroundColor Red
$error.clear()
continue;
}
else
{
$script:Description2 = $Description.ToUpper()
Organizational-Unit
break;
}
}
}
#=========================================================================================================================================== #
Function NT-Password
{
$script:ntpwd = "Welcome"+$Description2
return $ntpwd
}
#=========================================================================================================================================== #
cls
Function Select-Options
{
write-host `n "Enter number to select an option" -ForegroundColor yellow -NoNewline
$choice = Read-host " "
Switch($choice)
{
1 {
CSV-File
#Organizational-Unit
}
2 {
Search-User
}
3 {
LoggedIn-User
Continue-Query
}
4 {
Search-Computer
}
0 {
exit
}
Default {
Write-host " "`n
Write-Warning "INVALID input."
Write-host `n "Try again? [y or n]" -ForegroundColor Yellow -NoNewline
$ans = read-host " "
if($ans -eq 'y')
{
Select-Options
Continue-Query
}
elseif($ans -eq 'n')
{
Continue-Query
}
else
{
Write-host `n "ERROR: Invalid input again." -ForegroundColor DarkRed -BackgroundColor white `n
Continue-Query
}
}
}
}
# =========================================================================================================================================== #
Function Continue-Query
{
write-host " "`n
write-host "CONTINUE AD Operation ?? [y or n]" -ForegroundColor Cyan -NoNewline
switch(Read-host " " )
{
y
{
cls
Main-Menu
}
n
{
Write-host `n
write-host "*** TASK HAS BEEN COMPLETED ***" -ForegroundColor Cyan
exit
}
default
{
Write-warning -Message "Invalid Input."
continue;
}
}
} # End Continue-Query
# =========================================================================================================================================== #
Function Main-Menu
{
write-host `n
Write-Host "********************************" `n -ForegroundColor Green
write-host " 1 : ADD NEW USERS " `n #-ForegroundColor Yellow #-BackgroundColor Gray
write-host " 2 : SEARCH USERS " `n #-ForegroundColor Red `n #-BackgroundColor White
write-host " 3 : CHECK WHO'S LOGGED IN " `n
write-host " 4 : SEARCH COMPUTERS " `n
write-host " 0 : EXIT TO COMMAND LINE " `n
Write-Host "********************************"`n `n -ForegroundColor Green
Write-host "[ Press CTRL C to cancel ]" `n -BackgroundColor Black
Select-Options
}
# =========================================================================================================================================== #
Function LoggedIn-User
{ #Start Continue-Query
cls
Header-Menu
cmd /c echo on
cmd /c cd "%windir%\system32\"
$hostname = Read-host "Enter computer name"
Write-host `n "*** Checking who's logged in to: $hostname" -ForegroundColor Yellow `n
psexec \\$hostname query user
}
#=====================================================================================================================================================================================================#
Function Retrieve-Users
{
$when = (get-date).AddMinutes(-10).DateTime
$script:review3 = Get-ADUser -Filter * -Properties * | Where-Object {$_.whenCreated -ge $when}
if( !($review3) )
{ Write-host "NO users have been currently added in the Domain." -ForegroundColor Yellow }
if( $review3 ){
Write-host "*** New Users have just been added successfully into the Domain. ***" -Backgroundcolor DarkRed
Write-host "*** Already added into [Monitor] Security Group for Telstrat Access. ***"`n -Backgroundcolor Black
Write-host "-------------------------------------------------------------------------------"
Write-host `t `t "*** SEE LIST BELOW :" -ForegroundColor Green
Write-host "-------------------------------------------------------------------------------"
$review2 = $review3 | Select-Object -ExpandProperty SAMAccountName
Add-ADGroupMember -identity "Monitor" -Members $review2
$review3 |
Select-Object @{Label = "Name";Expression = {$_.Name}},
@{Label = "NTLogin-Username";Expression = {$_.SamAccountName}},
@{Label = "Email Address";Expression = {$_.EmailAddress}},
@{Label = "Description";Expression = {$Description2}},
@{Label = "Account Status";Expression = {if (($_.Enabled -eq 'TRUE') ) {'Enabled'} Else {'Disabled'}}}, # the 'if statement# replaces $_.Enabled
@{Label = "Date Created";Expression = {$_.whenCreated}},
@{Label = "OU Location";Expression = {$_.CanonicalName}} | FT -AutoSize
New-item -path $path -name $Description2 -itemtype directory -Force
Start-Sleep -Milliseconds 250
#----------------------------------------------------------------------------------------#
$outfile = "$path\$Description2\*.*"
$path2 = Split-Path -Parent $outfile
$csvfile = $path2 + "\NTLOGIN_EMAIL_$Description2.csv"
$txtfile = $path2 + "\PASSWORDS_$Description2.txt"
$script:msg1 = 'NTLogin-Password'
$script:msg2 = 'Email-Password'
$changepwd = ""
$note1 = "Note: NTLogin-Username and Email Address are *NOT case-sensitive."
$note2 = "*** Kindly forward this to the Trainer."
$note3 = "Passwords are case-sensitive."
$space = " "
$ntpwd = NT-Password
$emailpassword = Email-Password
#----------------------------------------------------------------------------------------#
$review3 |
Select-Object @{Label = "Name";Expression = {$_.Name}},
@{Label = "NTLogin-Username";Expression = {$_.SamAccountName}},
@{Label = "Email Address";Expression = {$_.EmailAddress}},
@{Label = "Description";Expression = {$Description2}},
@{Label = "Account Status";Expression = {if (($_.Enabled -eq 'TRUE') ) {'Enabled'} Else {'Disabled'}}}, # the 'if statement# replaces $_.Enabled
@{Label = "Date Created";Expression = {$_.whenCreated}},
@{Label = "OU Location";Expression = {$_.CanonicalName}} |
Export-Csv -Path $csvfile -NoTypeInformation -Force
Start-Sleep -Milliseconds 100
Add-Content $csvfile $space -Force
Add-Content $csvfile $note1 -Force
Add-Content $csvfile $space -Force
Add-Content $csvfile $note2 -Force
Add-Content $txtfile $note2 -Force
Add-Content $txtfile $space -force
Add-Content $txtfile "$msg1 : $ntpwd" -Force
Add-content $txtfile "$msg2 : $emailpassword" -Force
Add-Content $txtfile $space -Force
Add-Content $txtfile "NOTE: $changepwd" -Force
Write-host "-----------------------------------------------------------------------"
Write-host "| OUTPUT file 1: '$csvfile' |" -ForegroundColor Green
Write-host "-----------------------------------------------------------------------"
Write-host "| OUTPUT file 2: '$txtfile' |" -ForegroundColor Green
Write-host "-----------------------------------------------------------------------"`n
} #else
}
Ok, so that is a lot of code to digest. Here are some things I see:
-
This isn't .NET, you don't need to add assemblys. Powershell will handle much of this in the background for you. There are rare occasions when you loading an assembly is required, but there isn't anything in this script that requires loading an assembly:
Add-Type -AssemblyName System.String
Add-Type -AssemblyName System.Object
Add-Type -AssemblyName System.Management.Automation
Add-Type -AssemblyName Microsoft.ActiveDirectory.Management
Add-Type -AssemblyName Microsoft.ActiveDirectory.Management.Resources
-
Calculated expressions are for calculations, so this is unnecessary:
Select-Object @{Label = "Name";Expression = {$_.Name}}, ...
You’re not doing anything with $_.Name, so you can simply list the property:
Select-Object Name,
@{Label = "NTLogin-Username";Expression = {$_.SamAccountName}},...
-
The power of splatting. Rather than using the continuation character, you can shrink your code with splatting. It appears the switch is to simply choose a different OU location, so you're duplicating a large chunk of code just to change an OU path. If you take this code:
New-ADUser -Path $officers `
-GivenName $gn2 `
-Surname $ln2 `
-Name $n2 ` ...
and do this:
$newUserParams = @{
GivenName = $gn2;
Surname = $ln2;
Name = $n2;
}
switch ($OU) {
1{ $newUserParams.Add("Path", $agentsOUPath) }
2{ $newUserParams.Add("Path", $officerOUPath) }
default { $newUserParams.Add("Path", $defaultOUPath) }
}
New-ADUser @newUserParams
Using a splat, which is a hashtable, you can dynmically, add, remove, update parameters based on logic
-
Why go through the work of creating variables of variables?
$gn2 = ($user.GivenName)
You can just reference GivenName = $user.GivenName
-
Error handling. In order to leverage Try\Catch, you need to set the ErrorAction=Stop for New-ADUser, otherwise it will silently continue. So, if you leverage splatting referenced above, you would just add ErrorAction="Stop".
To summarize, I think you need to modularize your code better and dynamically create your New-ADUser command to start. Add the ErrorAction=“Stop” to actually stop the command and process your catches.