Powershell issue extracting primary SMTP while having multiple smtps - powershell

Was looking around and found this little powershell script. BAsically want to be able to export all my primary SMTP and username from AD.
Get-ADUser -Filter * -Properties proxyaddresses | Select-Object Name, #{L = "ProxyAddresses"; E = {($_.ProxyAddresses | Where-Object {$_ -like "*SMTP:*" }) -join ';'} | Export-Csv -Path C:\Users\mohammad.anwar\Documents\proxyaddresses.csv -NoTypeInformation
The output would give me multiple smtp. Im looking for the Primary SMTP.

The logic of your query is fairly sound. There are just some syntax and operator issues with producing the result you want.
Get-ADUser -Filter * -Properties ProxyAddresses |
Select-Object Name, #{L = "ProxyAddresses"; E = {($_.ProxyAddresses -clike "SMTP:*") -join ';'}} |
Export-Csv -Path C:\proxyaddresses.csv -NoTypeInformation
Most PowerShell Comparison Operators are case-insensitive. The case-sensitive operators begin with -c. -clike should be used instead of -like when case matters.
Since ProxyAddresses will be a collection, you don't need Where-Object (if running PowerShell 3+). You can just compare the ProxyAddresses values directly. PowerShell will enumerate the collection.
I honestly can't think of a case where an account would have multiple primary SMTP addresses (the SMTP: address). So having a -join doesn't make much sense since -join attempts to join items of a resulting collection. If you want to query all SMTP addresses (including lowercase smtp:) for an account, then -join would make sense here.
In your attempt, you will see >> when the code is run at the console. The reason is because you did not close all of your open {. The hash table for the Select-Object calculated property (begins with #{) was never closed. The PowerShell console has this behavior when an opening (, {, or quote is not closed properly.

Try the below.
This is a very common thing with plenty of examples all over the web showing how to do this. Why do this from ADDS vs native Exchange cmdlets to get this info by default.
You can use remoting to get the Exchange cmdlets for use via your
workstation.
Of course, searching for 'PowerShell get primary SMTP address' delivers examples for Exchange native and ADDS options.
Examples:
Get-Mailbox -ResultSize Unlimited |
Select-Object SamAccoutnName, DisplayName, PrimarySmtpAddress
# Or this...
Get-Mailbox -Identity $UID |
Select -ExpandProperty PrimarySmtpAddress
# Or via ADDS cmdlets or other
Get-ADUser -LDAPFilter "(proxyAddresses=*)" -Properties sAMAccountName, proxyAddresses |
Select sAMAccountName, proxyAddresses |
ForEach {
$Name = $User.sAMAccountname
$Addresses = $User.proxyAddresses
ForEach ($Address In $Addresses)
{
If ($Address -cmatch "SMTP:")
{"User $Name has primary address $Address" }
}
}
Identify primary SMTP Address from Active Directory with PowerShell
# First, we need to get the ProxyAddresses attribute from AD :
Get-ADUser -Identity SomeUserName -Properties ProxyAddresses |
select -ExpandProperty ProxyAddresses
# Then, we need to identify the one that starts with “SMTP:” :
# We used the “clike” operators, which is case sensitive :
Get-ADUser -Identity SomeUserName -Properties ProxyAddresses |
select -ExpandProperty ProxyAddresses |
? {$_ -clike "SMTP:*"}

Related

How to output Name or DisplayName of members of shared mailbox in Powershell

I'm trying to output a list of members of a shared mailbox by selecting displayName. I have the below script which will output the users userPrincipalName(UPN), the problem with this is our users login with an ID number, for example when I run the script I get the output: 666777#mycompany.com I would like to output the actual name of the user so I don't have to go to Active Directory and type in 666777 to find out the name of the user. The script I use is:
Get-Mailbox -Identity "NorthOffice#mycompany.com" -ResultSize:Unlimited | Get-MailboxPermission | Select-Object User
The above script outputs for example:
User
----
666777#mycompany.com
I've tried using: | Select-Object displayName but these properties show as empty/blank
Anyone know a way around this?
EDIT
I've found a way to do it but it's quite long winded:
I export the results of the script into a csv
Get-Mailbox -Identity "NorthOffice#mycompany.com" -ResultSize:Unlimited | Get-MailboxPermission | Select-Object User | Export-csv c:\myfolder\NorthOffice.csv
I then change the header of the csv to userPrincipalName and save. I then import the csv and run a 'ForEach' like below:
Import-Csv C:\myfolder\NorthOffice.csv | ForEach {
Get-ADUser -Filter "userPrincipalName -eq '$($_.userPrincipalName )'" -Properties Name, SamAccountName | Select Name,SamAccountName
} | Export-CSV -path C:\myfolder\NorthOfficeOutput.csv -NoTypeInformation
Does anyone know a quicker way to achieve this?
Try this:
Get-MailboxPermission -Identity "NorthOffice#mycompany.com" | select -ExpandProperty User | findstr /v /c:"NT AUTHORITY\SELF" | foreach {Get-ADUser -Identity ($_ -split "#")[0] -Properties * | select displayName} | sort
Get-ADUser won't accept UserPrincipalName as Identity (but it will accept SamAccountName), so we split the SMTP address at the "#" to get just the first part. (This, of course, assumes that the UPN and SMTP address are the same, and the first part of the SMTP address is the same as the SamAccountName.)
If this does not work for you, and you don't need to drop back to AD, you can just use Get-Mailbox to resolve the DisplayName directly from Exchange:
Get-MailboxPermission -Identity "NorthOffice#mycompany.com" | select -ExpandProperty User | findstr /v /c:"NT AUTHORITY\SELF" | foreach {Get-Mailbox -Identity $_ | select displayName} | sort

Need SMTP Address for Accepted Senders, ManagedBy and ModeratedBy in Distribution List

So I'm working in PowerShell to pull some data down from my exchange server.
I'm looking to get the following fields from the distribution list.
Display Name, SAM Account Name, Primary SMTP Address, Accepted Senders, Moderation Enabled, ModeratedBy, Internal Senders Only, and Managed By.
I'm using the below script to do this.
$props = #(
"DisplayName"
"SamAccountName"
"PrimarySmtpAddress"
#{Name="Accepted Senders";Expression= {(([string]($_.AcceptMessagesOnlyFromSendersOrMembers | foreach {$_.tostring().split("/")[-1]+';'})).TrimEnd(";") | foreach {$_.split(", ")[2,3,0]})}}
"ModerationEnabled"
#{Name="ModeratedBy";Expression= {([string]($_.ModeratedBy | foreach {$_.tostring().split("/")[-1]+';'})).TrimEnd(";")}}
#{Name="Internal Senders Only";E={$_.RequireSenderAuthenticationEnabled}}
#{Name="ManagedBy";E= {(([string]($_.ManagedBy | foreach {$_.tostring().split("/")[-1]+';'})).TrimEnd(";").split(", ")[2,3,0])}}
)
Get-DistributionGroup -ResultSize Unlimited | select $props | export-Csv x:\xxxxx\test6.csv -NoTypeInformation
Which works basically perfectly, except that is lists the display name of the Accepted Senders, ManagedBy and ModeratedBy instead of the smtp address.
To make it even more interesting, the email smtp format is first.last#company.com while the display names are Last, First often with additional words such as inactive and mixed in.
I have been able to format the data for managedby and accepted Senders so that the names show as first last as long as there is only one name and it doesn't have additional words in the Display Name, but I can't get it to insert a period so that I can pipe the output to a get-aduser request for the SMTP.
Anyway, let me know if you can help.
Ryan
If you want to interact with AD, you can do the following with your calculated property:
#{
n='Accepted Senders'
e={($_.acceptmessagesonlyfromsendersormembers | Foreach-Object {
(Get-AdUser -Filter "DisplayName -eq '$_'" -Property ProxyAddresses |
Select -Expand ProxyAddresses | Where-Object {$_ -cmatch '^SMTP:'}) -replace '^SMTP:'}) -join ';'}
}
I don't know if your code $_.tostring().split("/")[-1] is causing you problems or not. However, if you need that functionality, you can change to the following:
#{
n='Accepted Senders'
e={($_.acceptmessagesonlyfromsendersormembers | Foreach-Object {
(Get-AdUser -Filter "DisplayName -eq '$($_.Split('/')[-1])'" -Property ProxyAddresses |
Select -Expand ProxyAddresses | Where-Object {$_ -cmatch '^SMTP:'}) -replace '^SMTP:'}) -join ';'}
}

How do I split content from a command line

My question is how I split content prompted from a command line in powershell
I want to find all the OU's path on my server, so I can use them later on..
get-aduser -Filter * | Select DistinguishedName | findstr "OU="
OUTPUT
CN=Username1,OU=firma1,DC=bc,DC=local
CN=Username2,OU=firma2,DC=ad,DC=local
and I want only
OU=firma1,DC=bc,DC=local
OU=firma2,DC=ad,DC=local
This should work:
Get-ADUser -Filter * |
Where-Object { $_.DistinguishedName.IndexOf('OU=') -gt 0 } |
ForEach-Object { $_.DistinguishedName.Substring($_.DistinguishedName.IndexOf('OU=')) }
This code filters out any objects that aren't in an OU, which includes those which are in the Users built-in container, like CN=Administrator,CN=Users,DC=bc,DC=local. You could also handle those users with an if statement in the ForEach-Object.
How about using the .NET String.Split method directly
Get-ADUser -Properties DistinguishedName | ForEach-Object {
$_.DistinguishedName.Split(",", 2)[1]
}
This splits the DistinguishedName into two parts at the comma (i.e. everything before the first comma and everything after) and returns the second part only (array index [1]).
I would probably add a Sort-Object and a Select-Object -Unique to the end of that.
Worth a read: Get-ADOrganizationalUnit, maybe that is what you are actually are looking for?
This approach is similar, with the PowerShell-native -split operator:
$DNs = Get-ADUser -Properties DistinguishedName | Select -ExpandProperty DistinguishedName
$DNs -split ',',2 | where { $_.StartsWith("OU=") }

Get AD Group Names from List and Group Members Properties with Powershell

I'm trying to Get-Content from a text file which includes AD group names. Then from this group list get the AD user properties for each member samaccountname, name, enabled properties of the user. The output I'd like to see would look something like this for each group in the text file.
Group Name
samaccountname name enabled
I managed to get the correct output but cannot get it output properly as the Write-Host result cannot be output to a file. Here is the script that gets what I want (well sort of - the first group name appears above the header).
$ErrorActionPreference = "SilentlyContinue"
Get-Content D:\ADGroups.txt | Where{$_ -ne $null -and $_.trim() -ne ""} |
foreach{
$Group = $_
Write-Host "$Group"
Get-ADGroup -Identity $Group -Properties members |
Select-Object -ExpandProperty members |
Get-ADUser -Properties samaccountname, enabled |
Select samaccountname, name, Enabled
}
I've searched and found similar scripts but none of them produced the results I'm looking for.
You should simply be able to do (with optimizations):
# Apply Silent Errors to only the functions you trust
$SC = ${ErrorAction="SilentlyContinue"}
cat "D:\ADGroups.txt" #SC | ? {"$_".trim()} | % {
$Group = $_
"$Group"
Get-ADGroup -Identity $Group -Properties members #SC |
Select -ExpandProperty members |
Get-ADUser -Properties samaccountname, enabled #SC |
Select samaccountname,name,enabled
} | Out-File "D:\Final-Output.txt"
This is because Write-Host writes directly to the shell and is ignored by PowerShell's stdout stream handling.

Finding AD Distro Group samaccountname with email address

I need to move a few hundred AD distro groups to a new OU. I was given their email address only, and wanted to make a script to move them based on samaccountname. I am wondering why the below does not return anything, if I do the groups one-off filtering for email address it works, but foreach returns nothing.
The "groups.txt" listed below is just a list of email addresses.
gc groups.txt | % {
Get-ADGroup -Filter {mail -eq "$_"}| Select-Object -ExpandProperty SamAccountName
}
Remove the quotes you have around $_.
gc groups.txt | % {
Get-ADGroup -Filter {mail -eq $_}| Select-Object -ExpandProperty SamAccountName
}
In your posted filter script block the variable is quoted. Since it is a script block, PowerShell doesn't do any processing first and the ActiveDirectory module expects a variable not surrounded in quotes. That would look for Mail that is literally "$_" and not the email address value of the variable.
Take the "" off of $_
gc groups.txt | %{ Get-ADGroup -Filter {mail -eq "$_"} | select -expandproperty samaccountname}