Prepend AD User description with PS - Duplicate Update with ForEach - powershell

I've seen many code examples where Get-ADUser can be used to append a description with the following code:
get-aduser username -Properties Description | ForEach-Object { Set-ADUser $_ -Description "$($_.Description) Some more stuff" }
I had thought I could simply invert the order of the code in order to prepend, like so:
get-aduser username -properties Description | ForEach-Object { Set-ADUser $_ -Description "Stuff To Use - $($_.Description)"}
The output then becomes:
"Stuff To Use - Stuff To Use"
In essence, whatever is there to start with is wiped out completely and replaced with a doubled up result of the intended goal.
What am I missing here?

The code is good and it likely ran twice accidentally.
Reset the description, run the code, then refresh Active Directory Users and Computers and recheck.

Related

Get samaccountname from display name - but with extras

First time poster but site has helped me so much in the past.
We are an MSP and regularly get requests from clients to pull various details off a list of users they send us. Unfortunately though their lists rarely (if ever) contain any unique identifiers for AD such as samAccountName or even e-mail.
So typically I only get their first and last names, job titles etc. and use a slight variation on the below to try and get the required samAccountNames to work in batch modify scripts.
Get Samaccountname from display name into .csv
The problem comes (and caused a big headache recently) when I try to put that output back into a table to line up with the displaynames. As if the script can't find the displayname it just moves onto the next one in the list and puts the samAccountName directly below the last one it found. making it out of line with the displayname column I've put it beside.
My question is is there something I can add to the below script that when an error occurs it simply inputs null or similar into the samAccountName output csv so I could spot that easily in an excel sheet.
Similarly some users have multiple accounts like an admin and non-admin account with the same display name but different samAccountName so it pulls both of them, which is less of a problem but also if there was any way to have the script let me know when that happens? That would be super useful for future.
Import-Module activedirectory
$displayname = #()
$names = get-content "c:\temp\users.csv"
foreach ($name in $names) {
$displaynamedetails = Get-ADUser -filter { DisplayName -eq $name } -server "domain.local"| Select name,samAccountName
$displayname += $displaynamedetails
}
$displayname | Export-Csv "C:\temp\Samaccountname.csv"
So the problem lies in that you rely on Get-ADUser to provide you with user objects and when it doesn't you have gaps in your output. You instead need to create an object for every name/line in your "csv" regardless of whether Get-ADUser finds anything.
Get-Content 'c:\temp\users.csv' |
ForEach-Object {
$name = $_
$adUser = Get-ADUser -Filter "DisplayName -eq '$name'" -Server 'domain.local'
# Create object for every user in users.csv even if Get-ADUser returns nothing
[PSCustomObject]#{
DisplayName = $name # this will be populated with name from the csv file
SamAccountName = $adUser.SamAccountName # this will be empty if $adUser is empty
}
} | Export-Csv 'C:\temp\Samaccountname.csv'

GET not printing when there is another GET after it?

I've gt this script to automate removal of users for our workplace and I can't figure out why this Get doesn't print anything if there is another get after it. Is this a delay issue? or there a problem with my syntax"
#Requests user input username
$_Name=Read-Host "Enter account name you wish to disable"
#Lists the users AD groups and removes them
Get-ADPrincipalGroupMembership $_Name | select name
Get-ADUser -Identity $_Name -Properties MemberOf -Credential $_Creds| ForEach-Object {
$_.MemberOf | Remove-ADGroupMember -Members $_.DistinguishedName -Credential $_Creds -Confirm:$false
}
write-host "User has been removed from the listed groups..."
It just returns a blank space where the list should be.
To extrapolate what was mentioned in the comments:
You are currently running two separate Get commands. The first one, Get-ADPrincipalGroupMembership will generate output. It's a list of groups a principal is member of. The second Get command you're running (Get-ADUser) has it's output used in a loop and you're not printing that output. You'd need to do something like Write-Output $_.MemberOf to see it.
You're using $_.MemberOf as another input to the command Remove-ADGroupMember. For that command the documentation states:
Outputs
None or Microsoft.ActiveDirectory.Management.ADGroup
Returns the modified group object when the PassThru parameter is specified. By default, this cmdlet does not generate any output.
So unless you supply the parameter -PassThru it will consume the "output" of $_.MemberOf and not display anything.

Fax number update script, how to reverse?

I have created a script that would allow for the addition of the values "1-" to the beginning of our current AD fax numbers. I am running this in a test environment and the script runs exactly as I want it. I am looking for a failback and I can't seem to get that script to remove the "1-" it instead removes the 1 from the beginning and the final number from the end of the fax so the output looks like this: "-(###)-###-###" instead of looking like the correct number format "(###)-###-####"
Get-ADUser -Filter {facsimileTelephoneNumber -like "*"} -Properties facsimileTelephoneNumber| foreach {Set-ADUser -Identity $_ –replace #{facsimileTelephoneNumber="1-$($_.facsimileTelephoneNumber)"}}
Get-ADUser -Filter {facsimileTelephoneNumber -like "*"} -Properties facsimileTelephoneNumber| foreach {Set-ADUser -Identity $_ –replace #{facsimileTelephoneNumber="$(($_.facsimileTelephoneNumber).Substring(1,($_.facsimileTelephoneNumber.length) -2 ))"}}
Following my answer to your previous question where the 1- is added to the fax number, this is how you can reverse that.
I see in your question you are trying to do it all as one-liners, thereby skipping all possibility to check your code step-by-step. Using the first oneliner in your question also prepends 1- to simply every faxnumber found, regardless if it is needed or not.
Especially when just starting PowerShell, writing things out is a good thing.
Having said that, here's the code to remove the leading 1- from faxnumbers
# Remove leading '1-' from ADUsers faxnumbers
Import-Module ActiveDirectory
# get all users in the specified OU that have a fax number starting with '1-'
Get-ADUser -LdapFilter '(facsimileTelephoneNumber=1-*)' -SearchBase 'OU=UserAccounts,DC=YourDomain,DC=com' -Properties 'Fax' | ForEach-Object {
# using Substring() to remove the first two characters. See: https://ss64.com/ps/substring.html
$newFax = ($_.Fax).Substring(2)
Write-Host "Setting Faxnumber to '$newFax' for user $($_.Name)"
# remove the '-WhatIf' if you are sure the number may be changed
$_ | Set-ADUser -Fax $newFax -WhatIf
}
Hope this helps

Unexpected Token 'Set-ADUser' in expression when trying to change particular Descriptions in Active Directory

This is a two-fold question.
First, I'm trying to get this PS command to work (trying to pull accounts with certain characters in their description and replace those characters), and it keeps giving me the "Unexpected token 'Set-ADUser' in expression or statement." error:
Get-ADUser -Filter {description -like "*Example*"} -Properties description | ForEach-Object {$newDescription = $_.Description.Replace("Example", "Example2") Set-ADUser -Identity $_ -Description $newDescription}
I'm basing this off of what I found here (Second Answer - by Ansgar Wiechers) How to Replace Description Text for All Users in an Organizational Unit using Powershell
Any Help is much appreciated! Never used a site like this before but don't want to spend Way too much time on this.
My second question relates to the first one, with examples on the link mentioned previously. Is there a way to move to the next line in PS without hitting Enter?
The reason I ask is when I copied the code from the above link into Word, edited it, then copied into PS and ran it, it ran fine--didn't actually change anything, but it ran. When I try to run it all as one line, it throws the error.
Are people building the commands in another program when they do it like this?
You almost got it right. The only mistake was that you needed to use $_.DistinguishedName or $_.SamAccountName for the -Identity parameter of Set-ADUser.
These things happen quite often when you try and put everything on one single line like you did. This makes reading the code very hard to do.
I also have changed the .Replace into -replace. This makes it case-insensitive (same as your -Filter),so now also 'example' will be replaced by 'Example2'.
Here's the new code.
Get-ADUser -Filter { Description -like "*Example*"} -Properties Description |
ForEach-Object {
$newDescription = $_.Description -replace "Example", "Example2"
Set-ADUser -Identity $_.DistinguishedName -Description $newDescription
}

powershell script add-adgroupmember

I'm writing a script which is supposed to show me security groups by matching an input e.g. 'marketing'.
Afterwards I want to add a user to this security group. Since the exchange-powershell can search for user via -anr it's much easier to find the right person.
Here is the part of my script:
$grparray = get-adgroup -filter * | where { $_.name -match "marketing" -and $_.GroupCategory -eq 'Security' }
$potentarray = get-mailbox -anr Julia | select SamAccoutName
$grparray[1] | add-adgroupmember -members $potentarray[1]
But I get the error:
CannotConvertArgumentNoMessage,Microsoft.AcitveDirectory.Management.Commands.AddAdGroupMember
Seems like the ad-modules can't handle the Exchange input.
Does anyone know how I can solve this issue, or got another idea how to?
Ambiguous Name Resolution is available with Get-ADUser, this is preferable over Get-Mailbox as it returns an AD Object which can be used as an input for Add-ADGroupmember.
Try $potentarray = Get-ADUser -LDAPFilter "(anr=Julia)" instead of Get-Mailbox.