Finding mailbox server - powershell

I'm trying to write down a powershell script that will automatically finds the mailbox server and connect to it (using the URI https://mailboxserver/powershell).
Problem is I haven't found a way to automatically detect a mailbox server for a given exchange organization. I found a way how to find the CAS server because someone posted how the outlook finds this manually.
I tried to query AD but I do not know which attribute is unique to exchange mailbox server.
I also tried DNS records but found none which helps.
Does anybody know about a unique value of mailbox server which could be queried from AD or GC? Or a DNS record or something else I have not thought of?
Exchange 2010
I could post forest and domain functional level if necessary but I am on the way.
Thanks in advance

Your AD user attributes have this information, albeit you have to parse the mailbox server name from them.
HomeMTA
msExchHomeServerName
So if you have access to the AD cmdlets you might be able to get your mailbox server this way.
$adUser = get-aduser someuser -Properties msExchHomeServerName
$mailboxServerName = ($aduser.msExchHomeServerName -split "cn=")[-1]
Those attributes help you find your current mailbox is hosted. The mailbox server in my case was the last "item" in msExchHomeServerName so I split the string on "cn=" and then the last element of that array would be my mailbox server name.
Then you can use that to connect to an Exchange session!
$Credentials = Get-Credential
$exchangePath = "http://$mailboxServerName/PowerShell/?SerializationLevel=Full"
$ExSession = New-PSSession –ConfigurationName Microsoft.Exchange –ConnectionUri $exchangePath -Credential $Credentials –Authentication Kerberos
Import-PSSession $ExSession

Does the code below get you what you need? It uses EWS - see my SO post for further details on EWS.
# load the assembly
[void][Reflection.Assembly]::LoadFile("D:\Temp\Microsoft.Exchange.WebServices.2.2\lib\40\Microsoft.Exchange.WebServices.dll")
# set ref to exchange - may need to change the version
$s = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010_SP2)
# replace with your email address
$email = "your.email#domain.com"
# grab your own credentials
$s.UseDefaultCredentials = $true
# discover the url from your email address
$s.AutodiscoverUrl($email)
$s.Url.AbsoluteUri

Related

How does New-MigrationBatch work?

Does New-MigrationBatch create New-MoveRequest for each user internally?
Can somebody explain to me how New-MigrationBatch works internally?
New-MigrationBatch cmdlet is use to submit a new migration request for a batch of users. It helps to Move mailboxes to different databases in on-premises Exchange organizations.
Example to take input from CSV file:
#It creates a migration batch for a local move, where the mailboxes in the specified CSV file are moved to a different mailbox database.
#This CSV file contains a single column with the email address for the mailboxes that will be moved.
#The header for this column must be named EmailAddress.
$InputCSV="C:\Users\Administrator\Desktop\Input.csv"
New-MigrationBatch -Local -Name MyFirstBatch -CSVData ([System.IO.File]::ReadAllBytes($InputCSV)) -TargetDatabases MyLocalDB
Start-MigrationBatch -Identity MyFirstBatch
Note: You can use AutoStart in order to run batches automatically.
To create a migration endpoint for the on-premises Exchange server, and then uses that endpoint to create the migration batch.
$InputCSV="C:\Users\Administrator\Desktop\FirstBatch.csv"
$Endpoint = New-MigrationEndpoint -ExchangeOutlookAnywhere -Name Endpoint -Autodiscover -EmailAddress user#domain.com -Credentials $Credentials
$StagedBatch1 = New-MigrationBatch -Name FirstBatch -SourceEndpoint $Endpoint.Identity -CSVData ([System.IO.File]::ReadAllBytes($InputCSV))
Start-MigrationBatch -Identity $FirstBatch.Identity
For Further reference, Please visit Technet--New-MigrationBatch
Hope it helps.

How to get SMTP server name through PowerShell when $PSEmailServer is empty?

Windows 7, PowerShell 4.0. Computer is in the Windows domain.
I need to get SMTP server name (for using of the send-mailmessage cmdlet). The $PSEmailServer is empty.
I read this TechNet page about the Get-AcceptedDomain cmdlet. But I see this (on the TechNet page):
This cmdlet is available in on-premises Exchange Server 2016 and in
the cloud-based service.
How can I get SMTP server name or its IP-address?
If properly defined, the SMTP server address, either host name or IP, can be set through the SCP record in AD or Autodiscover DNS record of Exchange Server. There is a Powershell solution for querying SCP but Autodiscover solution is shorter, so I'll go on with it.
This works on Exchange Server 2010 and later. It should work with Exchange Server 2007 also but personally I have never used it.
You can get the host name;
$MailServer = [Net.DNS]::GetHostByAddress([Net.DNS]::GetHostEntry("Autodiscover").AddressList[0]).Hostname
or IP address (as string);
$MailServer = [Net.DNS]::GetHostByAddress([Net.DNS]::GetHostEntry("Autodiscover").AddressList[0]).AddressList[0].IPAddressToString
Since the GetHostByAddress(string) returns an instance of class System.Net.IPHostEntry, you can have some properties to make use of. For details, please read Microsoft Docs.
PS: I know, that's not the best practice to use the index of integers for values, but AddressList is an array of strings. So it does not define a method such as FirstOrDefault() or a property like DefaultAddress. So far, that is the most optimal and practical solution AFAIK.
Assuming the computer is member of a domain with Exchange deployed, and you want to use Exchange as STMP relay for send-mailmessage, you could ask the exchange configuration in the AD Configuration Context:
import-module activedirectory
$ag = "Exchange Administrative Group (ABCDEFGHIJKLM)" #enter your EAD
$c = "Acme" # Enter your company name (get this form ADSIEdit if unknown)
$sb = ("CN=Servers,CN=" + $ag + ",CN=Administrative Groups,CN=" + $c + ",CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=staff,DC=hsrw")
$server = Get-ADObject -Properties cn, msExchSMTPReceiveConnectorFQDN, msExchSmtpReceiveBindings, msExchSMTPReceiveInboundSecurityFlag -SearchBase $sb -filter { objectClass -eq "msExchSmtpReceiveConnector"}
$server | ft cn, msExchSMTPReceiveConnectorFQDN, msExchSmtpReceiveBindings, msExchSMTPReceiveInboundSecurityFlag
This will spit out the hostnames and port bindings of every receive connector in your organisation. You then have to choose which one to use.
As I don't know how much Exchange knowledge you have, I will stop here. If something's unclear, just ask.

Send mail from powershell as anonymous user

I've always used the cmdlet Send-MailMessage without specifying any -Credential. Now I need to send mail using the anonymous user. The workaround I've found is this piece of code
$pass = ConvertTo-SecureString "anyString"-AsPlainText -Force
$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList "NT AUTHORITY\ANONYMOUS LOGON",$pass
Send-MailMessage -Credential $cred #...
It works, but is this the correct method to get the anonymous is and send anonymous mail?
You can send mail from any address, it just depends on whether the receiving mail server cares about whether it can verify the sending user or not.
For example if you send from anon#microsoft.com and microsoft does not have that account, OR they have SPF records to indicate whether the sending mail server is valid or not, then the receiving mail server might(not always) reject it.
Just make sure your email user actually exists and has a valid domain... and you can send from anonymous# or noreply# or whatever you want to.
Okay, from the comments we know we're dealing with an Exchange server. Whether or not it will do an anonymous relay depends on the configuration of the Recieve Connectors. But those restrictions only apply to the network connections. If you run Send-MailMessage on the Exchange server and use 'LocalHost' as your SMTPServer it didn't go through a receive connector so those restrictions don't apply.
If you have remoting enabled on the Exchange server you can use that to do a local invocation to send email without having to modify the Receive Connector configurations:
$EmailParams =
#{
To = '<Email To>'
From = '<Email From>'
Subject = '<Email Subject>'
Body = '<Email Body>'
SMTPServer = 'localhost'
}
$Scriptblock = [Scriptblock]::Create(
"Send-MailMessage $(&{$args} #EmailParams) ")
Invoke-Command -ScriptBlock $Scriptblock -ComputerName ExchangeServer

Having trouble binding to Active Directory with specified credentials

As part of my current role, I frequently find myself having to work with objects in one of my organisation's resource forests. At the moment in order to do that, I use an RDP session connected to a server within that forest, and authenticate to it with a specific "Admin" account in that forest.
I'm starting to find this tedious, and so I've been trying to come up with a nice profile.ps1 which will get me a DirectoryEntry for the resource forest that I can work on with Powershell (v2.0) on my local workstation instead, and save me the tedium of constantly re-establishing RDP sessions.
So I've got some code in my profile.ps1 which looks like this:
$resforest = "LDAP://DC=ldap,DC=path,DC=details"
$creds = Get-Credential -credential "RESOURCE_FOREST\my_admin_account"
$username = $creds.username
$password = $creds.GetNetworkCredential().password
$directoryentry = New-Object System.DirectoryServices.DirectoryEntry($resforest,$username,$password)
All of this proceeds fine, however, when I come to actually use the entry thus:
$search = New-Object DirectoryServices.DirectorySearcher($directoryentry)
$search.filter = "(&(anr=something_to_look_for))"
$search.findall()
I get a logon failure.
Now, I know the credentials are fine, I can map drives with them from my workstation to machines in the resource forest - and that works fine - so what am I ballsing up here?
PS - Please don't ask me to do anything with Quest's AD cmdlets - they're not allowed here.
Turns out the issue was with the serverless binding I was attempting to do.
If I modify the LDAP path to "LDAP://ldap.path.details/DC=ldap,DC=path,DC=details" then everything works.
Thanks for everyone who at least looked at the question ;)

PowerShell, Exchange 2010 Addressbook

It is possible to access Exchange 2010 Addressbook from a PowerShell Script which is running on a client?
I want to access the addressbook, search by properties and work with the results.
I have not found any tutorial for the EWS and PowerShell.
[Reflection.Assembly]::LoadFrom("path to ews.dll")
$ExchangeService = new-object ExchangeServiceBinding
$paramName = New-Object UserConfigurationNameType
$paramName.Item = New-Object FolderIdType
$paramName.Name = "CategoryList"
$params = New-Object GetUserConfigurationType
$params.UserConfigurationName = $paramName
$params.UserConfigurationProperties = [UserConfigurationPropertyType]::ALL
$ExchangeService.UseDefaultCredentials
$ExchangeService.Url = "https://path.to.exchange/EWS/Exchange.asmx"
$ExchangeService.GetUserConfiguration($params)
I don't know about PowerShell, but you can accomplish this in Exchange Management Shell (EMC). PowerShell v2.0+ can run remote sessions, so the EMC commands can be used from your clients. Of course they'll need some Exchange rights to do this. Conveniently in Exchange 2010, RBAC allows you to give miniscule Exchange rights to your users. If this is not an option, you could do an LDAP query (that's what Outlook does) but I'm not sure of the exact procedure.
However, if it is an option:
1. Initiate your remote PowerShell session.
1a. $session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionURI http://FQDNofCAS/PowerShell/ -Authentication Kerberos
1b. Import-PSSession $session
After that, try one of the following:
1. Get-GlobalAddressList
1b. Note the GAL you'll be using
2. $GAL = (Get-GlobalAddressList "Default Global Address List").DistinguishedName
2b. Replace _Default GAL_ with the output of step one.
3. Get-GlobalAddressList $GAL | Update-GlobalAddressList
4. Get-Recipinet -Filter {Addresslistmembership -eq $GAL}
4b. -Filter may require some tweaking to your specifics.
Note: See http://www.msexchange.org/articles_tutorials/exchange-server-2007/management-administration/address-lists-exchange-2007-part1.html for a better explanation of this.
--OR--
1. Get-User | where($_.RecipientType -like "*Mail*"}
Note: This will show all Mail-Enabled users, so it might not be exactly what you're looking for.
You need the Exchange EWS Managed API:
http://msdn.microsoft.com/en-us/library/dd637749.aspx