I'm having some problems running a powershell script when not on the domain controller.
The idea is that a delegated user such as a principal can change the passwords for students.
On the server I have added the membership into the powershell script allowing users to remote connect.
I have tested the code line by line on an end users account and computer.
However, when I run the script the import-module active directory doesn't work.
The error I get on the screen shows that it doesn't know what get-ADUser is followed by still being connected to the remote powershell connection on the domain controller.
Enter-PSSession -ComputerName DomainController
Import-Module ActiveDirectory
Write - Host "********************************************************** `r`nDomainController - Studnet Password Configurator `r`n********************************************************** `r`n `r`nThis program will assist when a student requires a password change. `r`nPlease ensure that you verify the student prior to implementing the change. `r`n"
do
{
$TargetUser = Read-Host -Prompt 'Enter a student user ID name'
if (Get-ADUser -Filter {SamAccountName -eq $TargetUser})
{
"Process user $TargetUser"
Get-ADUser -Identity $TargetUser
$passwordchange = Read-Host -Prompt 'Would you like to change the user password? [y|n]'
if ($passwordchange -eq 'y')
{
$newPassword = Read-Host -Prompt 'Please type new password'
Set-ADAccountPassword $TargetUser -Reset -NewPassword (ConvertTo-SecureString -Force -AsPlainText '$newPassword')
Write - Host "$TargetUser` password has now been changed to: $newPassword"
}
}
else
{
Write - Host "$TargetUser` does not exist, please try again."
}
$answer = Read-Host -Prompt 'Would you like to see another user? [y|n]'
}
until ($answer -eq 'n')
Exit-PSSession
Related
I'm looking to create a simple powershell script that will import the user's first name from file, prompt to create a new password and loop on error when the password doesn't meet the password requirement based on the "ErrorVariable" if possible. If not, please advise.
# import user firstname from file
$firstname = $(Get-Content "C:\tmp\local\firstname.txt")
# prompt user for new password
$password = Read-Host "Hello, $firstname!! Please change your local admin account password. (Requirements: At least 8-characters, 1-Cap Letter, 1-Number) " -AsSecureString -Erroraction silentlycontinue -ErrorVariable PasswordError
# create new password
$password = $password
Get-LocalUser -Name "$firstname" | Set-LocalUser -Password $password -Erroraction silentlycontinue -ErrorVariable PasswordError
If ($PasswordError)
{
"Unable to update the password. The new password does not meet the length or complexity."
}
If (-Not $PasswordError)
{
"Password updated successfully!!"
See script above.........
Think you could simply use try/catch - e.g.:
try {
Set-LocalUser -Name $firstname -Password $password -Erroraction:stop
write-host "Password updated successfully!!"
}
Catch {
write-error $_
}
If the operation succeeded you will get "Password updated successfully!!", otherwise it returns the error.
I am writing the script which should validate the user in the active directory and gets some AD information. I am struggling with the error handling in this script:
$user = (Read-Host -Prompt 'Enter your network id').ToUpper()
#check if the user exists in the AD database
$userid= Get-ADUser $user | Select SamAccountName
$userid = $user
if (($user -match $userid)) {
Write-Host $user "exists in AD"
}else{
write-host "user cannot be found"
}
If someone who uses the script will put incorrect userId (which doesn't exist in AD), the script will throw an error message :
Get-ADUser : Cannot find an object with identity: 'DUMMY' under: 'DC=company,DC=com'.
At line:9 char:11
+ $memoid = Get-ADUser $user | Select SamAccountName
+ ~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (DUMMY:ADUser) [Get-ADUser], ADIdentityNotF
oundException
+ FullyQualifiedErrorId : ActiveDirectoryCmdlet:Microsoft.ActiveDirectory.Management.
ADIdentityNotFoundException,Microsoft.ActiveDirectory.Management.Commands.GetADUser
Even though incorrect userID was entered, I receive
= DUMMY exists in AD
How can I turn this exceptional error message into my custom message - "The user doesn't exist in AD"? Thank you in advance
For this, it is better not to use the -Identity parameter (which you imply in your code by using Get-ADUser $user)
Try
$userID = Read-Host -Prompt 'Enter your network id'
# check if the user exists in the AD database
# this will either return an ADUser object or $null
$user = Get-ADUser -Filter "SamAccountName -eq '$userID'" -ErrorAction SilentlyContinue
if ($user) {
Write-Host "$($user.SamAccountName) exists in AD" -ForegroundColor Green
}
else{
Write-Host "user $($user.SamAccountName) cannot be found" -ForegroundColor Red
}
You need to catch the exceptions using try/catch
In the error message, it is telling that "cannot find that object"
So, your first approach is to check whether the user exists or not in the If statement and then put them in try/catch like below
try{
$user = (Read-Host -Prompt 'Enter your network id').ToUpper()
#check if the user exists in the AD database
$userid= Get-ADUser $user | Select SamAccountName
$userid = $user
if (($user -match $userid)) {
Write-Host $user "exists in AD"
}else{
write-host "user cannot be found"
}
}
catch
{
#Your Custom Message in case of the error is coming in Std Out . $_.Exception.Message will catch the exact error message.
"Error Message: "+ "$_.Exception.Message"
}
The statement: $userid = $user needs to be deleted. As is it insures that you always have a match.
Next place your call to Get-ADUser in a Try/Catch construct to catch the error.
$user = (Read-Host -Prompt 'Enter your network id').ToUpper()
#check if the user exists in the AD database
Try {
$userid= Get-ADUser $user -EA "STOP" | Select SamAccountName
Write-Host $user "exists in AD"
}
Catch {
#*** Process errors here ***
write-host "user cannot be found"
Exit
}
#Continue your script here
Note: I don't have access to a Server so this is untested but should work in theory!
HTH
The second half of my script does not function the way I want it to. I believe I am using the incorrect cmdlet. I am trying to add a group from active directory to the local administrator account on a laptop/pc. And after this add a domain user to the power user group.
I want to pull from AD the group name, which I thought this cmdlet would do so. Any ideas?
I only ran the second half but receive errors. I have tried other cmdlets but I think this one is the most accurate.
#change computer name of the device + condition
$answer = Read-Host -Prompt 'Do you want to change the computer name?'
# First condition - 1) name comupter 2) take user creds 3) Rename computer using stored cred 4) write host if yes is the answer
if ($answer -match "yes"){
$computername = Read-Host -Prompt "What will be the name of the computer?"
#This part of the script will contain your credentials to change the computername and priveledges
$cred = Get-Credential -Message "This will be used to changed the computername. Do not worry!"
#$cred = Read-Host -Prompt "Enter your network username" - Uneeded string
Rename-Computer -NewName "$computername" -LocalCredential $cred -DomainCredential $cred
Write-Host "Computername has been changed to $computername successfully!"
}
#Second condition - If answer is no move on to second portion of the script to set privledges
elseif($answer -match "no"){
Write-Host "Moving to the next part of the script"
}
#Third condition - If answer is anything else - loop to the beginning of the script to accept the right answer
else{
write-host "Please answer with yes or no"
}
#Second half of script
#Adding AD group to local adminitrator
$localuser= Read-Host "Enter username of the PowerUser."
Add-LocalGroupMember -Group "Administrator" -Member "memeber"
Add-LocalGroupMember -Group "Power Users" -Member $localuser + "tamu.jaguar.edu"
This script is for reseting passwords on AD users if they lost it and need to make a new one. But let's say we dont know the username only their real name, so we want to search for the username and insert it to $Username.
function Reset_Password_Account () {
$Username = Read-Host "Enter your username"
Write-Host "Changing Password for account" $Username
$Newpassword = Read-Host "Enter Temporary Password" -AsSecureString
Write-Host "Running Script..."
Set-ADAccountPassword $Username -NewPassword $Newpassword
Write-Host "Temporary password set"
Set-ADUser $Username -ChangePasswordAtLogon $True
Write-Host "You can now change password on login"
# Stop powershell from exiting after script is run
Read-Host "Press enter to exit"
}
$Readhost = Read-Host "To run script: Enter y
To decline script: Enter n and exit PowerShell
Press Enter to accept your input. ( y / n )"
switch ($ReadHost) {
Y {Reset_Password_Account}
N {exit}
I would recommend using Ambiguous Name Resolution, it searches a range if AD Attributes (list in link) and finds any matches.
The example query below would return both Jimmy Smith and Jim Smith-Williams
Get-ADUser -LDAPFilter "(anr=Jim Smith)"
It will search for all objects where any of the naming attributes start with the string "jim smith*", plus all objects where (givenName=jim*) and (sn=smith*), plus objects where (givenName=smith*) and (sn=jim*).
Setup:
We are all in domain environment. Active Directory is Windows Server 2012 R2
Client Workstations are mix of Windows 10 versions (1703 and 1709)
Need to create user "Servis" on all workstation and place it to local Administrator group. I will input a text file with the host names.
This is the script im trying to make it work, but no success.
The user is created, but user is not added to local admin group.
This is the error i get :
Error creating Service23 on WinNT://WS-TEST: The following exception occurred while retrieving member "add": "The network path was not found.
$computers = Get-Content -path C:\Scripts\CreateLocalUser\New\Computers.txt
$username = "Servis"
$password = "P4$$w0rd!##"
Foreach ($computer in $computers) {
$users = $null
$computer = [ADSI]"WinNT://$computername"
Try {
$users = $computer.psbase.children | select -expand name
if ($users -like $username) {
Write-Host "$username already exists" -ForegroundColor Green
}
Else {
$user_obj = $computer.Create("user", "$username")
$user_obj.SetPassword($password)
$user_obj.SetInfo()
$user_obj.Put("description", "$username")
$user_obj.SetInfo()
$user_obj.psbase.invokeset("AccountDisabled", "False")
$user_obj.SetInfo()
$users = $computer.psbase.children | select -expand name
if ($users -like $username) {
Write-Host "$username has been created on $($computer.name)"
$group = [ADSI]("WinNT://" + $computername + "/administrators,group")
$group.add("WinNT://" + $computername + "/" + $username + ",user")
}
Else {
Write-Host "$username has not been created on $($computer.name)"
}
}
}
Catch {
Write-Host "Error creating $username on $($computer.path): $($Error[0].Exception.Message)"
}
}
Once you've defined your credential correctly with a password in a SecureString format creating a local admin is a 2 step process:
Create a user
Add that user to the Local Administrators group
These few lines are the powershell code needed:
$username = "Servis"
$password = ConvertTo-SecureString -AsPlainText "P4$$w0rd!##" -Force
New-LocalUser "$username" -Password $password -FullName "$username" -Description "Local admin $username"
Add-LocalGroupMember -Group "Administrators" -Member "$username"
If you want make you script more robust you should consider to create some Pester tests and add these checks to your script:
Validate if your file exists
Validate the content of the file (if is an IP or a FQDN with a regex)
Test if the host is reachable (e.g. Test-Connection -computername $computer -count 1 -quiet) before connecting
Using invoke-command with computername and argumentlist (username, password)
Check if the user was created successfully and is a member of the administrator group if not throwing an error
Write a log file to keep trace of all the tasks completed (by who, when on what host and so on).
I wrote a blog post on www.scriptinglibrary.com on few better ways of completing this task if you're interested.