ExchangePowershell: Difference between revisions

From Piszczynski
No edit summary
 
(31 intermediate revisions by 3 users not shown)
Line 1: Line 1:


== Handy Commands ==
== Connect to O365 Exchange ==
Set-MailboxFolderPermission “CalendarName:\calendar” –User default –AccessRights reviewer
<syntaxhighlight lang="powershell" line>$UserCredential = Get-Credential
<nowiki>
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $UserCredential -Authentication Basic -AllowRedirection
• Send on Behalf
Import-PSSession $Session -DisableNameChecking</syntaxhighlight>
This will grant Charles permissions to send on behalf of Gert.
 
Then to close the session
<syntaxhighlight lang="powershell">Remove-PSSession $Session</syntaxhighlight>
 
 
Hide O365 group from GAL ( as this cannot be done on admin portal )
<syntaxhighlight lang="powershell">Set-UnifiedGroup <group> -HiddenFromAddressListsEnabled $true</syntaxhighlight>
 
 
Install the exchange online management module
<syntaxhighlight lang="powershell">Install-Module -Name ExchangeOnlineManagement -RequiredVersion 2.0.3</syntaxhighlight>
 
== Connect to Remote Exchange Shell ==
Use the following commands to connect to an exchange server using powershell:<syntaxhighlight lang="powershell">
$UserCredential = Get-Credential
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://<ServerFQDN>/PowerShell/ -Authentication Kerberos -Credential $UserCredential
Import-PSSession $Session -DisableNameChecking
</syntaxhighlight>
 
== Handy Commands for Exchange Powershell ==
*Add permission to calendar:
**This will give a user permissions to another calendar
<syntaxhighlight lang="powershell">Set-MailboxFolderPermission “CalendarName:\calendar” –User default –AccessRights reviewer</syntaxhighlight>
 
*Send on Behalf
**This will grant Charles permissions to send on behalf of Gert.
<syntaxhighlight lang="powershell">
Set-Mailbox gert.mailbox -GrantSendOnBehalfTo charles.surname
Set-Mailbox gert.mailbox -GrantSendOnBehalfTo charles.surname
• Send As
</syntaxhighlight>
This will grant Charles permissions to send as Gert.
 
*Send As
**This will grant Charles permissions to send as Gert.
<syntaxhighlight lang="powershell">
Add-ADPermission gert.mailbox -ExtendedRights Send-As -user charles.surname
Add-ADPermission gert.mailbox -ExtendedRights Send-As -user charles.surname
• Full Mailbox Access
</syntaxhighlight>
This will grant Charles full access to Gert's mailbox.
 
Add-MailboxPermission -Identity gert.mailbox -User charles.surname</nowiki>
*Full Mailbox Access
**This will grant Charles full access to Gert's mailbox.
<syntaxhighlight lang="powershell">
Add-MailboxPermission -Identity gert.mailbox -User charles.surname
</syntaxhighlight>
 
 
Add full access permission to all mailboxes to an account:
<syntaxhighlight lang="powershell">
Get-Mailbox -ResultSize unlimited -Filter {(RecipientTypeDetails -eq 'UserMailbox') -and (Alias -ne 'Admin')} | Add-MailboxPermission -User UserAccount@domain.com -AccessRights fullaccess -InheritanceType all -AutoMapping:$False
</syntaxhighlight>
 
 
Add Send as permissions to mailboxes:
<syntaxhighlight lang="powershell">
$UserMailboxes = Get-Mailbox | Where {$_.RecipientTypeDetails -eq “<Type of mailbox>”}
$UserMailboxes | Add-RecipientPermission -AccessRights SendAs –Trustee <identity>
</syntaxhighlight>
 
 
Get all disconnected mailboxes:
<syntaxhighlight lang="powershell">
$dbs = Get-MailboxDatabase; $dbs | foreach {Get-MailboxStatistics -Database $_.DistinguishedName} | where {$_.DisconnectReason -eq "Disabled"} | Format-Table DisplayName,Database,DisconnectDate
</syntaxhighlight>
 
 
Reconnect Mailbox:
<syntaxhighlight lang="powershell">
Connect-Mailbox -Identity "<mailbox name>" -Database <database shown in previous check>  -User "<user name>"
</syntaxhighlight>
 
 
Get mailbox sizes
<syntaxhighlight lang="powershell">
Get-Mailbox -ResultSize Unlimited | Get-MailboxStatistics | Sort-Object TotalItemSize -Descending | Select-Object DisplayName,TotalItemSize
Get-OutlookProvider | fl
Get-OutlookAnywhere | fl
Get-ClientAccessServer | fl
Get-ActiveSyncVirtualDirectory | fl
Get-AutodiscoverVirtualDirectory | fl
Get-EcpVirtualDirectory | fl
Get-OabVirtualDirectory | fl
Get-OwaVirtualDirectory | fl
Get-PowerShellVirtualDirectory | fl
Get-WebServicesVirtualDirectory | fl
Get-SendConnector | Where-Object {$_.Enabled -eq $true} | fl
</syntaxhighlight>
 
 
==Exchange Certificates==
Get and assign exchange certificates
<syntaxhighlight lang="powershell">Get-ExchangeCertificate | Format-List FriendlyName,Subject,CertificateDomains,Thumbprint,Services</syntaxhighlight>
<syntaxhighlight lang="powershell">Enable-ExchangeCertificate -Thumbprint <certificate thumbprint> -Services POP,IMAP,IIS,SMTP</syntaxhighlight>
 
 
 
Update send and receive connector certificates:
 
Find out what connectors may need updating with new certificate:
<syntaxhighlight lang="powershell">Get-ReceiveConnector | where {$_.TlsCertificateName -like "<certificate name>"}</syntaxhighlight>
<syntaxhighlight lang="powershell">Get-SendConnector | where {$_.TlsCertificateName -like "<certificate name>"}</syntaxhighlight>
 
 
Get new certificate:
<syntaxhighlight lang="powershell">$cert = Get-ExchangeCertificate -Thumbprint <NewCertificateThumbprint></syntaxhighlight>
 
 
Get details required for send/receive connector format:
<syntaxhighlight lang="powershell">$tlscertificatename = "<i>$($cert.Issuer)<s>$($cert.Subject)"</syntaxhighlight>
 
 
Set the certificate for send/receive connector
<syntaxhighlight lang="powershell">Set-ReceiveConnector "<ReceiveConnectorName>" -TlsCertificateName $tlscertificatename</syntaxhighlight>
 
== Exchange issues Powershell==
 
Get active backend components
<syntaxhighlight lang="powershell">
Get-ServerComponentState <ServerName> | ft Component,State –Autosize
</syntaxhighlight>
 
 
Get Mail Queue
<syntaxhighlight lang="powershell">
Get-Queue
</syntaxhighlight>
 
 
Check event viewer for Backpressure events: 15004 15005 15006 15007
<syntaxhighlight lang="powershell">
Get-EventLog -ComputerName <servername> -LogName Application -After (Get-Date).AddDays(-1) | where {$_.EventID -eq "15004"}
</syntaxhighlight>
 
 
Check the Database availability groups cmdlet - use to find out if exchange server is the Primary or Secondary
<syntaxhighlight lang="powershell">
Get-DatabaseAvailabilityGroup
</syntaxhighlight>
 
 
You can get all the details you need by using the following command:
<syntaxhighlight lang="powershell">
Get-DatabaseAvailabilityGroup | fl
Get-DatabaseAvailabilityGroup -status
</syntaxhighlight>
 
Sometimes the witness will fail, you can check the status of the witness by using the cluster resource cmdlet:
<syntaxhighlight lang="powershell">
ipmo failoverclusters
Get-ClusterResource
</syntaxhighlight>
 
 
This will tell you where the witness stores the file. If the DAG finds the resource unrelibale it might mark it as failed - you can restart this by using start-cluster resource:
<syntaxhighlight lang="powershell">
Get-ClusterResource | Start-ClusterResource
</syntaxhighlight>
 
Get the log for the cluster
<syntaxhighlight lang="powershell">
Get-ClusterLog -Destination <File pathway>
</syntaxhighlight>
 
== Set remote mailbox for hybrid / shared mailboxes ==
For when there is on-prem and O365 mailboxes
 
- Need a local user in domain for the shared mailbox for permissions
 
In Office 365:
 
1. <syntaxhighlight lang="powershell">Get-Mailbox nameofmailbox@domain.com | fl ExchangeGuid
Get-Mailbox nameofmailbox@domain.com | fl ExchangeGuid
</syntaxhighlight>In Exchange on-premise powershell:
 
2. <syntaxhighlight lang="powershell">
Enable-RemoteMailbox nameofmailbox@domain.com -RemoteRoutingAddress nameofmailbox@domain.mail.onmicrosoft.com
</syntaxhighlight>
 
3. <syntaxhighlight lang="powershell">
Set-RemoteMailbox nameofmailbox@domain.com -ExchangeGuid <GUID recorded from step 1>
</syntaxhighlight>
 
== Add O365 mailbox to local exchange ==
When a hybrid deployment has shared mailboxes created in O365 there can be issues if on-prem devices try to use the mailboxes. This is because there is no AD object for the mailbox on the local exchange. You will need to create a new remote mailbox object in the on-prem exchange server:<syntaxhighlight lang="powershell">
New-RemoteMailbox -Shared -Name "sharedmailboxname" `
 
-Firstname "sharedmailboxname" `
 
-LastName "sharedmailboxname" `
 
-UserPrincipalName "sharedmailboxname@domain.org" `
 
-OnPremisesOrganizationalUnit "OU=users,DC=domain,DC=local" `
 
-RemoteRoutingAddress "sharedmailboxname@domain.mail.onmicrosoft.com"
</syntaxhighlight>
 
==Exchange online issues==
 
Clear old problems with hybrid exchange conflicts by removing old mailbox configurations from user objects:
 
Log into exchange online with connect-exchangeonline:
<syntaxhighlight lang="powershell">
Set-User <problem user objectid> -PermanentlyClearPreviousMailboxInfo
</syntaxhighlight>
 
== Exchange message tracking logs ==
on the on prem exchange server you can use the following cmdlet to check the exchange message logs for the last two hours:<syntaxhighlight lang="powershell">
Get-MessageTrackingLog  -start (get-date).AddHours(-2) | ? {$_.recipients -eq "<user@domain.com>"}
</syntaxhighlight>

Latest revision as of 17:33, 14 August 2024

Connect to O365 Exchange

$UserCredential = Get-Credential
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $UserCredential -Authentication Basic -AllowRedirection
Import-PSSession $Session -DisableNameChecking

Then to close the session

Remove-PSSession $Session


Hide O365 group from GAL ( as this cannot be done on admin portal )

Set-UnifiedGroup <group> -HiddenFromAddressListsEnabled $true


Install the exchange online management module

Install-Module -Name ExchangeOnlineManagement -RequiredVersion 2.0.3

Connect to Remote Exchange Shell

Use the following commands to connect to an exchange server using powershell:

$UserCredential = Get-Credential
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://<ServerFQDN>/PowerShell/ -Authentication Kerberos -Credential $UserCredential
Import-PSSession $Session -DisableNameChecking

Handy Commands for Exchange Powershell

  • Add permission to calendar:
    • This will give a user permissions to another calendar
Set-MailboxFolderPermission “CalendarName:\calendar” –User default –AccessRights reviewer
  • Send on Behalf
    • This will grant Charles permissions to send on behalf of Gert.
Set-Mailbox gert.mailbox -GrantSendOnBehalfTo charles.surname
  • Send As
    • This will grant Charles permissions to send as Gert.
Add-ADPermission gert.mailbox -ExtendedRights Send-As -user charles.surname
  • Full Mailbox Access
    • This will grant Charles full access to Gert's mailbox.
Add-MailboxPermission -Identity gert.mailbox -User charles.surname


Add full access permission to all mailboxes to an account:

Get-Mailbox -ResultSize unlimited -Filter {(RecipientTypeDetails -eq 'UserMailbox') -and (Alias -ne 'Admin')} | Add-MailboxPermission -User UserAccount@domain.com -AccessRights fullaccess -InheritanceType all -AutoMapping:$False


Add Send as permissions to mailboxes:

$UserMailboxes = Get-Mailbox | Where {$_.RecipientTypeDetails -eq “<Type of mailbox>”}
$UserMailboxes | Add-RecipientPermission -AccessRights SendAs –Trustee <identity>


Get all disconnected mailboxes:

$dbs = Get-MailboxDatabase; $dbs | foreach {Get-MailboxStatistics -Database $_.DistinguishedName} | where {$_.DisconnectReason -eq "Disabled"} | Format-Table DisplayName,Database,DisconnectDate


Reconnect Mailbox:

Connect-Mailbox -Identity "<mailbox name>" -Database <database shown in previous check>  -User "<user name>"


Get mailbox sizes

Get-Mailbox -ResultSize Unlimited | Get-MailboxStatistics | Sort-Object TotalItemSize -Descending | Select-Object DisplayName,TotalItemSize
Get-OutlookProvider | fl
Get-OutlookAnywhere | fl
Get-ClientAccessServer | fl
Get-ActiveSyncVirtualDirectory | fl
Get-AutodiscoverVirtualDirectory | fl
Get-EcpVirtualDirectory | fl
Get-OabVirtualDirectory | fl
Get-OwaVirtualDirectory | fl
Get-PowerShellVirtualDirectory | fl
Get-WebServicesVirtualDirectory | fl
Get-SendConnector | Where-Object {$_.Enabled -eq $true} | fl


Exchange Certificates

Get and assign exchange certificates

Get-ExchangeCertificate | Format-List FriendlyName,Subject,CertificateDomains,Thumbprint,Services
Enable-ExchangeCertificate -Thumbprint <certificate thumbprint> -Services POP,IMAP,IIS,SMTP


Update send and receive connector certificates:

Find out what connectors may need updating with new certificate:

Get-ReceiveConnector | where {$_.TlsCertificateName -like "<certificate name>"}
Get-SendConnector | where {$_.TlsCertificateName -like "<certificate name>"}


Get new certificate:

$cert = Get-ExchangeCertificate -Thumbprint <NewCertificateThumbprint>


Get details required for send/receive connector format:

$tlscertificatename = "<i>$($cert.Issuer)<s>$($cert.Subject)"


Set the certificate for send/receive connector

Set-ReceiveConnector "<ReceiveConnectorName>" -TlsCertificateName $tlscertificatename

Exchange issues Powershell

Get active backend components

Get-ServerComponentState <ServerName> | ft Component,State –Autosize


Get Mail Queue

Get-Queue


Check event viewer for Backpressure events: 15004 15005 15006 15007

Get-EventLog -ComputerName <servername> -LogName Application -After (Get-Date).AddDays(-1) | where {$_.EventID -eq "15004"}


Check the Database availability groups cmdlet - use to find out if exchange server is the Primary or Secondary

Get-DatabaseAvailabilityGroup


You can get all the details you need by using the following command:

Get-DatabaseAvailabilityGroup | fl
Get-DatabaseAvailabilityGroup -status

Sometimes the witness will fail, you can check the status of the witness by using the cluster resource cmdlet:

ipmo failoverclusters
Get-ClusterResource


This will tell you where the witness stores the file. If the DAG finds the resource unrelibale it might mark it as failed - you can restart this by using start-cluster resource:

Get-ClusterResource | Start-ClusterResource

Get the log for the cluster

Get-ClusterLog -Destination <File pathway>

Set remote mailbox for hybrid / shared mailboxes

For when there is on-prem and O365 mailboxes

- Need a local user in domain for the shared mailbox for permissions

In Office 365:

1.

Get-Mailbox nameofmailbox@domain.com | fl ExchangeGuid
Get-Mailbox nameofmailbox@domain.com | fl ExchangeGuid

In Exchange on-premise powershell: 2.

Enable-RemoteMailbox nameofmailbox@domain.com -RemoteRoutingAddress nameofmailbox@domain.mail.onmicrosoft.com

3.

Set-RemoteMailbox nameofmailbox@domain.com -ExchangeGuid <GUID recorded from step 1>

Add O365 mailbox to local exchange

When a hybrid deployment has shared mailboxes created in O365 there can be issues if on-prem devices try to use the mailboxes. This is because there is no AD object for the mailbox on the local exchange. You will need to create a new remote mailbox object in the on-prem exchange server:

New-RemoteMailbox -Shared -Name "sharedmailboxname" `

-Firstname "sharedmailboxname" `

-LastName "sharedmailboxname" `

-UserPrincipalName "sharedmailboxname@domain.org" `

-OnPremisesOrganizationalUnit "OU=users,DC=domain,DC=local" `

-RemoteRoutingAddress "sharedmailboxname@domain.mail.onmicrosoft.com"

Exchange online issues

Clear old problems with hybrid exchange conflicts by removing old mailbox configurations from user objects:

Log into exchange online with connect-exchangeonline:

Set-User <problem user objectid> -PermanentlyClearPreviousMailboxInfo

Exchange message tracking logs

on the on prem exchange server you can use the following cmdlet to check the exchange message logs for the last two hours:

Get-MessageTrackingLog  -start (get-date).AddHours(-2) | ? {$_.recipients -eq "<user@domain.com>"}