Powershell Modify Emailaddresses in Exchange 2010 - powershell

I am trying add text before all the email address, instead of that it overwriting and creating one copy of email address of the last. Any ideas what is causing this?
$UD = Get-Mailbox -Identity $_identity
$SmtpAdd=$UD|select -ExpandProperty EmailAddresses|Select SmtpAddress
foreach($address in $SmtpAdd)
{
$Changed="Disabled_"+$($address.SmtpAddress)
Set-Mailbox $_identity -EmailAddresses $Chnged -EmailAddressPolicyEnabled $true
}
expecting output: Disabled_rave#in.com,Disabled_raj#in.com
but it is giving: Disabled_raj#in.com,raj#in.com.
It is not adding Disabled in all the mails.

You actual results indicate that $($address.SmtpAddress) is a string. In such case, you are combing two strings:
"a" + "b,c" and the results of this operation will be "ab,c"
So you need to split $($address.SmtpAddress) by ',' ,add "Disabled_" for each element, store all new email address inside array and then join those elements as string using ',':
[array]$Changed = $null
$($address.SmtpAddress) -split ',' | % {
$Changed += "Disabled_"+ $_
}
$Changed = $Changed -join ','
Set-Mailbox $_identity -EmailAddresses $Chnged -EmailAddressPolicyEnabled $true
Hope that this will help you.

Related

Adding a string to a extensionattribute in Powershell

I try to add value X to a Active Directory Member Y that has already some values in extensionAttribute10. How do I add a specific string into that? Also I want to scan the extensionAttribute and remove a specific entry.
Testparameters:
$ThisUser = "Testaccount01"
#{extensionAttribute10=Computer01, Computer02}
$adding = "Computer03"
$delete = "Computer01"
assuming the target is a user account:
#Replace existing value with a new one
set-aduser -identity [userSamAccountName] -replace #{extensionAttribute10=$value}
#Add new value to
set-aduser -identity [userSamAccountName] -add #{extensionAttribute10=$value}
If your target is a different object type, e.g. a computer use the related cmdlets, the syntax is equal....
As response to your comment: Sure the code does work but you need to consider the datatype of the target attribute, which is not an array it's a single value. So if you need to store multiple values there you need to transform the array into a delimited string, e.g.:
$value = #('comp1','comp2')
$valueString = $value -join ","
set-aduser -identity [userSamAccountName] -add #{extensionAttribute10=$valueString}
But be aware that this attribute has a size limit.
Ok based on your code sample, you cast the output as string array ([string[]]) but as outlined earlier you need a string and not an array:
your code
$newAttribute = [string[]]($user.extensionAttribute10 -split '[,\s]+' | ?{$_ -ne $delete}) + $add
replace with:
$valueArray = #($user.extensionAttribute10 -split ',' | ?{$_ -ne $delete})
$valueArray += $add
$valueString = $valueArray -join ","
set-aduser -identity [userSamAccountName] -replace #{extensionAttribute10=$valueString}
$ThisUser = "Test"
$delete = "Computer2"
$add = "Computer3"
$user = Get-ADUser -Identity $ThisUser -Properties extensionAttribute10
$newAttribute = [string[]]($user.extensionAttribute10 -split '[,\s]+' | ?{$_ -ne $delete}) + $add
Set-ADUser $thisUser -Replace #{extensionAttribute10=$newAttribute}

Adding a ROW for missing Attribute values to Export-CSV

I using the following POWER SHELL script, to extract ( to csv ) managers name , from a "Manager" user attribute.
#This script, , Exports the Manager name of the employee`s in the TXT file.
# users.txt file - contains a simply list of user names ( samaccount-names )
Get-Content D:\powershell\permmisions\Users.txt | Foreach-Object {
Get-ADUser -Identity $_ -Properties Manager | Select-Object name, Manager | Export-Csv D:\Powershell\ADuserinformation\Export-Managers-of-specific-users.csv
-Append
}
The challenge i am facing, is when is on the exported CSV file,
the list "SKIPS" blank value-fields,In case there is no manager set for the user.
And a ROWS is not created , where MANAGER is missing.
What i would like to do , is the script to enter a charcter ( ~ ) for example, where, value is blank.
That way , a row will be created for the blank MANAGER value, on the CSV file
Please help ,
Thanks all in advance.
Note: At least the Name property should exist on all AD users retrieved, so you would get a row even for users where Manager is empty, but with an empty Manager column. If you do need to deal with possibly not all users named in Users.txt actually existing, see Theo's helpful answer.
The simplest approach is to use a calculated property:
Get-ADUser -Identity $_ -Properties Manager |
Select-Object Name, #{ Name='Manager';
Expression={ if ($_.Manager) { $_.Manager } else { '~' } } }
Note:
It is common to abbreviate the key names of the hashtable that defines the calculated property to n and e.
The if statement takes advantage of the fact that an empty string (or $null) evaluates to $false in a Boolean context; for an overview of PowerShell's implicit to-Boolean conversion, see the bottom section of this answer.
In PowerShell [Core] 7.0 or above, you could additionally take advantage of the ternary operator (<condition> ? <valueIfTrue> : <valueIfFalse>) to further shorten the command:
# PSv7+
Get-ADUser -Identity $_ -Properties Manager |
Select-Object Name, #{ n='Manager'; e={ $_.Manager ? $_.Manager : '~' } }
Note: If $_.Manager were to return $null rather than the empty string ('') if no manager is assigned, you could use ??, the PSv7+ null-coalescing operator instead: $_.Manager ?? '~'
Not concise at all, but this allows you to insert more properties of interest in your report, and does some error-checking if the user listed in your input file does not exist:
$report = foreach ($account in (Get-Content D:\powershell\permmisions\Users.txt)) {
$user = Get-ADUser -Filter "SamAccountName -eq '$account'" -Properties Manager -ErrorAction SilentlyContinue
if ($user) {
if (!$user.Manager) { $mgr = '~' }
else {
# the Manager property is the DistinghuishedName for the manager.
# if you want that in your report, just do
$mgr = $user.Manager
# if you want the Name for instance of that manager in your report,
# comment out the above line and do this instead:
# $mgr = (Get-ADUser -Identity $user.Manager).Name
}
# now output an object
[PsCustomObject]#{
UserName = $user.Name
Manager = $mgr
}
}
else {
Write-Warning "User '$account' does not exist"
}
}
# output on screen
$report | Format-Table -AutoSize
# output to CSV file
$report | Export-Csv -Path 'D:\Powershell\ADuserinformation\Export-Managers-of-specific-users.csv' -NoTypeInformation

Find AD-user by Email

I'm trying to get users from active directory, who have a certain email address.
I've got a CSV-File, which contains the emails.
$data = import-csv -path .\are.csv -delimiter +
foreach($i in $data)
{
get-aduser -filter {UserPrincipalName -like '$i.email'}
}
My problem is, that I don't get any output. No error, no data. When I replace $i.email with one of the email addresses, I get the right user information for the one user. So hard coding works.
When I do:
foreach($i in $data)
{
$i.email
}
I get a list of all the emails.
What is wrong with the code?
Your variable is within single quotes thus doesn't get populated. You have to three options to fix that:
Use double quotes with a sub expression $():
UserPrincipalName -like "$($i.email)"
Just omit the quotes:
UserPrincipalName -like $i.email
And finally you could use a format string (even with single quotes):
UserPrincipalName -like ('{0}' -f $i.email)
Here is an example to demonstrate what actual value gets passed using the Write-Host cmdlet:
$data =
#'
email, id
myname#web.de, 1
'# | convertfrom-csv
foreach($i in $data)
{
Write-Host '$i.email' # This is your current approach
Write-Host "$($i.email)"
Write-Host $i.email
Write-Host ('{0}' -f $i.email)
}
Output:
$i.email # This is the output of your current approach
myname#web.de
myname#web.de
myname#web.de

Add "_" before all SMTP addresses in Exchange

I'm looking script that help me to add "_" before all SMTP addresses in Exchange.
Let's say we have a user John Doe. John has 3 different SMTP addresses:
john.doe#contoso.com
jdoe#domain.com,
john#contoso.com
I'd like to change disable all features in Exchange (like OWA, ActiveSync and so on), hide his account in GAL and set all his addresses to:
_john.doe#contoso.com
_jdoe#domain.com,
_john#contoso.com
I can do it for primary SMTP but I can't for rest of them :(
For Now I have try such solution:
Set-Mailbox $sam -HiddenFromAddressListsEnabled $true -DomainController $dmc
Set-CasMailbox $sam -OWAEnabled $false -ActiveSyncEnabled $false -MAPIEnabled $false -PopEnabled $false -ImapEnabled $false -DomainController $dmc
mbx = Get-Mailbox $sam -DomainController $dmc | select -expand EmailAddresses | %{$_.SmtpAddress}
foreach ($M in $mbx)
{
[string]$email += "'smtp:_"+$M+"',"
}
but it doesn't works for me. I'm quite fresh in PS so could you please help me.
Multiple issues:
The main problem is that you're generating a list of the new addresses, but you're not modifying the mailbox objects. Just running a foreach loop against results queried from a mailbox isn't going to modify that object. You need to use Set-Mailbox to actually set the new addresses:
Set-Mailbox -EmailAddresses <new_addresses>
The way you're creating the string, it will have a trailing comma. If you want to create a comma-separated string from strings generated by a loop, do it this way:
$email = $(foreach ($m in $mbx) {
"'smtp:_" + $m + "'"
}) -join ','
The loop returns an array of the strings generated by each iteration, and the -join ',' joins them into a comma-separated string.
That said, you actually don't want to join them into a comma-separated string, because the -EmailAddresses parameter of Set-Mailbox takes an array argument. So, you just want to use the return value of the loop as the argument.
Adding the smtp: prefix is unnecessary because that's the default.
On the other hand, if you're only modifying SMTP addresses, you do want to use Where-Object to filter the contents of the EmailAddresses property for SMTP addresses:
?{$_.Prefix.ToString() -eq 'smtp'}
Putting it all together:
foreach ($mbx in (Get-Mailbox <whatever>)) {
$modified_addresses = $mbx.EmailAddresses `
| ?{$_.Prefix.ToString() -eq 'smtp'} `
| select -ExpandProperty EmailAddresses `
| %{"_$_"}
Set-Mailbox $mbx -EmailAddresses $modified_addresses
}

How to skip empty cells in a csv when using PowerShell to import Email Addresses?

I am trying to run the following script to import email addresses in powershell:
Import-CSV "C:\AliasesTest.csv" | foreach-object {
Set-Mailbox -Display Name $_.Name -EmailAddresses #{add=$_.Alias1,$_.Alias2,$_Alias3}}
It works fine, unless the csv has an empty cell under one of the Alias columns, at which point the following error is produced:
"The address '' is invalid: "" isn't a valid SMTP address..:
How can I construct my script to just ignore empty cells when it comes across them?
Check each property (alias) to see if it is empty, and only add the ones with values to the array inside your hash table:
Import-CSV "c:\AliasesTest.csv" | ForEach-Object {
#Save the CSV row for use in another loop later
$CSV = $_
Set-Mailbox -DisplayName $_.Name -EmailAddresses #{add = ("Alias1","Alias2","Alias3" | ForEach-Object { $Csv.$_ } | Where-Object{$_}) }
}
What that craziness does is, create a new hashtable with a key "add" that has a value of a sub expression. The sub expression has an array of property names that you want to check that it iterates over, converting each name to the value of that property, then filters out the empty ones.
Use a Where-Object filter prior to ForEach-Object like this:
Import-CSV "C:\AliasesTest.csv" | Where-Object {
$_.Alias1 -and $_.Alias2 -and $_Alias3
} | foreach-object { $_ }
If the alias' are empty strings they will be skipped. You don't have to use -and for all of them, if just one value is fine change to use -or.
Filter the aliases to take out the empty ones:
Import-CSV "C:\AliasesTest.csv" | foreach-object {
$aliases = #($_.Alias1,$_.Alias2,$_Alias3) | where-object{$_};
Set-Mailbox -Display Name $_.Name -EmailAddresses #{add=$aliases}}