Missing Terminator and Missing Closing in PowerShell - powershell

I'm quite new to PowerShell, so apologies if this should be obvious to me.
I have the following PowerShell script;
$FieryChasm = {
Clear-Host
Write-Host "`n This script is for dropping user accounts from the Active Directory.`n`n`n It will :`n`n - Disable the AD account`n - Reset the AD password`n - Move the account to the Disabled OU`n - Set the expiry date on the account to yesterday's date`n - Remove all # groups`n- Hide the user from the email exchange`n`n`n`n Input the UserID`n"
$UserID = Read-Host -Prompt ' '
Clear-Host
$title = "`n You input '$UserID'"
$message = "`n`n Are you certain you want to process this UserID as a leaver?`n`n`n`n"
$yes = New-Object System.Management.Automation.Host.ChoiceDescription " &Yes", `
"Yes, process this userID as a leaver.`n"
$no = New-Object System.Management.Automation.Host.ChoiceDescription " &No", `
"No, take me back a step so I can input the UserID again.`n"
$options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no)
$result = $host.ui.PromptForChoice($title, $message, $options, 1)
Clear-Host
switch ($result)
{
0 {
Write-Host "`n Disabling account...`n"
Disable-ADAccount -Identity $UserID
Write-Host "`n Moving to OU 'Disabled Accounts'...`n"
Move-ADObject -Identity $UserID -TargetPath "OU=Disabled Accounts,DC=my-company,DC=co,DC=uk"
Write-Host "`n Resetting password...`n"
$YouShallNotPass = (Get-Random -input "Da$her","Danc%r","Pr$ncer","V!xen","C$met","Cup!d","Donn%r","Bl!tzen") + (Get-Random -Minimum 1000 -Maximum 999999) + (Get-Random -input "Da$her","Danc%r","Pr$ncer","V!xen","C$met","Cup!d","Donn%r","Bl!tzen")
Set-ADAccountPassword -Reset -NewPassword $YouShallNotPass –Identity $UserID
Write-Host "`n Setting expiry date...`n"
$Yesterday = (Get-Date).AddDays(-1).ToString('dd/MM/yyyy')
Set-ADAccountExpiration $UserID -DateTime $Yesterday
Write-Host "`n Removing AD groups...`n"
Get-ADuser $UserID -property MemberOf | % {$_.MemberOf | Get-ADGroup | select Name | sort name} | clip
Get-ADGroup -Filter 'name -like "#*"' | Remove-ADGroup -identity $UserID
Write-Host "`n Hiding user from Exchange...`n"
Set-Mailbox -Identity DOMAIN\$UserID -HiddenFromAddressListsEnabled $true
Write-Host "`n Completed.`n`n $UserID has been processed as a leaver.`n`n`n Press any key to go back to the fiery chasm from whence you came ..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
}
1 {
Write-Host "`n You selected No.`n`n User was NOT set as a leaver.`n`n`n Press any key to go back to the fiery chasm from whence you came ..."
}
}
.$FieryChasm
}
and I'm getting the following errors...
At C:\Users\user\Desktop\LeaverScript.ps1:64 char:148
+ ... ce you came ..."
+ ~
The string is missing the terminator: ".
At C:\Users\user\Desktop\LeaverScript.ps1:34 char:8
+ 0 {
+ ~
Missing closing '}' in statement block.
At C:\Users\user\Desktop\LeaverScript.ps1:33 char:5
+ {
+ ~
Missing closing '}' in statement block.
At C:\Users\user\Desktop\LeaverScript.ps1:1 char:15
+ $FieryChasm = {
+ ~
Missing closing '}' in statement block.
+ CategoryInfo : ParserError: (:) [], ParseException
+ FullyQualifiedErrorId : TerminatorExpectedAtEndOfString
Could someone explain why, and give some tips on me not making the same mistake again?
Thank you.

Ah, got it!
On line 37, which was this;
Set-ADAccountPassword -Reset -NewPassword $YouShallNotPass -Identity $UserID
the dash before 'Identity' was an incorrect Unicode character. I replaced it and the errors went away :)

Related

Argument Passed into ScriptBlock Doesn't Work on Last Iteration

I'm using the following script to run through all of the servers in a specified Active Directory OU and log out the specified user. This runs perfectly well for the first 35 servers but always errors out on the very last server it iterates through. The error is:
Program 'quser.exe' failed to run: Object reference not set to an instance of an object. At line:6 char:24
+ $result = (quser $userAccount)
+ ~~~~~~~~~~~~~~~~~~.
At \\path\to\script.ps1:79 char:5
+ invoke-command -ComputerName $server -ScriptBlock $scriptBlock -A ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (Program 'quser....~~~~~~~~~~~~~~.:String) [], RuntimeException
+ FullyQualifiedErrorId : Program 'quser.exe' failed to run: Object reference not set to an instance of an object.At line:6 char:24
+ $result = (quser $userAccount)
+ ~~~~~~~~~~~~~~~~~~.
My reading of the error is that it thinks $userAccount has no value. Is that correct and, if so, can anyone point at what I'm missing? Thank you in advance!
Write-Host " "
Write-Host "This script will log out all active sessions for the specified user. Proceed with caution." -ForegroundColor Black -BackgroundColor Yellow
Write-Host " "
$servers = [System.Collections.ArrayList]::new()
foreach ($server in (Get-ADComputer -SearchBase "OU=FictionalDepartment,DC=Company,DC=net" -Filter "OperatingSystem -like 'Windows Server*'" -Properties Name | select -ExpandProperty name))
{
$servers.add($server) | Out-Null
}
$servers.Sort()
$userAccount = Read-Host "Enter account to log out"
Write-Host " "
foreach ($server in $servers)
{
$scriptBlock = {
param($userAccount)
$ErrorActionPreference = 'Stop'
try
{
$result = (quser $userAccount)
$session = ((quser $userAccount)[1] -split "\s+")[2]
logoff $session
Write-Host " The user was logged into session #$session. They have been LOGGED OFF." -ForegroundColor Yellow
}
catch
{
if ($_.Exception.Message -match 'No user exists')
{
Write-Host " User is not logged in." -ForegroundColor Green
}
else
{
throw $_.Exception.Message
}
}
}
Write-Host "$server"
Invoke-Command -ComputerName $server -ScriptBlock $scriptBlock -ArgumentList $userAccount
$session = $null
}
Based on feedback, I modified the script so that it no longer uses Invoke-Command, but parses the active sessions by running quser <user> /SERVER:<server> as follows:
Write-Host "Will log specified user out of all servers..." -ForegroundColor Black -BackgroundColor Yellow
Write-Host " "
$servers = [System.Collections.ArrayList]::new()
foreach ($server in (Get-ADComputer -SearchBase "OU=Fictional,DC=Company,DC=net" -Filter "OperatingSystem -like 'Windows Server*'" -Properties Name | select -ExpandProperty name))
{
$servers.add($server) | Out-Null
}
$servers.Sort()
$userAccount = Read-Host "Enter account to scan for"
Write-Host ""
foreach ($server in $servers)
{
Write-Host "$server"
$ErrorActionPreference = 'Stop'
try
{
$session = ((quser $userAccount /SERVER:$server)[1] -split "\s+")[3]
logoff /SERVER:$server $session
Write-Host " The user was logged into session #$session. They have been LOGGED OFF." -ForegroundColor Yellow
}
catch
{
if ($_.Exception.Message -match 'No user exists')
{
Write-Host " User is not logged in." -ForegroundColor Green
}
}
}

A fairly Simple Script, but cannot see what is wrong here

I have written a fairly simple script, to simply retrieve users via the UserPrinsipalName. It fails with the following error:
Get-AdUser : Property: 'UserPrincipalName' not found in object of type: 'System.Management.Automation.PSCustomObject'.
At C:\Temp\changeUPN.ps1:8 char:16
+ ... serObject = Get-AdUser -Filter {UserPrincipalName -eq $Obj.UserPrinci ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Get-ADUser], ArgumentException
+ FullyQualifiedErrorId : ActiveDirectoryCmdlet:System.ArgumentException,Microsoft.ActiveDirectory.Management.Commands.GetADUser
$Csv = Read-Host "Enter Path to the Csv file"
$sps = Import-csv -Path $Csv
Foreach ($Obj in $Sps) {
Write-Host "Splitting UPN $($Obj.UserPrincipalName) to retreive domain information" -ForegroundColor Green
$Domain = ($Obj.UserPrincipalName -split "#")[1]
Write-Host "$($Obj.UserPrincipalName) is located in $($Domain)" -ForegroundColor Green
Write-Host "Getting AD Object" -ForegroundColor Green
$UserObject = Get-AdUser -Filter {UserPrincipalName -eq "$Obj.UserPrincipalName"} -Server $Domain
If ($UserObject) {
Write-Host "UserObject $($UserObject.DistinguishedName) Retrieved" -ForegroundColor Green
Write-Host "Changing UPN" -ForegroundColor Green
$NewUpn = $Obj.UserPrincipalName -Replace ("$Domain", "Contoso.com")
Write-Host "New UserPrincipalName = $($NewUpn)" -ForegroundColor Green
$UserObject | Set-AdUser -UserPrincipalName $NewUpn
}
Else {
Write-Host "Could not retrieve $($Obj.UserPrincipalName) from $($Domain)" -ForegroundColor Yellow
}
}

student multi add user script, broken filter on get-aduser

hi just student trying to Bulk add Users from a .csv
when using this, its breaking at the User Filter, but I'm unsure why
error says this line is the issue
" if (Get-ADUser -F { sAMAccountName -eq $username })
Get-ADUser: The search filter cannot be recognized"
i think the csv import is fine but I'm new to this so not really sure what causing the filter to break
$ADUsers = Import-csv 'Path'
#$apiRequest = Get-Content -Raw -Path path.json | ConvertFrom-Json
foreach ($User in $ADUsers) {
$firstName = $user.FirstName
$surname = $user.Surname
$branch = $user.Branch
$city = $user.City
$country = $user.Country
$company = $user.CompanyName
$countryCode = $user.CountryCode
$email = $user.Email
$userType = $User.UserType
$vaildUsernameFormat = "[^a-zA-Z_]" # anything that's _not_ a-z or underscore
$username = ($firstName.$surname) -replace $vaildUsernameFormat, '' #removes anything that isn't a-z
$ou = $User.ou
#Check if the user account already exists in AD
if (Get-ADUser -F { sAMAccountName -eq $username }) {
#If user does exist, output a warning message
Write-Warning "A user account $username has already exist in Active Directory."
}
else {
#If a user does not exist then create a new user account
New-ADUser `
-co $country
-company $company
-countryCode $countryCode
-department $department
-displayName $username
-sn $surname
-st $streetName
-title $title
}
}
thanks for anything you can offer
full error message is
Get-ADUser : The search filter cannot be recognized
At "path" csv.ps1:41 char:13
+ if (Get-ADUser -F { sAMAccountName -eq $username }) {
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-ADUser], ADException
+ FullyQualifiedErrorId : ActiveDirectoryServer:8254,Microsoft.ActiveDirectory.Management.Commands.GetADUser

Add Multiple Users To AD, CSV

I'm attempting to import users via a CSV folder.
I have certain parameters that need to be kept, so I'm only using certain fields.
Powershell
$csv = Import-Csv -Path "newusers.csv"
foreach ($User in $csv)
{
#region Data Generation
$DisplayName = $User.'Surname' + " " + $User.'GivenName'
$Mail = $User.'GivenName' + "." + $User.'Surname' + "#" + "royalberkshire.nhs.uk"
$MailAlias = $User.'GivenName' + "." + $User.'Surname' + "#" + $DNSRoot2
$SInitial = $User.'Surname'[0]
$Initial = $User.'GivenName'[0]
$SAMAccountName = $User.'Surname' + "" + $Initial
$SAMAccountLower = $SAMAccountName.ToLower()
$UserPrincipalName = $User.'Surname'+$Initial
$HD = "U"
$HDir = "\\RBHFILRED002\"
$AC = "Users_01$\"
$DH = "Users_02$\"
$IM = "Users_03$\"
$NS = "Users_04$\"
$TZ = "Users_05$\"
$Folder = if ($SInitial -in 'a','b','c'){$AC}
ElseIf ($SInitial -in 'd','e','f', 'g','h'){$DH}
ElseIf ($SInitial -in 'i','j','k', 'l','m'){$IM}
ElseIf ($SInitial -in 'n','o','p', 'q','r','s'){$NS}
Else {$TZ}
$group1 = "zz Everyone"
$group2 = "Safeboot Domain Users"
$defaultname = $SAMAccountName
$email = $User.'GivenName' + "." + $User.'Surname'
$i = 1
cls
# Create The User
While ((Get-ADUser -Filter "SamAccountName -eq '$SAMAccountName'" -ErrorAction SilentlyContinue) -ne $null){
$SamAccountName = $defaultname + [string]$i
$Mail = $email + [string]$i + "#" + "royalberkshire.nhs.uk"
$i++
}
$NewUserParams = #{
path = "OU=Users,OU=RBFT,DC=rbbh-tr,DC=nhs,DC=uk"
SamAccountName = $SAMAccountName
Name = $SAMAccountName
DisplayName = $DisplayName
GivenName = $User.'GivenName'
Surname = $User.'Surname'
EmailAddress = $Mail
UserPrincipalName = "$SAMAccountName#rbbh-tr.nhs.uk"
Title = $title
HomeDrive = $HomeDrive
HomeDirectory = "$HDir$Folder$SAMAccountName"
Description = $User.'Description'
ChangePasswordAtLogon = $true
PasswordNeverExpires = $false
AccountPassword = $password
Enabled = $true
}
New-ADUser #NewUserParams -ErrorAction SilentlyContinue
Add-ADGroupMember -Identity $group1 -Members $SAMAccountName
Start-Sleep -s 10
Add-ADGroupMember -Identity $group2 -Members $SAMAccountName
cls
echo "Please Wait Whilst We Create The AD Account & Create The Exchange Mailbox.."
Start-Sleep -s 30
Enable-Mailbox -Identity $SAMAccountName
cls
echo "Please Wait Whilst We Activate The Exchange Mailbox..."
Start-Sleep -s 15
# Sets The User Up With The Randomised Password, And Re-Encrypts It For Double Protection
Set-ADAccountPassword -Identity $SAMAccountName -Reset -NewPassword (ConvertTo-SecureString -AsPlainText $random -Force)
cls
}
CSV
User GivenName Surname Description
User James Timms Test
User James Timms Test
User Hulk Hogan Test
User Ultimate Warrior Test
User The Rock Test
User Dwayne Johnson Test
The script does not run. It tells me that the Search Filter Cannot Be Recognized.
It just errors on me.
It works with a single user fine using Write-Hosts and Inputs.
However with the CSV it doesn't work.
I must note, this is also the first time I've created users via a CSV on powershell.
Does anybody have any idea on how to fix this issue?
I got it working,
Turns out when I was building the CSV within Excel 2016 it wasn't adding the commas to seperate values.
I ended up opening the CSV within notepad and added commas to separate the values.
Powershell reads the Values based on Comma Seperation, so if there are no commas, it doesn't know what values to push out.

powershell - new-aduser skip empty cells CSV - attributes with -

I really really need your help. I got a task to create/import users from csv to AD.
But I have two problems
not all the user have all the attributes filled = there are empty "cells" in CSV
Two custom attributes contains dash - and PSH is returning error that this is not allowed.
I tried to search, there are some solutions but I am not sure how to implement it to my file (| ForEach-Object {$CSV = $_ ?????. Cant make it work.
Here is what I have so far
Import-Module ActiveDirectory
$ErrorActionPreference = 'SilentlyContinue'
$ScriptDir = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent
$log = "$ScriptDir\Error-Import.log"
$log1 = "$ScriptDir\Success-Import.log"
$date = Get-Date
$inputFile = Import-CSV $ScriptDir\allusers.csv
Function cUser
{
"ERROR LOG from (" + $date + ") :" | Out-File $log -Append
"————————————————-" | Out-File $log -Append
"Following accounts has been successfully created (" + $date + ") :" | Out-File $log1 - Append
"————————————————-" | Out-File $log1 -Append
foreach($line in $inputFile)
{
$sam = $line.samaccoutnname
#check if user already exists
$exists = Get-ADUser -LDAPFilter "(sAMAccountName=$sam)"
if (!$exists)
{
# when does not exists - load data from CSV and set as variable
$gn = $line.givenName
$sn = $line.sn
$title = $line.title
$stAd=$line.streetAddress
$upn = $line.sAMAccountName + "`#targetrange.local"
$city=$line.l
$st=$line.st
$postc=$line.postalCode
$ehrd=$line.award-hireDate
$comp=$line.company
$dvs=$line.division
$edvs=$line.award-subdivision
$dept=$line.department
$st=$line.street
$tarA=$line.targetAddress
$dn=$line.displayName
$ext2=$line.extensionAttribute2
$ext4=$line.extensionAttribute4
$ext5=$line.extensionAttribute5
$alias = $line.sAMAccountName
$cn=$line.cn
$hdir=$line.unixHomeDirectory
$desc=$line.description
$pat = $line.OU
$pwd = $line.pass
$spass =ConvertTo-SecureString -AsPlainText -Force -String $pwd
$aexp=$line.accountExpires
$Expconv=(Get-Date $aexp ).ToFileTime()
New-ADUser -SamAccountName $alias -UserPrincipalName $upn -GivenName $gn -Surname $sn -title $title -StreetAddress $stAd -l $city -State $st -PostalCode $postc -award-hireDate $ehrd -Company $comp -Division $dvs -award-subdivision $edvs -Department $dept -street $st -targetAddress $tarA -extensionAttribute2 $ext2 -extensionAttribute4 $ext4 -extensionAttribute5 $ext5 -DisplayName $dn -Name $cn -unixHomeDirectory $hdir -Description $Desc -path $pat -AccountExpirationDate $Expconv -AccountPassword $spass -PassThru | Enable-ADAccount
$exists1 = Get-ADUser -LDAPFilter "(sAMAccountName=$sam)"
if ($exists1)
{
"User successfully created : " + $sam | Out-File $log1 -Append
}
Else
{
"SKIPPED – MISSING OR INCORRECT VALUES : " + $sam | Out-File $log -Append
}
}
# if user already exists - skip and write to logfile
Else
{
"SKIPPED – ALREADY EXISTS OR DUPLICATE ALIAS : " + $sam | Out-File $log -Append
}
}
"————————————————-" + "`n" | Out-File $log -Append
}
createUsers
# finito
}
If you can help, it would save my life :-) How to skip empty cells??? And to make attributes with - working - apostrophe is enough? 'award-hiredate' ?
You mentioned that you wanted to skip empty cells. I am not sure how far you wanted to take that but here is something I think does the trick. You have the line.
$inputFile = Import-CSV $ScriptDir\allusers.csv
I would propose it gets updated as follows
$inputFile = Import-CSV $ScriptDir\allusers.csv | Where-Object{$_.psobject.properties.value -notcontains ""}
What this will do is break each entry into an array of its values. If any of the values are empty or "" then they will not be matched into the $inputFile.
Count EventID EventType
----- ------- ---------
14 Information
2 7040 Information
2 0
1 8224 Information
The above data was put into the filter and the output was
Count EventID EventType
----- ------- ---------
2 7040 Information
1 8224 Information
As you can see the lines with empty data are filtered out and the data structure is still preserved.
The Hyphen
As for the hyphen - issue I'm assuming the error you are getting is Unexpected token '-Type' in expression or statement. Guessing it is trying to treat the -hireData in $line.award-hireDate. What you are trying to do is the best in this case. Just use quotes around the parameter name. You would do the same if the parameter had a space in it.
$line."award-hireDate"
$line."award hireDate"