Create a No-Forward Role Assignment Policy for OWA

Scenario: You want to prevent users from configuring forwarding within Outlook on the Web (OWA).

Solution: Run the following in Exchange PowerShell

To Create the Policy:

New-ManagementRole MyBaseOptions-NoForward -Parent MyBaseOptions
Set-ManagementRoleEntry MyBaseOptions-NoForward\Set-Mailbox -RemoveParameter -Parameters DeliverToMailboxAndForward, ForwardingSmtpAddress

Set-ManagementRoleEntry MyBaseOptions-NoForward\New-InboxRule -RemoveParameter -Parameters ForwardTo, RedirectTo, ForwardAsAttachmentTo

Set-ManagementRoleEntry MyBaseOptions-NoForward\Set-InboxRule -RemoveParameter -Parameters ForwardTo, RedirectTo, ForwardAsAttachmentTo

New-RoleAssignmentPolicy -Name PolicyWithNoEmailForward -Roles MyContactInformation, MyRetentionPolicies, MyMailSubscriptions, MyTextMessaging, MyVoiceMail, MyDistributionGroupMembership, MyDistributionGroups, MyProfileInformation, MyBaseOptions-NoForward -Description “User role assignment policy that restricts the assignees from being able to autoforward email outside the organization”

To set it:

get-mailboxplan | Set-mailboxplan -RoleAssignmentPolicy PolicyWithNoEmailForward

get-mailbox | Set-Mailbox -RoleAssignmentPolicy PolicyWithNoEmailForward



Configure PowerShell to automatically run PowerShell Scripts/Functions/Commands when PowerShell is opened

Scenario: Do you have a common command, function, or script that you always execute manually within PowerShell at Startup? For example in my case, a .ps1 file that contains functions with how to connect to specific remote PowerShell instances.

Solution:

Run this within PowerShell:
New-item –type file –force $profile

Then edit the file it creates Microsoft.Powershell_profile.ps1 (usually located in this directory: C:\Users\<username>\Documents\PowerShell\) with the call to the script, the function, the commands, etc. Every time you open PowerShell, it will automatically run it and will be ready for you.

Search-Mailbox: Easy way to convert String values to Integers

Scenario: Need an easy way to convert the [string] value into a number? Specifically for the Search-Mailbox command for the ResultItemsCount and ResultItemsSize?

Solution:

Command:
$Search = Search-Mailbox $mbx -SearchDumpster -SearchQuery Received:1/1/1900..1/1/2013 -EstimateResultOnly

Now convert the results and store in a variable:
Note: $ItemSize is in Bytes.

$ItemCount = ($Search.ResultItemsCount) -as [int]

$ItemSize = (([regex]::match($Search.ResultItemsSize, $regex).Groups[1].value) -replace " bytes","" -as [int])

STOP THAT Print Spooler!

Scenario: With some of the latest exploits, stop that print spooler on your servers if its unneeded


Solution: PowerShell Scriptlets

If you are on the server, run the following:

Set-service Spooler -startuptype disabled
stop-service Spooler
get-service spooler



OR

If you want to remotely run the commands, like the big bad admin that you are, run the following:

$s = "ExServer1","ExServer2"
$s | %{
    $n = $_
    "Disabling Spooler on $_"

    Invoke-Command -ComputerName $n -ScriptBlock { Set-service Spooler -startuptype disabled }
    Invoke-Command -ComputerName $n -ScriptBlock { stop-service Spooler}

}

New-ApplicationAccessPolicy

Scenario: A registered App within Azure was created that has various ‘Application’ Exchange Permissions granted to it. You want to apply a scope to that registered app so the app only has permissions to specific mailbox, and not every mailbox by default

Scriptlet: Use the New-ApplicationAccessPolicy to Restrict Access

New-ApplicationAccessPolicy -AccessRight RestrictAccess -AppId “<client app id>” -PolicyScopeGroupId grp-app_Mbx_access -Description “Restrict this app to members of security group grp-app_MBX_access.”

Recursive Search for AD Group Members

Scenario: You need to perform a search for membership of AD Groups, including nested membership, for specific AD Groups

Function:

Function Get-GroupMembers {
   param(
          [string]$GroupName
   )

    #Var
    $objects = @()
    $members = @()
If($Layer -eq $Null){$layer = 1}else{$layer = $layer + 1}


    get-ADGroup $GroupName  -Properties *|select -ExpandProperty members | %{$Members += Get-ADObject -Filter {Distinguishedname -eq $_} | Select Name, ObjectClass, DistinguishedName}
    If($OriginalGroup -eq $Null){$OriginalGroup = $groupname}



   foreach ($member in $members) {

          if ($member.objectClass -eq "group") {
                 $objects += Get-GroupMembers -GroupName $member.distinguishedname
          }


            $obj = new-object psObject
            $obj | Add-Member -membertype noteproperty -Name Group -Value $OriginalGroup
            $obj | Add-Member -MemberType noteproperty -Name Layer -Value $layer
            $obj | Add-Member -membertype noteproperty -Name ObjectClass -Value $member.objectclass
            $obj | Add-Member -MemberType noteproperty -Name Name -Value $member.name
            $obj | Add-Member -membertype noteproperty -Name NameDN -Value $groupname

            $objects = $objects += $obj




   } # foreach

   return $objects
}#

Results: Run the following in Powershell after copying the function from above: Get-groupmembers -groupname “EmailAdmins”


Checking SCP status during Exchange On-Premise rebuild

Scenario: You are going to build a new Exchange On-Premises server, and you want to monitor the Autodiscover SCP record that is created so you can $null it out BEFORE your customer Outlook email clients start discovering the default server and pulling in the incorrect configuration values for the email clients server settings.

Script: Here is a monitor script that you can use, or build off of, to identify when the SCP record is created and you can go directly into ADSI edit and $null out the ServiceBindingInformation:

Do{
$r = @()
$r += get-adobject “CN=ExServer1,CN=Autodiscover,CN=Protocols,CN=ExServer1,CN=Servers,CN=Exchange Administrative Group (FYDIBOHF23SPDLT),CN=Administrative Groups,CN=Enterprise Exchange,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=domain,DC=com” -Properties * | Select CN, objectclass, ServiceBindingInformation
$r += get-adobject “CN=ExServer2,CN=Autodiscover,CN=Protocols,CN=ExServer2,CN=Servers,CN=Exchange Administrative Group (FYDIBOHF23SPDLT),CN=Administrative Groups,CN=Enterprise Exchange,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=domain,DC=com” -Properties * | Select CN, objectclass, ServiceBindingInformation
$r
Sleep 10



Sleeping 10 Sec

}While($C -ne 1002)

SMTP Error: ‘550 5.7.54 SMTP; Unable to relay recipient in non-accepted domain’ ·

Scenario: After standing up a new Exchange On-Premises Server, users are receiving the bounce back message with wording similar to the following:

For Email Admins: The message couldn’t be sent because it’s an attempt to relay a message to a recipient in a non-accepted domain (open relay) which isn’t allowed.

-or-

‘550 5.7.54 SMTP; Unable to relay recipient in non-accepted domain’

Solution: Make sure the Default Frontend Receive Connector is set to accept AnonymousUsers when connecting AND the ADPermission for AnonymousLogon is applied to the Receive Connector on the new server:

Set-ReceiveConnector “ExSrv1\Default Frontend ExSrv1” -PermissionGroups AnonymousUsers

Get-ReceiveConnector “ExSrv1\Default Frontend ExSrv1” | Add-ADPermission -User ‘NT Authority\Anonymous Logon’ -ExtendedRights MS-Exch-SMTP-Accept-Any-Recipient