Labels

Tuesday, April 2, 2013

Exchange PowerShell Commands

It's been a long time between drinks...

However, I have still been quietly squirreling away useful command lines, with the following 166 commands used for Exchange 2007/2010 information gathering, automating configuration management, troubleshooting and many bits in between.

Each command can be copied and pasted into a PowerShell command line running the Exchange snap-in loaded with the default prefix, although you may need to adjust input such as distinguished names, server names, mailbox names etc.

Let me know if you find them useful.



Get mailboxes that have a space in the displayName
get-mailbox -filter "(displayname -like '* *')" | ft identity,database -wrap -auto

Find Exchange transport rules
Get-TransportRule | ft Name,Priority,{$_.Conditions | select Name,{$_.Words}},{$_.Actions | select Name,Rank,SclValue},Comments -wrap -auto 

Find Exchange 2007 mailbox servers in the local organisation
get-mailboxserver

Get mailbox statistics for mailbox servers with the specified name
get-mailboxserver | where {$_.Name -like 'server*'} | Get-MailboxStatistics | Sort-Object TotalItemSize -Descending | select-object -prop DisplayName,LastLogonTime,StorageLimitStatus,TotalItemSize,TotalDeletedItemSize,@{N="Size (MB)";E={$_.TotalItemSize.Value.ToMB()}},@{N="Deleted Item Size (MB)";E={$_.TotalDeletedItemSize.Value.ToMB()}},ItemCount,ServerName,StorageGroupName,DatabaseName.LegacyDN | export-csv -path c:\temp\MailboxStatistics.csv

Get mailbox database size limit/quota settings on malibox stores
get-mailboxdatabase | select-object -prop Name,ServerName,StorageGroup,ProhibitSendReceiveQuota,ProhibitSendQuota,IssueWarningQuota | ft -wrap -autosize

Find the number of mail-enabled contacts in the organisation
get-mailcontact -ResultSize 'unlimited' | measure

Export the IP addressed allowed to relay through the specified connector
$rc = Get-ReceiveConnector -id 'server01\connector01'; $rc.RemoteIPRanges | export-csv -path c:\temp\rc1.csv

Exchange 2007 global transport size limits
get-transportconfig | ft -prop MaxReceiveSize,MaxSendSize -wrap -autosize   

Exchange 2007 transport server sizelimits
get-transportserver | ft -prop Name,OriginatingServer,InternalDsnMaxMessageAttachSize,ExternalDsnMaxMessageAttachSize -wrap -autosize

Exchange 2007 send connector size limits
get-sendconnector | ft -prop Identity,AddressSpaces,MaxMessageSize -wrap -autosize

Exchange 2007 receive connector size limits
get-receiveconnector | ft -prop Identity,AddressSpaces,MaxMessageSize -wrap -autosize

Exchange 2007 mailbox limits other than unlimited
get-mailbox |where {$_.MaxSendSize -ne 'unlimited' -or $_.MaxReceiveSize -ne 'unlimited'} | ft -prop Identity,MaxSendSize,MaxReceiveSize -wrap -autosize

Get the storage group copy status (CCR/LCR/SCR) for mailbox stores 
get-mailboxserver | where {$_.Name -like 'server*'} | Get-StorageGroupCopyStatus  | ft -wrap -autosize

Get storage groups and their SCR stand-by machine
Get-StorageGroup  | ft -prop Name,Server,StandbyMachines -wrap -autosize

Get the storage group copy status (SCR) for the first target on all SGs
Get-StorageGroup | %{Get-StorageGroupCopyStatus -id $_.Identity -StandbyMachine $_.StandbyMachines[0].NodeName} | sort -prop LastReplayedLogTime | select -prop Identity,SummaryCopyStatus,ServiceDown,CopyQueueLength,ReplayQueueLength,LatestAvailableLogTime,LastCopyNotificationedLogTime,LastCopiedLogTime,LastInspectedLogTime,LastReplayedLogTime,LatestFullBackupTime | export-csv -path c:\temp\SCR_Status.csv

Get the storage group copy status (SCR) for the specified server/target
Get-StorageGroupCopyStatus -Server server01 -standbymachine server01 | ft -wrap -autosize

Find the backup status and whether VSS was used for the backup
Get-StorageGroup | %{Get-StorageGroupCopyStatus -id $_.Identity -StandbyMachine $_.StandbyMachines[0].NodeName} | sort -prop LatestFullBackupTime | select -prop Identity,SummaryCopyStatus,ServiceDown,LatestFullBackupTime,SnapshotBackup  | export-csv -path c:\temp\MailboxBackup_Status.csv

Change an Exchange 2007 mailbox type to equipment (or room)
Set-Mailbox MailboxName -Type Equipment

Add full access mailbox permissoins for an Exchange 2007 mailbox
Add-MailboxPermission -Id MailboxName -User:'DOMAIN\group' -AccessRights:FullAccess

Add send as rights to the AD security of a mail-enabled user
Add-ADPermission -Id MailboxName -User:'DOMAIN\group' -ExtendedRights:Send-As

Find mailboxes that are not standard user mailboxes (Room, Equipment)
get-mailbox | where {$_.RecipientTypeDetails -ne 'UserMailbox'} | fl -prop Name,RecipientTypeDetails

Remove mailbox permissions for the specified user
Remove-MailboxPermission MailboxUser -User DOMAIN\User -AccessRight FullAccess    

Find exchange mailbox statistics including per-user mailbox and DB limits 
. C:\data\scripts\PowerShell\Exchange\FindMailboxSizes.ps1 | out-file -file c:\temp\MailboxStats.txt -encoding ascii

Find the AutomateProcessing setting for a resource mailbox
Get-MailboxCalendarSettings  -id mailboxID

Modify a resource mailbox to automatically accept in-policy requests
Set-MailboxCalendarSettings -id mailboxID -AllBookInPolicy:$true 

Find the mailbox type of one or more mailboxes
get-mailbox -id mailboxes* | fl -prop IsResource,RecipientType,RecipientTypeDetails,ResourceType

Find the debug event logging levels set on an Exchange 2007 server
Get-EventLoglevel -server ExchangeServer01

Set the equipment mailbox to auto-accept and allow anyone to automatically book
Set-MailboxCalendarSettings -Identity "mailbox01" -AutomateProcessing AutoAccept -AllBookInPolicy $true

Turn on high logging for the booking attendant
Set-EventLogLevel "server01\MSExchangeMailboxAssistants\Resource Booking Attendant" -Level High

Find all resource mailboxes of type equipment
get-mailbox |where {$_.resourcetype -eq 'Equipment'}

Read Exchange 2007 event logs for the MSExchangeMailboxAssistants (resources)
get-eventlog -logname application -computer server01 -source msexchangemailboxassistants

Check Exchange Message Tracking Logs based on message ID
Get-MessageTrackingLog -MessageId 'FBE264977E286848971C4C15BDD7F5FE439245C5EF@mx.company.com.au' -Start "05/07/2011 00:00:00" -End "07/07/2011 06:00:00" -server server01

Check Exchange Message Tracking Logs based on mail subject
Get-MessageTrackingLog -MessageSubject "RE: Subject" -Start "06/07/2011 00:00:00" -End "07/07/2011 00:00:00" -server server01

Find Exchange server version, edition and roles
Get-ExchangeServer | sort | select-object -prop Name,Role,Edition,ServerRole,Site,ExchangeVersion,AdminDisplayVersion | export-csv -path c:\temp\ExchangeServers.csv

Find the mailbox sizes in Exchange 2007 looking at the filesystem
Get-MailboxDatabase | foreach-object {add-member -inputobject $_ -membertype noteproperty -name mailboxdbsizeinGB -value ([math]::Round(([int64](get-wmiobject cim_datafile -computername $_.server -filter ('name=''' + $_.edbfilepath.pathname.replace("\","\\") + '''')).filesize / 1GB),2)) -passthru} | Sort-Object mailboxdbsizeinGB -Descending | format-table identity,mailboxdbsizeinGB 

Update the allowed IP addresses for an Exchange 2007 receive connector
$connector = Get-ReceiveConnector -id 'server01\connector01'; $connector.RemoteIPRanges += "192.168.20.10-196.168.20.20"; Set-ReceiveConnector 'server01\connector01' -RemoteIPRanges $connector.RemoteIPRanges

Move a mailbox to a new database
Move-Mailbox -id user01 -targetdatabase 'server01\sg01\db01' 

View the original warning quota message
Get-SystemMessage -original | where {$_.Identity -like 'en\warn*'}

Add a new warning quota message
New-SystemMessage -QuotaMessageType WarningMailbox -Language EN -Text "Please reduce your mailbox size! Delete any items you don't need from your mailbox and empty your Deleted Items folder."

Hide a mailbox from the GAL
get-mailbox -id user01 | set-mailbox -HiddenFromAddressListsEnabled:$true

Remove SID History from a user
get-aduser -id 'user01' -prop sIDHistory | foreach {set-aduser $_ -remove @{sIDHistory=$_.sIDHistory.value}}

Remove SID history from one or more groups
Import-Module ActiveDirectory; $groups = get-content -path groups_sAMAccountName.txt; foreach ($group in $groups) {get-adgroup -id $group -prop sIDHistory | foreach {set-adgroup $_ -remove @{sIDHistory=$_.sIDHistory.value}}}

Remove multiple attributes from an AD account
$user = get-aduser -id 'user01' -prop HomeDrive,HomeDirectory,ProfilePath; set-aduser $user -HomeDrive $null -HomeDirectory $null -ProfilePath $null

Enumerate public folders
Get-PublicFolder -server server01 -Recurse | ft -wrap -autosize

Restore a deleted user account using AD recycle bin
$deletedaccount = get-adobject -filter 'samaccountname -eq "user01"' -IncludeDeletedObjects -properties *; $deletedaccount | restore-adobject

Reconnect a mailbox to an AD user account 
$user = Get-MailboxStatistics -server server01 | where {$_.displayName -eq 'User01, Test' -and $_.DisconnectDate -ne $null}; Connect-Mailbox -Identity $user.Identity -Database $user.database -User DOMAIN\user01

Group and list the mailboxes on each mailbox store 
get-mailboxdatabase -server server01 | get-mailbox | Group-Object -prop database | ft -wrap -autosize

Create new mail contacts from CSV input in Exchange 2007
$dataSet = Import-Csv -path contacts.csv; foreach ($contact in $dataset)  {  New-MailContact -ExternalEmailAddress $contact.targetaddress -Name $contact.cn -DisplayName $contact.displayName -FirstName $contact.givenName -LastName $contact.sn -OrganizationalUnit domain.local/Contacts -PrimarySmtpAddress $contact.mail}

Set the primary mail AD attribute of a newly created Exchange 2007 contact
$contacts = get-mailcontact -OrganizationalUnit 'domain.local/Contacts' | where {$_.Name -like 'test*'} ; foreach ($contact in $contacts) {  set-mailcontact -id $contact.identity -WindowsEmailAddress $contact.PrimarySmtpAddress;  $contact.HiddenFromAddressListsEnabled = $true; }

Create a new basic authenticated send connector in Exchange 2007
$pass = Read-Host "Password?" -assecurestring; $credential = new-object System.Management.Automation.PSCredential("domain\username",$pass); $cred = get-credential -Credential $credential; New-SendConnector -Name "send01" -AddressSpaces * -AuthenticationCredential $cred -SmartHostAuthMechanism BasicAuth -DNSRoutingEnabled:$false -SmartHosts smtp.local

Find users who have been delegated send on behalf of rights to a mailbox
$delegates = Get-Mailbox 'room01' | select-object GrantSendOnBehalfTo; $delegates.GrantSendOnBehalfTo.toarray()

Find NDR 5.1.4 duplicate mail addresses from Exchange application event logs 
get-eventlog -logname 'Application' -computer server01 -after "28/10/2011 8:00:00" | where {$_.eventID -eq 3029}

Replace the primary SMTP email address 
Get-Mailbox -id 'user01' | Set-mailbox -EmailAddressPolicyEnabled $false; Get-Mailbox -id 'user01' | Update-List -Property EmailAddresses -Add "SMTP:user01@domain.local" | Set-Mailbox; Get-Mailbox -id 'user01' | Set-mailbox -EmailAddressPolicyEnabled $true

Add a new secondary SMTP address 
Get-Mailbox -id 'user01' | Update-List -Property EmailAddresses -Add "smtp:user01@domain.local" | Set-Mailbox

Check Exchange 2007 queues
Get-Queue -server server01 | ft -wrap -autosize

Find the public delegates for a mailbox and then reset to a new list
Get-Mailbox -id user01 | select -expand GrantSendOnBehalfTo; Get-Mailbox -id user01 | Set-Mailbox -grantSendOnBehalfto User02,User03,User04

Export Exchange client connection statistics (online/cached mode, client ver) 
$dateshort = [DateTime]::Now.ToString("yyyyMMddhhmmss"); get-mailboxserver | get-logonstatistics | select * | export-csv -path ("c:\temp\ExchangeLogonStats_" + $dateshort  + ".csv"); write-host ("c:\temp\ExchangeLogonStats_" + $dateshort  + ".csv")

Get a mailbox from the domain sAMAccountName 
get-mailbox -id 'domain\username' | fl *

Change the sAMAccountName of a mailbox-enabled user account
get-mailbox -id 'domain\user001' | set-mailbox -samaccountname user01

Change the Name/CN/DN of a mailbox-enabled user account
get-mailbox -id 'domain\user' | set-mailbox -DisplayName "User, Test" -Name "User, Test"

Change the alias of a mailbox object
get-mailbox -id 'domain\user' | set-mailbox -alias user01

Check if a mailbox exists
if (get-mailbox -id user01 -ErrorAction SilentlyContinue) {write-host "test"}

Find the oldest and newest dates of mailbox folders
get-mailboxfolderstatistics -id user01 -FolderScope Inbox -IncludeOldestAndNewestItems

Find Exchange logs for messages that failed to deliver
Get-MessageTrackingLog  -Start "21/12/2011 6:00:00" -server server01 | where {$_.eventId -eq 'Fail'} | ft * -wrap -autosize

Find messages where delivery failed 
Get-MessageTrackingLog -EventId FAIL -Start "20/12/2011 6:00:00" -server server01 | ft TimeStamp,Source,EventID,Recipients,Sender,RecipientStatus -wrap -autosize 

See which mailboxes a user has direct permissions to access
get-mailbox -OrganizationalUnit 'domain.local/Mailboxes/Shared' | get-mailboxpermission | where {$_.user -like 'domain\user01'}

Find mailboxes that have a specified ACE set
get-mailbox -OrganizationalUnit 'domain.local/Mailboxes/Shared' | get-adpermission | where {$_.AccessRights -contains 'WriteProperty' -and $_.Properties -like 'Personal-Information'} | ft -wrap -autosize

Find active sync utilisation for mailboxes
Get-Mailbox -ResultSize:Unlimited |ForEach {Get-ActiveSyncDeviceStatistics -Mailbox:$_.Identity} |ft identity,devicemodel,LastSuccessSync,LastPolicyUpdateTime,DeviceType,DeviceID,DeviceUserAgent,LastPingHeartbeat,DeviceFriendlyName,DeviceOS,DeviceIMEI,DevicePhoneNumber

Find SMTP mail delivery failures
foreach ($server in Get-TransportServer) {Get-MessageTrackingLog -EventId FAIL -Start "01/01/2012 6:00:00" -server $server.name | where {$_.recipients -like '*@*' -and $_.recipients -notlike '*@local.com' -and $_.recipients -notlike 'IMCEAEX*'} | ft EventId,Source,Sender,Recipients -wrap -autosize}

Find the owner of one or more mailboxes
get-mailbox -id user01 | get-adpermission -owner | ft -wrap -autosize

Get the Exchange 2007 organisation config
Get-OrganizationConfig

Find the Exchange 2007 accepted domains (authoritative and relay)
Get-AcceptedDomain

Find logs for distribution list expansion
foreach ($server in Get-TransportServer) {Get-MessageTrackingLog  -EventId EXPAND -Start "29/02/2012 17:28:00" -server $server.name | ft Timestamp,Sender,RelatedRecipientAddress,Recipients,RecipientStatus -wrap -autosize}

Find logs for e-mail from a specific address
foreach ($server in Get-TransportServer) {Get-MessageTrackingLog  -Sender "user01@external.com"  -Start "29/02/2012 17:28:00" -server $server.name | ft Timestamp,Recipients,RecipientStatus,Sender -wrap -autosize}

Find logs for failed messages
foreach ($server in Get-TransportServer) {Get-MessageTrackingLog  -EventId FAIL -Start "29/02/2012 17:28:00" -server $server.name | ft Timestamp,Recipients,RecipientStatus,Sender -wrap -autosize}

Find logs for messages from the last minute
foreach ($server in Get-TransportServer) {Get-MessageTrackingLog -start (Get-Date).AddMinutes(-1)  -server $server.name | ft Timestamp,Sender,RelatedRecipientAddress,Recipients,RecipientStatus -wrap -autosize}

Find mail attributes for a public folder
get-mailpublicfolder -id "\Folder01\SubFolder01" | fl *

Find Exchange 2007 Web Services
Get-WebServicesVirtualDirectory | fl *

Find Exchange Message Tracking messages from a particular client IP
foreach ($server in Get-TransportServer) {Get-MessageTrackingLog -resultsize unlimited -start (Get-Date).AddMinutes(-15) -server $server.name | where {$_.ClientIp -eq '192.168.1.10'} | ft * -wrap -autosize}   

Report explicit OU security for OUs in the domain
$ous = dsquery ou "dc=domain,dc=local" -limit 0; $permissions = foreach ($ou in $ous) {Get-ADPermission -id $ou.replace('"','') | where {$_.IsInherited -eq $False -and $_.User -like 'DOMAIN\*'}}; $permissions | select Identity,User,Deny,{$_.ChildObjectTypes},{$_.AccessRights},{$_.Properties},{$_.InheritedObjectType} | export-csv -path c:\temp\OU_Permission_20120309.csv

Find OWA Internal/External URL configuration
Get-OwaVirtualDirectory | where {$_.name -eq 'owa (Default Web Site)'} | ft Server,Name,InternalUrl,ExternalUrl -wrap -autosize 

Find transport server message tracking configuraiton 
Get-TransportServer | fl Name,messagetra*

List the available event logs from a remote server
Get-EventLog -computer server01 -list

List the Exchange 2007 diagnostic logging configuration
Get-EventLogLevel -server server01 | ft -wrap -autosize

Enable connectivity logging for Exchange 2007 Edge/Hub transport servers
get-TransportServer -id server01 | set-transportserver -ConnectivityLogEnabled:$true

View messages in the queue
get-queue -server server01 | get-message -IncludeRecipientInfo | fl *

Find recipients with a filter based on department
get-recipient -filter '((Department -eq "DEPT") -and (Alias -ne $null))'

Find users that do not have the specified primary SMTP address domain
get-recipient -filter '(ObjectClass -eq "User")' -resultsize:unlimited | where {$_.PrimarySmtpAddress -notlike "*@domain.local"} | ft Identity,PrimarySmtpAddress -wrap -autosize

Export to CSV users that don't have the specified primary SMTP domain
get-recipient -filter '(ObjectClass -eq "User")' -resultsize:unlimited | where {$_.PrimarySmtpAddress -notlike "*@domain.local"} | select Identity,PrimarySmtpAddress,Department | export-csv -path c:\temp\PrimarySMTP.csv

Expand a nested distribution group, counting all mail recipients
. C:\data\scripts\PowerShell\Exchange\ExpandDL.ps1 "CN=DL01,OU=Groups,dc=domain,dc=local"       

Find the user and SID on mailbox permissions (useful when sidhistory is used)
get-mailboxpermission -id user01 | ft User,{$_.user.securityidentifier} -wrap -auto

Find mailbox enabled users with a first/last name using ActiveDirectory
$users = get-aduser -filter {givenName -like '*' -and sn -like '*' -and mailnickname -like '*'}

Find user mailbox recipients that have a first and last name set
$mailboxes = get-recipient -resultsize unlimited -filter "(firstName -like '*' -and lastname -like '*' -and Alias -like '*' -and RecipientType -eq 'UserMailbox')"; foreach ($mailbox in $mailboxes) {  $firstName = $mailbox.firstname.replace(" ", "");   $lastName = $mailbox.lastname.replace(" ", "");   $primary = $mailbox.EmailAddresses | where {$_.IsPrimaryAddress -eq $true -and $_.PrefixString -eq "SMTP"} ;   $mailSplit =  $primary.SmtpAddress.split(".@");   if ($firstName -ne $mailSplit[0] -or $lastName -ne $mailSplit[1]) {    Write-Host $primary.SmtpAddress;   }}

Find mail recipients that don't have a first or last name (shared mailboxes)
$mailboxes = get-recipient -resultsize unlimited -filter {firstName -eq $null -and lastname -eq $null -and Alias -like '*' -and RecipientType -eq 'UserMailbox'}

Find mailboxes with the specified domain name
get-mailbox -filter {emailaddresses -like '*@domain.local'}

Find mailboxes with the specified domain name as their primary address
get-mailbox -filter {emailaddresses -like '*@domain.local'} | get-mailbox | where {$_.primarysmtpaddress -like '*@domain.local'}

Find distribution lists that can be emailed externally
$dls = get-distributiongroup -resultsize unlimited -filter {Alias -ne $null -and RequireAllSendersAreAuthenticated -eq $true}

Update the accept from for a DL with a list of users
$users = "User01, Test", "User02, Test"; foreach ($user in $users) {$user = get-mailbox -id $user; if ($user) {Get-DistributionGroup -id "DL01" | Update-List -Property AcceptMessagesOnlyFrom -Add $user.distinguishedName | Set-DistributionGroup }}

Update a distribution list to allow sending only from another DL
set-distributiongroup -id dl01 -AcceptMessagesOnlyFromDLMembers dl02

Find the user accounts for mailbox recipients with first and last name 
$mail = get-user -filter {(FirstName -ne $null -and LastName -ne $null)} -RecipientTypeDetails UserMailbox,LinkedMailbox -resultsize unlimited -OrganizationalUnit "OU=Mailboxes,dc=domain,dc=local" | select FirstName,LastName,windowsemailaddress

Find users that don't conform to first.last@ email addresses
$mail = get-user -filter {(FirstName -ne $null -and LastName -ne $null)} -RecipientTypeDetails UserMailbox,LinkedMailbox -resultsize unlimited -OrganizationalUnit "OU=Mailboxes,dc=domain,dc=local" | select FirstName,LastName,windowsemailaddress

Create a new transport rule setting SCL based on subject or body text
$condition = Get-TransportRulePredicate SubjectOrBodyContains; $condition.words = "SCL=9"; $action = Get-TransportRuleAction SetSCL; $action.sclvalue = 9; New-TransportRule -name "Filter01" -Condition $condition  -Action $action

Find mailboxes configured to forward and report details
$outputFile = "c:\temp\EmailForward_" + ([DateTime]::Now.ToString("yyyyMMddhhmmss")) + ".csv"; get-mailbox -filter {forwardingaddress -ne $null} | sort -prop whenChanged -descending | select whenChanged,SamAccountName,Identity,DeliverToMailboxAndForward,ForwardingAddress, @{N='ForwarderPrimarySMTPAddress';E={$recipient = get-recipient -id $_.ForwardingAddress; if ($recipient.recipienttype -eq 'MailContact') {write-output $recipient.externalemailaddress.tostring().replace("SMTP:","")} else {write-output $recipient.primarysmtpaddress}}},@{N='RecipientType';E={$recipient = get-recipient -id $_.ForwardingAddress; write-output $recipient.recipienttype.tostring()}} | export-csv -path $outputFile; write-host $outputFile

Turn on send connector verbose logging
get-sendconnector -id 'SendConnect01' | set-sendconnector -ProtocolLogginglevel verbose

Find NDR 5.4.6 routing loops in the last day from all transport servers
foreach ($server in Get-TransportServer) {Get-MessageTrackingLog -resultsize unlimited -EventId FAIL -Start (Get-Date).AddDays(-1) -server $server.name | where {$_.RecipientStatus -like '*5.4.6*'} | ft Timestamp,Recipients,RecipientStatus,Sender -wrap -autosize}

Find email addresses that aren't using first.last
foreach ($user in $mail) { if (!($user.windowsemailaddress.tostring().tolower().contains($user.firstname.tolower().replace(' ', '') + '.' + $user.lastName.tolower().replace(' ', '') + '@'))) { write-host $user.windowsemailaddress} }

Export a mailbox to PST
export-mailbox -id user01 -PSTFolderPath c:\temp\user01.pst

Find the Exchange 2003 global restrictions in AD for envelope recipients
Get-ADObject -id "CN=Message Delivery,CN=Global Settings,CN=ORG,CN=Microsoft Exchange,CN=Services,CN=Configuration,dc=domain,dc=local" -prop msExchRecipLimit

Find the Exchange 2007/2010 global restrictions in AD for envelope recipients
Get-ADObject -id "CN=Transport Settings,CN=ORG,CN=Microsoft Exchange,CN=Services,CN=Configuration,dc=domain,dc=local" -prop msExchRecipLimit

Find the Exchange 2007 transport settings for max enveople recipients
Get-TransportConfig | fl MaxRecipientEnvelopeLimit

Update managedBy for a distribution group
get-distributiongroup -id DL01 | Set-DistributionGroup -ManagedBy "CN=user01,OU=Mailboxes,dc=domain,dc=local"

Get the offline address book update schedule 
$oab = Get-OfflineAddressBook; $oab.schedule | ft -wrap -auto

Find the offline address book server, PF database and web distribution point
Get-OfflineAddressBook | fl Server,PublicFolderDatabase,VirtualDirectories

Find the Offline Address Book virtual directory
Get-OabVirtualDirectory | ft -wrap -auto

Find the custom resource schema configuration for custom resource properties
Get-ResourceConfig

Gather public folder statistics
$pfstats = Get-PublicFolderStatistics -server server01

Start the Exchange Management Shell from a standard powershell instance
add-pssnapin  Microsoft.Exchange.Management.PowerShell.Admin; . "C:\Program Files\Microsoft\Exchange Server\bin\Exchange.ps1"

Send an SMTP e-mail with PowerShell 2.0 or later
send-mailmessage -from $sendfrom -to $sendto -subject $subject -body $body -BodyAsHtml -smtpServer $smtpserver

Add an availability address space to access local public folder schedule+ FB
Add-AvailabilityAddressSpace -ForestName remote.address.space -AccessMethod PublicFolder

Query free/busy schedule+ public folder replica information
get-publicfolder -Identity "\NON_IPM_SUBTREE\SCHEDULE+ FREE BUSY"  -Recurse | ft Name,OriginatingServer,Replicas -wrap -auto

Query free/busy schedule+ public folder information on Exchange 2007/2010
get-publicfolder -Identity "\NON_IPM_SUBTREE\SCHEDULE+ FREE BUSY"  -Recurse | Get-PublicFolderItemStatistics | ft PublicFolderName,Subject -wrap -auto

Show the e-mail addresses for the specified user in list format
((Get-Mailbox user01).EmailAddresses)

Add a secondary e-mail address in Exchange 2010 to a mailbox user
Set-Mailbox user01 -EmailAddresses (((Get-Mailbox user01).EmailAddresses)+="smtp:user01@test.com")

Add a secondary e-mail address in Exchange 2010 to a MEU
Set-MailUser testuser01 -EmailAddresses (((Get-MaiLUser testuser01).EmailAddresses)+="smtp:testuser01@new.domain.com") -whatif

Update the targetAddress attribute for an ADSI object
$user = [adsi]"LDAP://CN=testuser01,OU=Migrated,DC=domain,DC=local"; $user.put("targetAddress","smtp:testuser01.User@new.domain.com")

List the client-side public folder permissions for all public folders
$pfperms = Get-PublicFolder -recurse | Get-PublicFolderClientPermission

Get the report from a Exchange 2010 new-moverequest operation
$MoveReport = (Get-MailboxStatistics -Identity user01 -IncludeMoveReport).MoveHistory

Add to the managedBy property of a distribution list
set-distributiongroup -id $group -managedby (((get-distributiongroup -id $group).managedby) += $user.identity.distinguishedName)

Find the current management roles that have distribution in the name
Get-ManagementRoleAssignment | where {$_.name -like '*recipient*'} -warningaction silentlycontinue | ft -wrap -auto

Find CAS array information for an Exchange 2010 installation
get-clientaccessarray

Find delegate access to a mailbox with Exchange 2010 SP1
adfind -b "DC=domain,DC=local" -f "(&(objectClass=User)(objectCategory=Person)(msExchDelegateListLink=*))" -h dc01.domain.local samaccountname msExchDelegateListLink

Find delegate access to a mailbox with Exchange 2010 SP1 through backlink
adfind -b "DC=domain,DC=local" -f "(&(objectClass=User)(objectCategory=Person)(MsExchDelegateListBL=*))" -h dc01.domain.local samaccountname MsExchDelegateListBL

Convert legacy global distribution groups to universal
Get-Group -ResultSize Unlimited -RecipientTypeDetails NonUniversalGroup -OrganizationalUnit "OU=Distribution Lists,OU=Resources,DC=domain,DC=local" | Where-Object {$_.GroupType -match 'global'} | Set-Group -Universal

Mail-enable legacy global DLs that have been converted to universal
Get-Group -ResultSize Unlimited -RecipientTypeDetails UniversalDistributionGroup -OrganizationalUnit "OU=Distribution Lists,OU=Resources,DC=domain,DC=local"  | enable-distributiongroup

Change group scope for non-universal groups to universal
Get-DistributionGroup -ResultSize Unlimited -RecipientTypeDetails MailNonUniversalGroup | Set-Group -Universal

Upgrade Exchange 2010 legacy groups
Get-DistributionGroup -ResultSize Unlimited | Set-DistributionGroup -ForceUpgrade

Extract all properties of one or more users and save to CSV
get-aduser -ldapfilter "(&(objectClass=User)(objectCategory=Person)(samaccountname=*.exchtest*))" -prop * | export-csv -path c:\temp\TestUsers.csv

Create a new display name with surname in UPPER and first in Title case
$newName = $user.LastName.toUpper() + ' ' + (Get-Culture).textinfo.totitlecase($user.FirstName)

Start a remote powershell session to an exchange 2010 namespace
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://cas01.domain.local/PowerShell/ -Authentication Kerberos;   Import-PSSession $Session

Start a remote powershell session to an exchange 2010 namespace using prefix
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://cas01.domain.local/PowerShell/ -Authentication Kerberos;   Import-PSSession $Session -prefix ResForest

Bitwise OR to whether whether grouptype is distribution or security
if (14 -bor 2147483648 -eq 14) {write-output "Distribution} else {write-output "Security"}

Find mailbox folder permissions in Exchange 2010
$mailbox = get-mailbox -id user01; get-mailboxfolderpermission -id ($mailbox.primarysmtpaddress.tostring() + ":\Calendar")

Find the Exchange 2010 autodiscover URL (then stored in SCP)
Get-ClientAccessServer | fl *autodisc*      

Find Exchange 2010 RBAC management roles
Get-ManagementRole -id 'Distribution Groups' | fl *

Find Exchange 2010 RBAC management role assignments
Get-ManagementRoleAssignment |where {$_.role -eq 'Distribution Groups'} | ft -wrap -auto

Select the value of a property as an array of strings rather noteproperty
$members = get-adgroup "CN=group,DC=domain,DC=local" -server $dc | get-adgroupmember -server $dc | %{write-output $_.SamAccountName.ToString()}

Convert a group from security to distribution
get-adgroup -id migtestdl3 | set-adgroup -GroupCategory 0

Find recipient info from multiple forests and group by primary SMTP domain
$recipients = get-recipient -domaincontroller dc01.domain.local -OrganizationalUnit "OU=People,DC=domain,DC=local" -filter {(firstName -ne $null -and LastName -ne $null) -and (RecipientType -eq 'UserMailbox')} -resultsize unlimited ; $recipients += get-recipient  -domaincontroller targetdc.target.domain -OrganizationalUnit "OU=People,DC=target,DC=domain" -filter {(firstName -ne $null -and LastName -ne $null) -and (RecipientType -eq 'UserMailbox')} -resultsize unlimited ; $recipients | select @{N='EmailDomain';e={$_.primarysmtpAddress.tostring().split("@")[1]}} | group-object -prop EmailDomain | sort -prop Count | ft -wrap -auto

Find mailboxes from multiple forest and info on e-mail domain and islinked
$mailboxes = get-recipient -domaincontroller dc01.domain.local -OrganizationalUnit "OU=People,DC=domain,DC=local" -filter {(firstName -ne $null -and LastName -ne $null) -and (RecipientType -eq 'UserMailbox')} -resultsize unlimited  | get-mailbox -domaincontroller dc01.domain.local; $mailboxes += get-recipient  -domaincontroller dc01.taret.domain -OrganizationalUnit "OU=People,DC=target,DC=domain" -filter {(firstName -ne $null -and LastName -ne $null) -and (RecipientType -eq 'UserMailbox')} -resultsize unlimited | get-mailbox -domaincontroller dc01.target.domain; $mailboxes | select OriginatingServer,@{N='EmailDomain';e={$_.primarysmtpAddress.tostring().split("@")[1]}},IsLinked | group-object -prop OriginatingServer,EmailDomain,IsLinked | sort -prop Count | ft Count,Name -wrap -auto  

Find mailboxes with an ActiveSync device partnership
get-casmailbox -resultsize unlimited  | where {$_.HasActiveSyncDevicePartnership -eq 'true'}

Find the preferred domain controllers for the current Exchange 2010 session
Get-ADServerSettings | fl *

Set domain controller configuration for an exchange server
Set-ExchangeServer -StaticConfigDomainController dc01 StaticDomainControllers dc01,dc02 -StaticExcludedDomainControllers dc03 -StaticGlobalCatalogs gc01

Link an Exchange 2010 mailbox to a cross-forest security principal
get-mailbox user01 | set-mailbox -LinkedMasterAccount domain\user01 -linkeddomaincontroller dc01.domain.local

Get Exchange 2010 IMAP settings
Get-IMAPSettings -Server cas01

Disable policy and update the primary SMTP address of a 2010 mailbox 
get-mailbox -id "CN=user01,OU=People,DC=domain,DC=local" | set-mailbox -EmailAddressPolicyEnabled $false -PrimarySmtpAddress user01@domain.local

Find the server generating the Offline Address Book
Get-OfflineAddressBook | ft server,guid,AddressLists -wrap -auto (files stored in C:\Program Files\Microsoft\Exchange Server\V14\ExchangeOAB\)

Prepare an Exchange 2010 cross-forest move (create MEU and merge contact)
.\Prepare-MoveRequest.ps1 -Identity $username -RemoteForestCredential $cred -RemoteForestDomainController dc01.domain.local -LinkedMailUser -MailboxDeliveryDomain domain.local -TargetMailUserOU "OU=Resource Forest Accounts,DC=domain,DC=local" -UseLocalObject

Initiate an Exchange  2010 cross-forest move request
New-MoveRequest -Identity $username -RemoteLegacy -RemoteGlobalCatalog dc01.domain.local -TargetDatabase 'DB01' -RemoteCredential $cred -TargetDeliveryDomain 'domain.local' ?Verbose

Get an Exchange 2010 move request report
$moverequest = Get-MoveRequestStatistics -id user01 -IncludeReport; $moverequest.report

Get all the mailbox users in an OU and set a user property
get-mailbox -org "OU=Resource Forest Accounts,DC=domain,DC=local" | set-user -company 'Company01'

Check Exchange 2010 CAS RPC Client Access stats for online mode
$matches = select-string -pattern "2013-03" -simple -path "\\cas01\c$\Program Files\Microsoft\Exchange Server\V14\Logging\RPC Client Access\RCA_201303*"; $results = foreach ($match in $matches) {$line = $match.line;   write-output $line }; $results | out-file -file c:\temp\rpcusage.txt -encoding ascii; $rpc = import-csv -path c:\temp\rpcusage.txt -header date-time,session-id,seq-number,client-name,organization-info,client-software,client-software-version,client-mode,client-ip,server-ip,protocol,application-id,operation,rpc-status,processing-time,operation-specific,failures; $classic = $rpc | where {$_.'client-mode' -eq 'Classic' -and $_.'client-software' -eq 'outlook.exe'}; $classic | select client-name | group-object -prop client-name | ft -wrap -auto Count,Name

Find Exchange 2007/2010 mailbox statistics in MB (not with remote powershell)
get-mailbox -id user* | get-mailbox | get-mailboxstatistics | select DisplayName,ItemCount,@{n='SizeMB';e={$_.TotalItemSize.value.tomb()}} | ft -wrap -autosize

Wayne's World of IT (WWoIT), Copyright 2010 Wayne Martin. 

2 comments:

Anonymous said...

greeting fellow oneliner.

search your groups (security, distro) and for those that have email addresses, see which are receiving email from outside your company.com domain.

get-qadobject -searchroot 'ou=groups,ou=people,dc=company,dc=local' | where-object {($_.primarysmtpaddress -ne $null)} | select-object primarysmtpaddress | foreach {get-messagetrackinglog -recipients $_.primarysmtpaddress -start 4/1/2013 -end 4/15/2013 | where {$_.sender -notlike '*company.com'}}

Anonymous said...

Hey,
Awesome list of commands, very helpful. I am new to pwershell and struggling with one.
I would liek to add a secondary email address to a bunch of mailusers (not mailboxes) in a specific OU.
I have the list of users but cannot seem to figure out how to add the secondary email address of givenName.lastName@domain.com Can you help?

So far I have:-
Get-recipient -OrganizationalUnit "Exchange Test Accounts" -filter "recipienttype -eq'MailUser'"


All Posts

printQueue AD objects for 2003 ClusterVirtualCenter Physical to VirtualVirtual 2003 MSCS Cluster in ESX VI3
Finding duplicate DNS recordsCommand-line automation – Echo and macrosCommand-line automation – set
Command-line automation - errorlevels and ifCommand-line automation - find and findstrBuilding blocks of command-line automation - FOR
Useful PowerShell command-line operationsMSCS 2003 Cluster Virtual Server ComponentsServer-side process for simple file access
OpsMgr 2007 performance script - VMware datastores...Enumerating URLs in Internet ExplorerNTLM Trusts between 2003 and NT4
2003 Servers with Hibernation enabledReading Shortcuts with PowerShell and VBSModifying DLL Resources
Automatically mapping printersSimple string encryption with PowerShellUseful NTFS and security command-line operations
Useful Windows Printer command-line operationsUseful Windows MSCS Cluster command-line operation...Useful VMware ESX and VC command-line operations
Useful general command-line operationsUseful DNS, DHCP and WINS command-line operationsUseful Active Directory command-line operations
Useful command-linesCreating secedit templates with PowerShellFixing Permissions with NTFS intra-volume moves
Converting filetime with vbs and PowerShellDifference between bat and cmdReplica Domain for Authentication
Troubleshooting Windows PrintingRenaming a user account in ADOpsMgr 2007 Reports - Sorting, Filtering, Charting...
WMIC XSL CSV output formattingEnumerating File Server ResourcesWMIC Custom Alias and Format
AD site discoveryPassing Parameters between OpsMgr and SSRSAnalyzing Windows Kernel Dumps
Process list with command-line argumentsOpsMgr 2007 Customized Reporting - SQL QueriesPreventing accidental NTFS data moves
FSRM and NTFS Quotas in 2003 R2PowerShell Deleting NTFS Alternate Data StreamsNTFS links - reparse, symbolic, hard, junction
IE Warnings when files are executedPowerShell Low-level keyboard hookCross-forest authentication and GP processing
Deleting Invalid SMS 2003 Distribution PointsCross-forest authentication and site synchronizati...Determining AD attribute replication
AD Security vs Distribution GroupsTroubleshooting cross-forest trust secure channels...RIS cross-domain access
Large SMS Web Reports return Error 500Troubleshooting SMS 2003 MP and SLPRemotely determine physical memory
VMware SDK with PowershellSpinning Excel Pie ChartPoke-Info PowerShell script
Reading web content with PowerShellAutomated Cluster File Security and PurgingManaging printers at the command-line
File System Filters and minifiltersOpsMgr 2007 SSRS Reports using SQL 2005 XMLAccess Based Enumeration in 2003 and MSCS
Find VM snapshots in ESX/VCComparing MSCS/VMware/DFS File & PrintModifying Exchange mailbox permissions
Nested 'for /f' catch-allPowerShell FindFirstFileW bypassing MAX_PATHRunning PowerSell Scripts from ASP.Net
Binary <-> Hex String files with PowershellOpsMgr 2007 Current Performance InstancesImpersonating a user without passwords
Running a process in the secure winlogon desktopShadow an XP Terminal Services sessionFind where a user is logged on from
Active Directory _msdcs DNS zonesUnlocking XP/2003 without passwords2003 Cluster-enabled scheduled tasks
Purging aged files from the filesystemFinding customised ADM templates in ADDomain local security groups for cross-forest secu...
Account Management eventlog auditingVMware cluster/Virtual Center StatisticsRunning scheduled tasks as a non-administrator
Audit Windows 2003 print server usageActive Directory DiagnosticsViewing NTFS information with nfi and diskedit
Performance Tuning for 2003 File ServersChecking ESX/VC VMs for snapshotsShowing non-persistent devices in device manager
Implementing an MSCS 2003 server clusterFinding users on a subnetWMI filter for subnet filtered Group Policy
Testing DNS records for scavengingRefreshing Computer Account AD Group MembershipTesting Network Ports from Windows
Using Recovery Console with RISPAE Boot.ini Switch for DEP or 4GB+ memoryUsing 32-bit COM objects on x64 platforms
Active Directory Organizational Unit (OU) DesignTroubleshooting computer accounts in an Active Dir...260+ character MAX_PATH limitations in filenames
Create or modify a security template for NTFS perm...Find where a user is connecting from through WMISDDL syntax in secedit security templates

About Me

I’ve worked in IT for over 13 years, and I know just about enough to realise that I don’t know very much.