Removing Orphaned Populated msExchangeDelegateLinkList and msExchangeDelegateLinkListBL Automapping Attributes

By Ace Fekay
Published 5/11/2017
Revamped 3/31/2018 – Added the option to selectively remove BLs without removing FullAccess permissions to the shared mailbox

Scope

How to remove a shared mailbox that keeps showing up in your Outlook profile that you’ve been removed as a delegate.

This shows how to remove the mailbox permissions and to re-add, and I just added how to simply just remove the backlinks WITHOUT removing FullAccess permissions. The users in this case, must re-add the mailbox in Outlook once it disappears from their profile.

Automapping

Automapping is an Autodiscover feature that was added to Exchange 2010 SP1 and newer, that allows Outlook to automatically add a delegated mailbox without additional tasks.

Autodiscover looks at the mailbox owner’s AD account for an attribute called the MSExchDelegateListLink attribute.

When you use the EAC or PowerShell to delegate permissions to a shared mailbox or to another user, Exchange will automatically set the Automapping feature to $True. In PowerShell you can disable this, but not in the EAC.

This feature populates the MSExchDelegateListLink attribute on the shared or delegated mailbox with the user accounts that will be Automapped, and vice-versa, it also populates the MSExchDelegateLinkListBL attribute on the user account. I look at this as the “back link” to the shared mailbox.

These two attributes are one of  nine (9) links and backlinks that exist. Here’s a list of all links and backlinks in AD and more specifics can be found at the following link:
http://www.neroblanco.co.uk/2015/07/links-and-backlinks-in-active-directory-for-exchange/

Outlook, Autodiscover, and those attributes

When Outlook fires up, and while running, part of what Autodiscover process performs is it will check these two attributes to determine if there are any shared mailboxes that must be automatically added to the Outlook profile. In some cases using a managed process for shared mailboxes, we may want this feature disabled so the shared mailbox does not get automatically added.

Orphaned Backlink is still populated and the mailbox still shows up in Outlook

If the user was previously delegated to a shared mailbox, then the delegated per,missions were removed, but for some reason, perhaps replication or corruption, or some other unforeseen factor (large environments fall under this category), the shared mailbox still shows up and you can’t get rid of it, and further, since you no longer have permissions, you can’t open it. This will cause the shared or delegated mailbox to still show up in Outlook. But you can clearly see in EAC or running a get-mailboxpermission that the user is no longer delegated.

Example of an account with the msExchDelegateLinkListBL still populated:

image

How to remove it?

First, establish your PowerShell session to Exchange OnPrem or your Office 365 tenant. If unsure how, see this:
http://blogs.msmvps.com/acefekay/2017/05/11/establishing-a-powershell-session-to-your-office-365-tenant-or-onprem-exchange/

Determine, if any, links or backlinks exist on the shared mailbox:

Get-ADUser “SharedMailboxDisplayName” -Properties msExchDelegateListLink | Select-object -ExpandProperty msExchDelegateListLink

If any show up, you’ll see their sAMAccountNames. If you don’t know who the sAMAccountNames are and you want to see their displayNames, run the following (this command works for DNs, too):

For one account:
get-aduser sAMAccountName -Properties displayName,mail  | ft Name, DisplayName, mail -A

For a list of accounts in a text file:
get-content c:\temp\names.txt | get-aduser -Properties displayName,mail  | ft Name, DisplayName, mail –A

 

Then remove the msexchDelegateLinkListBL orphaned backlink and FullAccess permissions to the shared mailbox

Note: I’m using the shared mailbox’s displayName. This will also work using the sAMAaccountName or the primary email address.

For one account:
Remove-MailboxPermission “SharedMailboxDisplayName” -user $_ –AccessRights FullAccess -Confirm:$false

For a list of accounts in a text file:
get-content c:\temp\ace\userIDs\users.txt | foreach {Remove-MailboxPermission “SharedMailboxDisplayName”  -user $_ –AccessRights FullAccess -Confirm:$false}

Then if needed, delegate the shared mailbox again & disabling Automapping

Delegate Ace to a shared mailbox:
Add-MailboxPermission “Shared Mailbox Name or email address” -User AceFekay@contoso.com -AccessRights FullAccess -AutoMapping:$false

To just remove the backlink WITHOUT removing permissions

Note, using this method, the shared mailbox will automatically disappear from the Outlook profile. As soon as it does, you must manually re-add the shared mailbox either under the user account properties, where the permissions are proxied through the user account, which is the same as if it were Automapped, or as a separate account, which provides better features including sent and deleted items go into the shared mailbox itself instead of the mailbox owner under an automapped account or added under the user account.

To remove all BLs all at once:

#########################################################
#Remove the MSExchDelegateListBL from an account

$userToClean = “I061859”
  $userDN = Get-ADUser $userToClean | select -ExpandProperty DistinguishedName
  $delegates = Get-ADUser $userToClean -Properties msExchDelegateListBL |  select -ExpandProperty msExchDelegateListBL
  Write-Host “======================================================”
  write-host “List of Delegated accounts that are backlinked:” $Delegates
  Write-Host “======================================================”
  foreach ($delegate in $delegates) {
  Set-ADUser $delegate -Remove @{msExchDelegateListLink = “$UserDN”}
  }
  Write-Host “======================================================”
  Write-Host “If the following get-aduser cmdlet searching for backlinds is empty, then all delegated backlinks have been removed”
  Get-ADUser $user -Properties msExchDelegateListBL |  select -ExpandProperty msExchDelegateListBL
  Write-Host “======================================================”

To remove specific BLs one at a time:

# 1. Find the list of users in a shared mailbox that have been backlinked.
#    Note, as said, this is only for removing users that have requested it, unless you are working on removing all, which use the above

$SharedMailboxOrUserDisplayName = “Shared Mailbox Display Name”
$SharedMailboxOrUser = (get-recipient “$SharedMailboxOrUserDisplayName”).name
Write-Host “======================================================”
Write-host “Shared Mailbox sAMAccountName:” $sharedMailboxorUser
Write-host “List of Users (or ‘Delegates’) that currently have Backlinks on Shared mailbox ‘$sharedMailboxorUser’ :”
Get-ADUser $SharedMailboxOrUser  -Properties msExchDelegateListLink | Select-object -ExpandProperty msExchDelegateListLink | get-aduser -Properties displayName,mail  | ft Name,DisplayName,mail -A
write-host “======================================================”

# 2. Then enter the user account name from the above list that you want to remove, and then find the user’s DN:
  $UserToClean = “User sAMAccountName”
  $userToCleanDisplayName = (get-recipient $UserToClean).displayName
  $userDN = Get-ADUser $UserToClean | select -ExpandProperty DistinguishedName
  Write-Host “The DN of ‘$userToCleanDisplayName’ ($UserToClean) that you want to clean is: ” $userDN
  Write-Host “======================================================”
  write-host “List of Backlink DNs that you want to remove from $UsertoClean :”
  Write-Host
  Get-ADUser  $UserToClean -Properties msExchDelegateListbl |  select -ExpandProperty msExchDelegateListBL

  Write-Host  “======================================================”

# 3. Remove the MSExchDelegateListBL from my account or an account that was migrated to the cloud that previously had a MSExchDelegateListBL
#    Just have to run this, the BL gets removed after you run it
#    This does not remove any AccessRights to the Mailbox, it just removes the automapping

Set-ADUser  $UserToClean -Remove @{msExchDelegateListLink = (Copy and Paste the Backlink DN of the specific shared mailbox from the previous list that you want to remove) }

# 4. Then check to see if it worked:
   Get-ADUser  $UserToClean -Properties msExchDelegateListBL |  select -ExpandProperty msExchDelegateListBL
   Get-ADUser  $UserToClean -Properties msExchDelegateListLink |  select -ExpandProperty msExchDelegateListBL

==========================================================

Summary

I hope this helps!

Published 5/18/2017

Ace Fekay
MVP, MCT, MCSE 2012, MCITP EA & MCTS Windows 2008/R2, Exchange 2013, 2010 EA & 2007, MCSE & MCSA 2003/2000, MCSA Messaging 2003
Microsoft Certified Trainer
Microsoft MVP – Directory Services

As many know, I work with Active Directory, Exchange server, and Office 365 engineer/architect, and an MVP in Active Directory and Identity Management, and I’m an MCT as well. I try to strive to perform my job with the best of my ability and efficiency, even when presented with a challenge, and then help others with my findings in case a similar issue arises to help ease their jobs. Share the knowledge, is what I’ve always learned.

I’ve found there are many qualified and very informative websites that provide how-to blogs, and I’m glad they exists and give due credit to the pros that put them together. In some cases when I must research an issue, I just needed something or specific that I couldn’t find or had to piece together from more than one site, such as a simple one-liner or a simple multiline script to perform day to day stuff.

I hope you’ve found this blog post helpful, along with my future scripts blog posts, especially with AD, Exchange, and Office 365.

clip_image0023 clip_image0043 clip_image0063 clip_image0083 clip_image0103 clip_image0123 clip_image0143 clip_image0163

Complete List of Technical Blogs: http://www.delawarecountycomputerconsulting.com/technicalblogs.php

Or just search within my blogs:
https://blogs.msmvps.com/acefekay/

This posting is provided AS-IS with no warranties or guarantees and confers no rights.


 

Get-Rules

By Ace Fekay
Published 2/21/2018

Intro

This is another quick script I created to help my day to day tasks. I hope you find it helpful.

Like I said before, I’m far from being an expert, but I continue to read up on it, research, and ask lots of questions. The more you work at something, the more you get something out of it. Ever play pool?

Scope

This script will enumerate the Inbox rules for a mailbox. You will have four options:

  1. List of rules without a description using FT
  2. List of rules with a description using FT
  3. Rules listed individually using FL
  4. Rules sent to a CSV file named based on the user account entered

Get-Rule Script

Copy and paste the following into notepad, and save it as Get-UserList.ps1, and run it to load the function.

#################################\\\\\\\\\\\\\\\\////////////////#################################
# This script will:
# 1. Read a console entry for a user accounts, whether a sAMAccountName, alias, or email address
# 2. Provide a list of rules without descriptions
# 3. Provide a list of rules with descriptions
#
#    .SYNOPSIS
#    Lists a User’s Mailbox InboxRules
#
#    .DESCRIPTION
#    Enumerate Inbox rules with and without a description
#
#    .PARAMETER User
#    Specific user you want to search for.
#
#    .PARAMETER Description
#    You want the rules listed out individually with a description
#
#    .PARAMETER NoDescription
#    You want the rules listed out in table format without a description
#
#    .PARAMETER NoDescription
#    You want the rules listed out in table format without a description
#
#################################\\\\\\\\\\\\\\\\////////////////#################################
# Variables

$RecipientName = “I823135”
$RecipientDisplayName = (get-recipient $RecipientName).displayname
$RecipientNetBIOSName = (get-recipient $RecipientName).name
$RecipientPrimAlias = (get-recipient $RecipientName).PrimarySmtpAddress

# Script

Function Get-Rules {
[CmdletBinding()]
Param (
[Parameter(Position=0,Mandatory=$true)]
[string]$RecipientName,

[Parameter(Mandatory=$false)]
[switch]$Description,

[Parameter(Mandatory=$false)]
[switch]$NoDescription,

[Parameter(Mandatory=$false)]
[switch]$IndividualList,

[Parameter(Mandatory=$false)]
[switch]$CSVFile
)

$RecipientDisplayName = (get-recipient $RecipientName).displayname
$RecipientNetBIOSName = (get-recipient $RecipientName).name
$RecipientPrimAlias = (get-recipient $RecipientName).PrimarySmtpAddress

#If -Description was selected – Inboxrules to Console Screen:
If ($NoDescription) {
Write-Host “=================================================================================================” -ForegroundColor Cyan
Write-Host “You’ve selected to List the Inbox Rules to the Console Without a Description” -ForegroundColor Magenta
write-host “INBOX Rules for Mailbox ‘$RecipientDisplayName’ ($Recipientname):”  “$(get-date)” -ForegroundColor Yellow
Write-Host “=================================================================================================” -ForegroundColor Cyan
Get-InboxRule -mailbox $RecipientName -IncludeHidden | ft @{name=”DisplayName”;expression={(get-recipient $RecipientName).displayname}}, name,enabled,priority,ruleidentity,forward*,RedirectTo,movetofolder,inerror,errortype -Wrap -a
Write-Host “=================================================================================================” -ForegroundColor Cyan
}

#If -NoDescription was selected – Inboxrules to Console Screen :
If ($Description) {
Write-Host “You’ve selected to List the Inbox Rules to the Console With a Description” -ForegroundColor Magenta
write-host “INBOX Rules for Mailbox ‘$RecipientDisplayName’ ($Recipientname):”  “$(get-date)” -ForegroundColor Yellow
Write-Host “=================================================================================================” -ForegroundColor Cyan
Get-InboxRule -mailbox $RecipientName -IncludeHidden | ft name,enabled,priority,ruleidentity,RedirectTo,movetofolder,inerror,errortype,description    -Wrap
#    Get-InboxRule -Mailbox $RecipientName -IncludeHidden | ft -AutoSize
#    (Get-InboxRule -Mailbox $RecipientName -IncludeHidden | ft -AutoSize).count
# FL –      Get-InboxRule -mailbox $RecipientName -IncludeHidden | fl @{name=”DisplayName”;expression={(get-recipient $RecipientName).displayname}}, name,enabled,priority,ruleidentity,forward*,RedirectTo,movetofolder,inerror,errortype,description
# Select –  Get-InboxRule -mailbox $RecipientName -IncludeHidden | select  @{name=”DisplayName”;expression={(get-recipient $RecipientName).displayname}}, name,enabled,priority,ruleidentity,forward*,RedirectTo,movetofolder,inerror,errortype,description
Write-Host “=================================================================================================” -ForegroundColor Cyan
$TotalRulesCount = ((Get-InboxRule -mailbox $RecipientName -IncludeHidden | measure-object).count)
Write-Host “Total Number of rules for $Recipientname is” $TotalRulesCount -ForegroundColor Magenta
Write-Host “=================================================================================================” -ForegroundColor Cyan
}
#################################\\\\\\\\\\\\\\\\////////////////#################################

#If -IndividualList is selected
If ($IndividualList) {
Write-Host “You’ve selected to list each InboxRule individually” -ForegroundColor Magenta
write-host “INBOX Rules for Mailbox ‘$RecipientDisplayName’ ($Recipientname):”  “$(get-date)” -ForegroundColor Yellow
Write-Host “=================================================================================================” -ForegroundColor Cyan
Get-InboxRule -mailbox $RecipientName -IncludeHidden | fl @{name=”DisplayName”;expression={(get-recipient $RecipientName).displayname}}, name,enabled,priority,ruleidentity,forward*,RedirectTo,movetofolder,inerror,errortype,description
Write-Host “=================================================================================================” -ForegroundColor Cyan
$TotalRulesCount = ((Get-InboxRule -mailbox $RecipientName -IncludeHidden | measure-object).count)
Write-Host “Total Number of rules for $Recipientname is” $TotalRulesCount -ForegroundColor Magenta
Write-Host “=================================================================================================” -ForegroundColor Cyan
}
#################################\\\\\\\\\\\\\\\\////////////////#################################

 

If ($CSVFile) {
#####################################################################################
#Inboxrules to CSV file
Write-Host “=================================================================================================” -ForegroundColor Cyan
Write-Host “You’ve selected to send the Inbox Rules to a CSV file.” -ForegroundColor Magenta
Write-host
Write-Host “Rules list was sent to a CSV file located at ***C:\temp\InboxRules-for-$RecipientName.csv***” -ForegroundColor Yellow
$TotalRulesCount = ((Get-InboxRule -mailbox $RecipientName -IncludeHidden | measure-object).count)
Write-Host
Write-Host “Total Number of rules for $Recipientname is” $TotalRulesCount -ForegroundColor Magenta
#Write-Host “=================================================================================================” -ForegroundColor Cyan
Get-InboxRule -mailbox $RecipientName -IncludeHidden | select @{name=”DisplayName”;expression={(get-recipient $RecipientName).displayname}}, name,enabled,priority,ruleidentity,description | export-csv “C:\temp\InboxRules-for-$RecipientName.csv”
Write-Host “=================================================================================================” -ForegroundColor Cyan
} }

 

How to run it

Create a list in notepad, save it as a txt file in c:\temp, or anywhere else and reference that in the script, then run:

get-Rules aceman –description –nodescription –individuallist –csv

Summary

I hope this helps!

Published 2/21/2018

Ace Fekay
MVP, MCT, MCSE 2012, MCITP EA & MCTS Windows 2012|R2, 2008|R2, Exchange 2013|2010EA|2007, MCSE & MCSA 2003/2000, MCSA Messaging 2003
Microsoft Certified Trainer
Microsoft MVP – Mobility

As many know, I work with Active Directory, Exchange server, and Office 365 engineer/architect, and an MVP in Active Directory and Identity Management, and I’m an MCT as well. I try to strive to perform my job with the best of my ability and efficiency, even when presented with a challenge, and then help others with my findings in case a similar issue arises to help ease their jobs. Share the knowledge, is what I’ve always learned.

I’ve found there are many qualified and very informative websites that provide how-to blogs, and I’m glad they exists and give due credit to the pros that put them together. In some cases when I must research an issue, I just needed something or specific that I couldn’t find or had to piece together from more than one site, such as a simple one-liner or a simple multiline script to perform day to day stuff.

I hope you’ve found this blog post helpful, along with my future scripts blog posts, especially with AD, Exchange, and Office 365.

clip_image0023 clip_image0043 clip_image0063 clip_image0083 clip_image0103 clip_image0123 clip_image0143 clip_image0163

Complete List of Technical Blogs
https://blogs.msmvps.com/acefekay/

This posting is provided AS-IS with no warranties or guarantees and confers no rights.


Get-UserList

By Ace Fekay
Published 2/21/2018

Intro

Ace here again. I’ve been playing more and more with scripting and well, I’m far from being an expert, but I continue to read up on it, research, and ask lots of questions.

I thought to share this cool function to enumerate a list of sAMAccountNames and email addresses and validate if the account exists. There isn’t anything out there like this at the moment, at least that I could find, which prompted its creation.

Kudos to my colleague Gamal. that helped me with this script.

Scope

Ever had a list of user accounts that you want to run the Exchange PowerShell cmdlet Get-Recipient to list their email addresses and displayNames, etc?

And the list is mixed with sAMAccountNames, email addresses, and displayNames, and worse, there are spaces and empty lines in the list, and further, they include bunch of accounts that don’t exist that give you that awesome (yea right) RED errors on your screen?

And you have to clean up the list first. Isn’t that a pain to clean it up before you run it?

Here’s a quick function to clean up the list, then enumerate and validate the list, reporting in almost any way you like that also tells you which accounts are invalid, without all those errors.

Get-Recipient

I decided to use Get-Recipient because the Get-Mailbox cmdlet won’t work if the account is a MailUser, Contact, or DL.

Quick script to enumerate and count, but without account validation

(Get-content “c:\temp\email-addresses.txt”) | ? {$_.trim() -ne “” } | set-content “c:\temp\user-list.txt”
$File = ((Get-content “c:\temp\user-list.txt”)).Trim()
$File | get-recipient  -Properties PrimarySmtpAddress ,displayName,name  | ft  Name,DisplayName, prim* -A
Write-Host “Total count:” ($file).Count

Script to enumerate and count, with account validation

Copy and paste the following into notepad, and save it as Get-UserList.ps1, and run it to load the function.

#################\\\\\\\\\\\\\\\\////////////////#################
# This Function (or script without the Function tag) will:
# 1. Reads a text file with mixed sAMAccountName, DisplayNames,
#     or primary email alias (recommended to not use displayNames)
# 2. Clean up white spaces and empty lines in the list
# 3. Searches and performs a validity check creating a report that
#      indicates active and inactive accounts
#
# Usage: Create a file of sAMAccountNames and email addresses,
# save it as a text file, then run Get-UserList
#
# Credit to my colleague Gamal for helping to create this cool script
#################\\\\\\\\\\\\\\\\////////////////#################
Function Get-UserList {

function change-color-red
{
process {Write-Host $_ -ForegroundColor DarkRed}
}
############
$EmailAddressList = “C:\temp\user-list.txt”
$File = ((Get-content $EmailAddressList) | Where-Object {$_.trim() -ne “” }).Trim()

$output = $File | ForEach-Object {

    $exists = if((Get-recipient $_ -erroraction SilentlyContinue)) {
                   Write-Output “Yes”
               }
             else {
                 Write-Output “Does not exist”
             }
     $recipient = Get-Recipient $_ -ErrorAction SilentlyContinue            

    $hash = @{‘Name’ = $_;
               ‘Does-Account-Exist?’ = $exists;
               ‘userID’ = $recipient.SamAccountName
               ‘DisplayName’ = $recipient.DisplayName
               ‘Email’ = $recipient.PrimarySMTPAddress
       }
      
     New-Object psobject -Property $hash
}
Write-Host “******************************************************************************”
$output | ft name,UserId, DisplayName, Email, Does-Account-Exist? -AutoSize | Out-Host
Write-Host “******************************************************************************”
Write-Host “There is/are $(($output).Count) account(s) in the queried user access list.” -ForegroundColor Magenta
Write-Host “Out of the list of users, there is/are $(($output | Where-Object Does-Account-Exist? -EQ ‘Yes’).count) Active account(s).” -ForegroundColor Cyan
Write-Host “Out of the list of users, there is/are $((($output | Where-Object Does-Account-Exist? -EQ ‘Does not exist’) | Measure-Object).count) Inactive account(s).” -ForegroundColor Red
Write-Host “******************************************************************************”
Write-Host “Ref: Part of a Cool Scripts and Functions List! – Ace Fekay”
}
#################////////////////\\\\\\\\\\\\\\\\#################

User list file example

As you can see I’ve mixed up the input type. The first.last represents a saMAccountName,”Ace Fekay” represents a displayname, and of course, email addresses.

============================
Smith, John

Ace Fekay
tom.thumb@contoso.com

j.doe
m.smith
============================

If you have displayNames mixed in the file

Keep in mind, if the displayName is not an exact match, it will result in a “Does Not Exist.” In such cases if you need to look them up, add the –anr (for ambiguous name lookup) to the Get-Recipient cmdlet – there are two lines in the script wtih the Get-Recipient. Add –anr to both, as shown below:

$recipient = Get-Recipient -anr $_ -ErrorAction SilentlyContinue

However, if there are multiple similar names, then you won’t get an accurate report. I’d rather just not use it and just create a user list based on either email addresses or sAMAccount names.           

How to run it

Create a list in notepad, save it as a txt file in c:\temp, or anywhere else and reference that in the script, then run:

get-Userlist

=====================

Summary

I hope this helps!

Published 2/21/2018

Ace Fekay
MVP, MCT, MCSE 2012, MCITP EA & MCTS Windows 2012|R2, 2008|R2, Exchange 2013|2010EA|2007, MCSE & MCSA 2003/2000, MCSA Messaging 2003
Microsoft Certified Trainer
Microsoft MVP – Directory Services

As many know, I work with Active Directory, Exchange server, and Office 365 engineer/architect, and an MVP in Active Directory and Identity Management, and I’m an MCT as well. I try to strive to perform my job with the best of my ability and efficiency, even when presented with a challenge, and then help others with my findings in case a similar issue arises to help ease their jobs. Share the knowledge, is what I’ve always learned.

I’ve found there are many qualified and very informative websites that provide how-to blogs, and I’m glad they exists and give due credit to the pros that put them together. In some cases when I must research an issue, I just needed something or specific that I couldn’t find or had to piece together from more than one site, such as a simple one-liner or a simple multiline script to perform day to day stuff.

I hope you’ve found this blog post helpful, along with my future scripts blog posts, especially with AD, Exchange, and Office 365.

clip_image0023 clip_image0043 clip_image0063 clip_image0083 clip_image0103 clip_image0123 clip_image0143 clip_image0163

Complete List of Technical Blogs (I may be moving the following site): http://www.delawarecountycomputerconsulting.com/technicalblogs.php

Or just search within my blogs:
https://blogs.msmvps.com/acefekay/

This posting is provided AS-IS with no warranties or guarantees and confers no rights.


 

Removing Orphaned Populated msExchangeDelegateLinkList and msExchangeDelegateLinkListBL Automapping Attributes

By Ace Fekay
Published 5/11/2017

Scope

How to remove a shared mailbox that keeps showing up in your Outlook profile that you’ve been removed as a delegate.

To add, this is a big stickler especially with migrating from on-premises to Office 365, where the SendAs permission is now changed, because the permission must be re-assigned to the EXO object, the entity actually sending-As the email as another, and not the on-premises AD object. This also discusses how to remove the original Automapped BL (backlink).

Automapping

Automapping is an Autodiscover feature that was added to Exchange 2010 SP1 and newer, that allows Outlook to automatically add a delegated mailbox without additional tasks.

Autodiscover looks at the mailbox owner’s AD account for an attribute called the MSExchDelegateListLink attribute.

When you use the EAC or PowerShell to delegate permissions to a shared mailbox or to another user, Exchange will automatically set the Automapping feature to $True. In PowerShell you can disable this, but not in the EAC.

This feature populates the MSExchDelegateListLink attribute on the shared or delegated mailbox with the user accounts that will be Automapped, and vice-versa, it also populates the MSExchDelegateLinkListBL attribute on the user account. I look at this as the “back link” to the shared mailbox.

These two attributes are one of  nine (9) links and backlinks that exist. Here’s a list of all links and backlinks in AD and more specifics can be found at the following link:
http://www.neroblanco.co.uk/2015/07/links-and-backlinks-in-active-directory-for-exchange/

Outlook, Autodiscover, and those attributes

When Outlook fires up, and while running, part of what Autodiscover process performs is it will check these two attributes to determine if there are any shared mailboxes that must be automatically added to the Outlook profile. In some cases using a managed process for shared mailboxes, we may want this feature disabled so the shared mailbox does not get automatically added.

Orphaned backlink is still populated and the mailbox still shows up in Outlook

If the user was previously delegated to a shared mailbox, then the delegated per,missions were removed, but for some reason, perhaps replication or corruption, or some other unforeseen factor (large environments fall under this category), the shared mailbox still shows up and you can’t get rid of it, and further, since you no longer have permissions, you can’t open it. This will cause the shared or delegated mailbox to still show up in Outlook. But you can clearly see in EAC or running a get-mailboxpermission that the user is no longer delegated.

Example of an account with the msExchDelegateLinkListBL still populated:

image

 

How to remove it?

First, establish your PowerShell session to Exchange onprem or your Office 365 tenant. If unsure how, see this:
https://blogs.msmvps.com/acefekay/2017/05/11/establishing-a-powershell-session-to-your-office-365-tenant-or-onprem-exchange/

Determine, if any, links or backlinks exist on the shared mailbox:

Get-ADUser “SharedMailboxDisplayName” -Properties msExchDelegateListLink | Select-object -ExpandProperty msExchDelegateListLink

If any show up, you’ll see their sAMAccountNames. If you don’t know who the sAMAccountNames are and you want to see their displayNames, run the following (this command works for DNs, too):

For one account:
get-aduser sAMAccountName -Properties displayName,mail  | ft Name, DisplayName, mail -A

For a list of accounts in a text file:
get-content c:\temp\names.txt | get-aduser -Properties displayName,mail  | ft Name, DisplayName, mail –A

 

Then remove the msexchDelegateLinkListBL orphaned backlink:

Note: I’m using the shared mailbox’s displayName. This will also work using the sAMAaccountName or the primary email address.

For one account:
Remove-MailboxPermission “SharedMailboxDisplayName” -user $_ –AccessRights FullAccess -Confirm:$false

For a list of accounts in a text file:
get-content c:\temp\ace\userIDs\users.txt | foreach {Remove-MailboxPermission “SharedMailboxDisplayName”  -user $_ –AccessRights FullAccess -Confirm:$false}

Then if needed, delegate the shared mailbox again & disabling Automapping

Delegate Ace to a shared mailbox:
Add-MailboxPermission “Shared Mailbox Name or email address” -User AceFekay@contoso.com -AccessRights FullAccess -AutoMapping:$false

 

============================================================

Summary

I hope this helps!

Published 5/18/2017

Ace Fekay
MVP, MCT, MCSE 2012, MCITP EA & MCTS Windows 2008/R2, Exchange 2013, 2010 EA & 2007, MCSE & MCSA 2003/2000, MCSA Messaging 2003
Microsoft Certified Trainer
Microsoft MVP – Directory Services

As many know, I work with Active Directory, Exchange server, and Office 365 engineer/architect, and an MVP in Active Directory and Identity Management, and I’m an MCT as well. I try to strive to perform my job with the best of my ability and efficiency, even when presented with a challenge, and then help others with my findings in case a similar issue arises to help ease their jobs. Share the knowledge, is what I’ve always learned.

I’ve found there are many qualified and very informative websites that provide how-to blogs, and I’m glad they exists and give due credit to the pros that put them together. In some cases when I must research an issue, I just needed something or specific that I couldn’t find or had to piece together from more than one site, such as a simple one-liner or a simple multiline script to perform day to day stuff.

I hope you’ve found this blog post helpful, along with my future scripts blog posts, especially with AD, Exchange, and Office 365.

 

clip_image0023 clip_image0043 clip_image0063 clip_image0083 clip_image0103 clip_image0123 clip_image0143 clip_image0163

Complete List of Technical Blogs: http://www.delawarecountycomputerconsulting.com/technicalblogs.php

Or just search within my blogs:
https://blogs.msmvps.com/acefekay/

This posting is provided AS-IS with no warranties or guarantees and confers no rights.


Establishing a PowerShell Session to Your Office 365 Tenant or OnPrem Exchange

By Ace Fekay
Published 5/11/2017

Prelude

I’m working on posting more scripting blogs managing Active Directory, Office 365, and Exchange OnPrem, or On Premises.

And I stress the phrase, “On Premises,” and NOT “On Premise!”

Scope

Instead of repeating this procedure in each blog I write that has something to do about scripting where you must connect a PowerShell or an ISE session (I’d rather use ISE) to the tenant or OnPrem box, I thought to just put this together and reference the URL to connect. It’s easier and takes up less space on the blog with the actuals PS commands and scripts.

Office 365 tenant without ADFS

If you are not using multifactor auth or ADFS, open a PowerShell window and the run the following:

$MySession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell/ -Credential $YourCred -Authentication Basic –AllowRedirection

This will prompt you for your credentials. Then import the session you just created:
import-pssession $MySession

If using a Proxy:

$MySession = New-PSSession -ConfigurationName Microsoft.Exchange –ConnectionUri https://ps.outlook.com/powershell/ -Credential $YourCred -Authentication Basic –AllowRedirection (New-PSSessionOption -ProxyAccessType IE)

This will prompt you for your credentials. Then import the session you just created:
import-pssession $MySession

Import AD Module:

I always import the Active Directory module so I can run AD tools. Of course, you will need AD permissions to modify, but anyone can read properties:

Import-module ActiveDirectory

.

Office 365 ADFS and/or Multifactor Auth

Go to http://aka.ms/exopspreview. It will open and create a PowerShell session specifically to assist with establishing a session with Office 365. Then run the following:

Connect-EXOPSSession -UserPrincipalName YourEmail@contoso.com -PSSessionOption

If using a Proxy:

Connect-EXOPSSession -UserPrincipalName YourUserNamea@contoso.com -PSSessionOption (New-PSSessionOption -ProxyAccessType IE)

Import the AD Module:

I always import the Active Directory module so I can run AD tools. Of course, you will need AD permissions to modify, but anyone can read properties:

Import-module ActiveDirectory

.

Exchange OnPrem

$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://Exchange02.contoso.local/PowerShell/ -Authentication Kerberos
Import-PSSession $Session
Add-PSSnapin Microsoft.Exchange.Management.Powershell.Support

Import the AD Module:

I always import the Active Directory module so I can run AD tools. Of course, you will need AD permissions to modify, but anyone can read properties:

Import-module ActiveDirectory

.

============================================================

Summary

I hope this helps!

Published 5/11/2017

Ace Fekay
MVP, MCT, MCSE 2012, MCITP EA & MCTS Windows 2008/R2, Exchange 2013, 2010 EA & 2007, MCSE & MCSA 2003/2000, MCSA Messaging 2003
Microsoft Certified Trainer
Microsoft MVP – Directory Services

clip_image0023 clip_image0043 clip_image0063 clip_image0083 clip_image0103 clip_image0123 clip_image0143 clip_image0163

Complete List of Technical Blogs: http://www.delawarecountycomputerconsulting.com/technicalblogs.php

Or just search within my blogs:
https://blogs.msmvps.com/acefekay/

This posting is provided AS-IS with no warranties or guarantees and confers no rights.

Remote Server Administration for Windows 2012 R2

image

 

Prologue

Ace here again. This discusses remote administration. Simple, right? Maybe not!

Remote Server Administration for Windows 2012 R2

Server Manager in Windows Server® 2012 R2 can be used to perform various management tasks on remote servers. By default, remote management is enabled on Windows Server 2012 R2.You can add remote servers to the Server Manager Server pool in Windows Server 2012 R2 Server Manager.

Objectives

Discuss the following remote admin methods

  • What is Remote Management?
  • How to Enable and Disable Remote Management
  • Remote Management and Tools Commands
  • Server Manager
  • WinRM
  • PowerShell Remoting
  • Remote Desktop
  • Remote Server Administration Tools (RSAT)
  • SCONFIG

What is Remote Management?

Windows Server 2012 R2 provides the ability to remotely manage multiple servers with a number of methods. One of the newest features in Windows Server 2012 is the ability to use Server Manager for this task.

In addition to Windows Remote Management, you can also use Remote Shell and Remote Windows PowerShell to manage remote computers. This provides you the ability to locally load Windows PowerShell modules, such as Server Manager, and execute PowerShell cmdlets available in the loaded module on remote servers. This allows you the ability to run PowerShell commands and scripts. This works including when the script is only on the local server

Windows Remote Management (WinRM) is the Windows implementation of WS-Management, which is an industry standard, Web-based services based protocol. Windows runs the WinRM as a service under the same name, WinRM. WinRM provides secure local and remote communications for management applications and scripts.

In addition, Windows Remote Management is one of the components of the Windows Hardware Management features to allow secure local and remote Windows Server management across a firewall using standard Web service-based protocols.

If the server hardware has an optional, built-in Baseboard Management Controller (BMC) provided by the hardware vendor, you can also remotely manage a system even if the Windows operating system has not yet booted or has failed. This also allows access to the server’s BIOS.

A BMC is an option m provided by hardware vendors, that consists of a microcontroller and an independent network connection that you can communicate to if the server ever becomes offline.

When a server is not connected to a BMC, WinRM can still be used to connect to WMI remotely in situations where firewalls may block DCOM communications, because WinRM uses the secure web-based port, TCP 443.

Additional Reading on WinRM:

About Windows Remote Management
http://msdn.microsoft.com/en-us/library/windows/desktop/aa384291(v=vs.85).aspx

Hardware Management Introduction (includes BMC information)
http://technet.microsoft.com/en-us/library/f550cac0-5344-41cb-8e89-6e5c93236886

.
 
How to Enable and Disable Remote Management

There are a number of methods to administer WinRM.

· Winrm.cmd – Command line tool that allows administrators to configure WinRM, get data, or manage resources. For syntax, you can run winrm /? for online help.

· Win-RM Scripting API – Allows you to create remote administration scripts that expose the WS-Management APIs and protocols.

· Winrs.exe –A command line tool to execute CMD commands on remote servers using WS-Management APIs. For example, to remotely get an ipconfig /all from a remote machine, you can run:
winrs –r:DC12.trimagna.com “ipconfig /all”;tasklist

You can also use the help command to see all possible options and syntax:
winrs –?

· IPMI and WMI Providers – The IPMI provider and drivers allow remote hardware management using BMC. These can be used programmatically.

· WMI Service – Using the WMI plug-in, WMI runs together with WinRM to provide data or control functions for remote management.

· WS-Management protocol – SOAP based protocol using XML messages. It is a web-based, firewall friendly protocol running across secure TCP 443 providing industry-standard interoperability to transfer and exchange management information.

Remote Management Tools and Commands

There are a number of ways to enable, disable and configure Remote Management.

Server Manager

To enable or disable Remote Management, in Server Manager Local Server node, click the text next to Remote Management icon.

WinRM Command

You can use the WinRM command to enable, disable, and configure Remote Management.

The syntax is:

WinRM OPERATION RESOURCE_URI [-SWITCH:VALUR [-SWITCH:VAKLUE] …] [@{KEY=VALUR [;KEP=VALUE]…}]

You can use the following to check the current Remote Management configuration and status:
winrm get winrm/config

Or you can run it remotely on another server using the WinRS command:
winrs –r:DC12-1.trimagna.com “winrm /config”;tasklist

To enable or disable Remote Management:
WinMR qc

When the WinRM qc command is run, it performs a number of steps to enable and configure the Remote Management service:

  1. Configures and changes the WinRM service from Manual to Automatic startup.
  2. Starts the WinRM service.
  3. Creates and configures a listener that will accept WinRM requests on any IP address.
  4. Creates a Windows Firewall exception for WS-Management traffic for the HTTP protocol.

If the Windows Firewall is disabled, you will see one of the following error messages:

  • WSManFault
  • Message
  • ProviderFault
  • WSManFault
  • Message = Unable to check the status of the firewall.
  • Error number: -2147023143 0x800706D9
  • There are no more endpoints available from the endpoint mapper.

To view the command syntax and options, you can run winrm -?

WinRM supports the following commands:

  • PUT
  • GET
  • ENUMERATION
  • INVOKE
WinRM Examples:

Start a service on a remote machine:
winrm invoke startservice wmicimv2/Win32_Service?name=w32time -r:DC12

Reboot a remote machine:
winrm invoke reboot wmicimv2/Win32_OperatingSystem -r:FS1

Additional Reading on the WinRM commands:

An Introduction to WinRM Basics – From the EPS Windows Server Performance Team
http://blogs.technet.com/b/askperf/archive/2010/09/24/an-introduction-to-winrm-basics.aspx

.

PowerShell Remoting

There a number of cmdlets that use WMI for remote administration. The cmdlets invoke a temporary connection the remote computer using WMI, runs the command, then closes the session.

These cmdlets do not use WS-Management based remoting, therefore the computer does not require to be configured for WS-Management nor does it have to meet the system requirement for WS-Management. Because they are not WS-Management service related, you can use the ComputerName parameter in any of these cmdlets

You can run the Invoke-Command cmdlets to run commands on other computers.

For example, to get a list of all services on a remote computer that are either running or stopped, you can run the following command
Invoke-Command –computername DC12 –scriptblock {get-service)

Or to see the status of a single service:
Invoke-Command –computername DC12 –scriptblock {get-service WinRm)

Additional Reading on Remote PowerShell:

Windows PowerShell Remoting – Complete list of commands
http://msdn.microsoft.com/en-us/library/windows/desktop/ee706585(v=vs.85).aspx

.

 

Remote Server Administration Tools (RSAT) for Windows

Remote Server Administration Tools for Windows®  includes Server Manager, Microsoft Management Console (MMC) snap-ins, consoles, Windows PowerShell® cmdlets and providers, and some command-line tools for managing roles and features that run on Windows Server 2012 R2.

.

SCONFIG

For Server Core, you can use the SCONFIG command and choosing Option #4, then choosing Option #1 to Enable Remote Management, or Option #2 to Disable Remote Management.

image

Additional Reading on WinRM tools

About Windows Remote Management
http://msdn.microsoft.com/en-us/library/windows/desktop/aa384291(v=vs.85).aspx

.

Remote Desktop

Remote Desktop has been used for a number of years, and it is the most common method to remotely administer a remote machine. To use Remote Desktop, it must be enabled first on the remote computer. To enable Remote Desktop on the full version of Windows Server 2012, perform the following steps”

  1. Open Server Manager
  2. Click the Local Server Node
  3. Click the “Disabled” status next to Remote Desktop.
  4. The System Properties page appears and is focused on the Remote tab.
  5. Under the Remote tab, select one of the following:
  1. Don’t allow connections to this computer – Default disabled.
  2. Allow connections only from Computers running:
  1. Checkbox: Allow Remote Desktop with Network Level Authentication – If you check this box, this setting enables and only allows secure connections from Remote Desktop clients that support network-level authentication.

image

You can also enable Remote Desktop on Sever Core using the SCONFIG command.

==================================================================

 

Ace Fekay
MVP, MCT, MCSE 2012, MCITP EA & MCTS Windows 2008/R2, Exchange 2013, 2010 EA & 2007, MCSE & MCSA 2003/2000, MCSA Messaging 2003
Microsoft Certified Trainer
Microsoft MVP – Directory Services

clip_image0023 clip_image0043 clip_image0063 clip_image0083 clip_image0103 clip_image0123 clip_image0143 clip_image0163

Complete List of Technical Blogs: http://www.delawarecountycomputerconsulting.com/technicalblogs.php

This posting is provided AS-IS with no warranties or guarantees and confers no rights.

PowerShell Script to Search Netlogon for a Specific List of Script files to Replace or Alter Drive Mappings

Updates/Edits:

10/12/2015: I’ve updated the script to allow multiple, simultaneous changes for a list of bat files, and no need to manually add “.bat” to the list of user account samAccount names.

Prologue

Yes, it’s me again, Ace Fekay.

You’ve already *probably* read my recent blog:

PowerShell Script to Search Netlogon logon scripts and Replace Drive Mappings – 9/10/2015
https://blogs.msmvps.com/acefekay/2015/09/10/script-to-search-netlogon-logon-scripts-and-replace-drive-mappings/

That blog is about searching all script files that end with *.bat, and make changes to the files.

This time we’re going to run something similar, but for a strict list of specific files (user logon scripts) for a list of users. This came about when a request came in to remove access to 140 users and remove their drive mappings, and another request to alter access for 120 users’ scripts.

To remove drive mapping is easy. The following shows our normal mapping method in each script:

:: Access has been provided by Ace Fekay on 10/3/2015 with approval in Ticket# 123456
net use t: /del
net use t: \\contoso.com\sharename

And for the ones we are removing access, we can keep the net use t: .del to delete the mappings when the user logs on, but we want to comment out the mapping, as such:

::Access Removed per Ace Fekay in Ticket# 123456 – net use x: \\contoso.com\SomeShareName$

And of course, this is based on reading a list of script.bat file names in a text file appropriately called, “SomeShareNameRemoveMappingsUserListBat.txt.”

Have fun!

Script:

– Updated script: 10/11/2015:

# *************************************************************************************
# If this is a migration, first run the robocopy script to copy all data
# Then run the netlogon report script to see how many bat files in netlogon
#    reference OldServerName
# Then run this script to replace any reference to OldServerName in the batch
#    files for each share.
# *************************************************************************************
# Modified by Ace Fekay 10/11/2015
#
# Changes:
#    Input file just needs to be samAccount names and no longer need .bat suffixed
#    Allows to change multiple scripts as long as they have a common name,
#    such as the server name
#    Accommodates if the multiple users have different mapped drive letters.
#
# *************************************************************************************

get-credential

# Used for testing – $Path = “\\contoso.com\NETLOGON\test-RemoveMapping2”

$Path = “\\contoso.com\NETLOGON”
$WhatAmIlookingFor = “contoso.com”

#This grabs the list of user UserAccounts from the input file.
$SourceListOfUserAccounts = “C:\PSScripts\Netlogon Search and Replace\UserFileList.txt”

#Example of UserFileList.txt:
# username1
# username2
# username3
# etc

cd $Path
$RemoveMappedDriveFromUserList = (get-content $SourceListOfUserAccounts)
$UserCount = 0
$MappingsRemoved = 0

Foreach ($User in $RemoveMappedDriveFromUserList) {

#This will annotate/suffix “.bat” to the end of each user name
$UserScript = $User+”.bat”
$UserCount++

$file = get-content $UserScript

    #only modify files that contain the string $WhatAmILookingFor
    if (Select-String -InputObject $file $WhatAmIlookingFor){

$MappingsRemoved++

    $file = $file -replace “net use .?\: \\\\contoso.com\\ShareName1″,”::Mapped Drive Access Removed by Ace Fekay per Ticket# 123456 – net use ?: \\contoso.com\ShareName1
    $file = $file -replace “net use .?\: \\\\contoso.com\\ShareName2\$”,”::Mapped Drive Access Removed by Ace Fekay per Ticket# 123456 – net use ?: \\Malvern\output$ \\contoso.com\ShareName2$
    $file = $file -replace “net use .?\: \\\\contoso.com\\ShareName3″,”::Mapped Drive Access Removed by Ace Fekay per Ticket# 123456 – net use ?: \\contoso.com\ShareName3

# *************************************************************************************
# Previous stuff I kept here for future reference but commented out:
#    $file = $file -replace “\\\\OldServerName\\ShareName1$”,”\\contos.com\ShareName1$”
#    $file = $file -replace “\\\\OldServerName\\ShareName2″,”\\contos.com\ShareName2”
#    $file = $file -replace “\\\\OldServerName\\ShareName3″,”\\contos.com\ShareName3”
#    $file = $file -replace “\\\\OldServerName\\ShareName4″,”\\contos.com\ShareName4”
#    $file = $file -replace “\\\\OldServerName\\ShareName5″,”\\contos.com\ShareName5”
#    $file = $file -replace “\\\\OldServerName\\ShareName6″,”\\contos.com\ShareName6”
#    $file = $file -replace “\\\\OldServerName\\ShareName7″,”\\contos.com\ShareName7”
#    $file = $file -replace “\\\\OldServerName\\ShareName8″,”\\contos.com\ShareName8”
#    $file = $file -replace “\\\\OldServerName\\ShareName9″,”\\contos.com\ShareName9”
# *************************************************************************************
   
#comment out net time statements if they exist
    $file = $file -replace “^net time”,”REM net time”
   
#write out the changes
    Set-Content -Value $file -Path $UserScript
    write-host $UserScript “was changed to” $file
    }
}

write-host “Total users:” $UserCount
write-host “Total Mappings removed:” $MappingsRemoved
# *************************************************************************************
# *************************************************************************************

– Old script prior to 10/10/2015:

# *************************************************************************************
# If this is for post-migration, first run the robocopy script to copy all data
# Then run the netlogon search report script to see how many script.bat files in netlogon reference SomehareName
# Then run this to replace any reference to SomeShareName to TheNewShareName or even just to disable the share or shares.
# Highly modified by Ace Fekay 10/3/2015
# *************************************************************************************

get-credential

$Path = “\\contoso.com\NETLOGON”

# This code snippet gets all the files in $Path that end in “.bat”.
cd $Path

$RemoveMappedDriveFromUserList = (get-content “C:\PSScripts\Netlogon Search and Replace\SomeShareNameRemoveMappingsUserListBat.txt”)
 
$UserCount = 0
$MappingsRemoved = 0

Foreach ($User in $RemoveMappedDriveFromUserList) {
$UserCount++
$file = $RemoveMappedDriveFromUser

# Only modify files that contain the string “SomeShareName”
    if (Select-String -InputObject $file “SomeShareName”){

$MappingsRemoved++

# Note that the following is doing a number of things, such as commenting out mappings that they are no longer permitted to use,
# providing comments, changing or updating sharenames, etc.
    $file = $RemoveMappedDriveFromUser
    $file = $file -replace “net use g\: \\\\contoso.com\\SomeShareName\$”,”::Access Removed per Ace Fekay in Ticket# 123456 – net use g: \\contoso.com\SomeShareName$”
    $file = $file -replace “net use X\: \\\\contoso.com\\SomeShareName\$”,”::Access Removed per Ace Fekay in Ticket# 123456 – net use x: \\contoso.com\SomeShareName$”
    $file = $file -replace “net use z\: \\\\contoso.com\\SomeOldShareName\$”,”net use z: \\contoso.com\SomeNewShareName$”
    $file = $file -replace “\\\\OldServerName\\ShareName1$”,”\\contoso.com\ShareName1$”
    $file = $file -replace “\\\\OldServerName\\ShareName2$”,”\\contoso.com\ShareName2$”
    $file = $file -replace “\\\\OldServerName\\ShareName3$”,”\\contoso.com\ShareName3$”
    $file = $file -replace “\\\\OldServerName\\ShareName4$”,”\\contoso.com\ShareName4$”
    $file = $file -replace “\\\\OldServerName\\ShareName5$”,”\\contoso.com\ShareName5$”

# Comment out net time statements
    $file = $file -replace “^net time”,”REM net time”
   
# Write out the changes
    Set-Content -Value $file -Path $_;
    }
}

write-host “Total users:” $UserCount
write-host “Total Mappings removed:” $MappingsRemoved
# *************************************************************************************

 

More to come…

Comments are welcomed.

==================================================================

Summary

I hope this helps!

Published 10/3/2015

Ace Fekay
MVP, MCT, MCSE 2012, MCITP EA & MCTS Windows 2008/R2, Exchange 2013, 2010 EA & 2007, MCSE & MCSA 2003/2000, MCSA Messaging 2003
Microsoft Certified Trainer
Microsoft MVP – Directory Services

clip_image002622[2][2][2] clip_image004622[2][2][2] clip_image006622[2][2][2] clip_image008622[2][2][2] clip_image010622[2][2][2] clip_image012622[2][2][2]

Complete List of Technical Blogs: http://www.delawarecountycomputerconsulting.com/technicalblogs.php

This posting is provided AS-IS with no warranties or guarantees and confers no rights.

Migrate Files to a new File Server using RoboCopy, IP addresses, and Relative Paths using the Administrative Shares

Prologue

Ace Fekay here again.

You might say to yourself this is some really simple stuff. Sure, it might be, for the pro. As many of you know, I’m an avid Active Directory and Exchange server engineer/architect, and an MVP in Active Directory.

Therefore with AD, Exchange, and Office 365, you will find that scripting comes into play more and more with your daily tasks.  The main reason I’m posting simple scripts is that to get the job done, I just needed an arsenal of simple quickie scripts when called upon a simple task, such as this one, when tasked to quickly get a list of users in a group.

I hope this, and my future scripts, especially with Office 365, help you out.

Scope

This is one method to migrate data from one file server to another. I have one method that I will post later, that does it by the share names. This is to just get the two closer to having the same data before I run the final script.

DFS

Keep in mind, we use DFS. I will already have created a new target to the new file server for the current share, but keep the new targets disabled until ready to cut over.

However, when we cut over the target to the new server, we would like to shut off the shares on the source (old) server, to prevent anyone from using it. Of course, we’ve already communicated to the user base the migration schedule.

Therefore, since the shares will be deleted, we must rely on running this by using IP addresses and relative paths from the default administrative shares (c$, d$, etc).

Share and NTFS Permissions Backup

Yes, absolutely! You definitely want to back up your Share and NTFS permissions on this server just in case something happens! The following link is a great article to show you how to do it:

How to Back Up and Restore NTFS and Share Permissions
http://blogs.technet.com/b/askds/archive/2008/11/24/how-to-back-up-and-restore-ntfs-and-share-permissions.aspx

Easy? Nah…

Many may say this is simple stuff. Sure, for the seasoned scripter, which I’m not, The main reason I’m posting this, and I will be posting much more, including Office 365 scripts, is that I had to look it up. I’ve found various websites that provide how-tos, but when it comes to handling variables and piping, I’ve found there is no one place to get various examples and have found myself looking at multiple places to get this info, including my colleagues, who are extremely adept at scripting. With many place, I also see elaborate scripts that do more than what I need. They are fabulous blogs and websites, but sometimes I need the simple one-liners to perform day to day stuff.

Script:

/

# Uses relative paths
# Make sure you change directory to where your script is located on the computer you are running this before running
#
# =========================================================================================
#Function: Get the Total Size of Folder

function Get-Size
{
     param([string]$pth)
     “{0:n2}” -f ((gci -path $pth -recurse | measure-object -property length -sum).sum /1mb) + ” mb”
}
# =========================================================================================
#
cd “C:\PSScripts\OldServerName”

$SourceServerNetBIOSName =     “OldServerName”
$SourceServerIP =         “10.100.200.200”
$DestinationServerName =     “NewFileServer.contoso.com”

#**************************************************************************************
#Ignore this section
#Test files with only one share

#Note: This section was a test to see if I can get this script to work if there is only one share.
#I could not get it to work with one share. The reason is there must be two (2) or more shares for
#this to work, because I’m using an array. There is no such thing as a single array.

#$SourceServerPath =            @()
#$SourceServerShares =          @()
#$DestinationServerShareNames = @()

#$SourceServerPath =            Get-Content ‘.\OldServerName-Share-paths-test.txt’
#$SourceServerShares =          Get-Content ‘.\OldServerName-SourceSharesList-test.txt’
#$DestinationServerShareNames = Get-Content ‘.\OldServerName-DestinationSharesList-test.txt’

#Ignore this section
#**************************************************************************************

$SourceServerPath =            Get-Content ‘.\OldServerName-Share-paths.txt’
$SourceServerShares =          Get-Content ‘.\OldServerName-SourceSharesList.txt’
$DestinationServerShareNames = Get-Content ‘.\OldServerName-DestinationSharesList.txt’

$LogDestinationFolder = “.\Logs”
$LogfileName = $SourceServerNetBIOSName+”.txt”
$LogFileAndPath = $LogDestinationFolder+”\”+$LogfileName

# Checks for existence of a directory for log files if not, one gets created.
If (!(Test-Path -Path $LogDestinationFolder)){
    New-Item -ItemType directory -Path $LogDestinationFolder
}

write-host “Total Share count = ” $SourceServerShares.count

for ($i = 0; $i -lt $SourceServerShares.count; $i++){

    $srcpath = $SourceServerPath[$i] -replace ‘(.*):’,’$1$’
    #$srcpath = $SourceServerPath -replace ‘(.*):’,’$1$’
    $dstpath = $DestinationServerShareNames[$i]

    $FullSourcePath = “\\”+$SourceServerIP+”\”+$srcpath
    $FullDestPath = “\\”+$DestinationServerName+”\”+$dstpath

    write-host “”
   
    if ((Test-Path $FullSourcePath) -and (Test-Path $FullDestPath))
    {
        $log = $LogDestinationFolder + “\” + $SourceServerNetBIOSName + “-” + $SourceServerShares[$i] +”.txt”
        write-host “Current share’s log:” $Log
       
        robocopy $FullSourcePath $FullDestPath /E /R:1 /W:1 /TEE /log:$log | Out-String

    #This is trying different switches – Ignore
        #robocopy $FullSourcePath $FullDestPath /MIR /copy:DT /W:5 /R:1 /V /IT /FP /NFL /TS  /log:$log | Out-String

    #This was a local drive to drive attempt – Ignore
    #robocopy e:\users y: /copy:DATSO /E /R:1 /W5 /TEE /log:c:\robocopy.log

    write-host “Source path is: ” $srcpath
        write-host “Full Source Path is: ” $FullSourcePath
    write-host “Destination path is:” $dstpath
        write-host “Full Destination path is: ” $FullDestPath

        $SharesProcessedSoFar = $i + 1
        write-host “Shares processed so far =” $SharesProcessedSoFar ” out of a total share count of ” $SourceServerShares.count
        write-host “”
        Write-Host “”
    }

    else

    {
        write-host “Problem with: ”           $srcpath         “Destination sharename is:”     $dstpath
        write-host “Referencing full Source Path:” $FullSourcePath  “Destination Path:”         $FullDestPath
        $SharesProcessedSoFar = $i + 1
        write-host “Shares processed so far =” $SharesProcessedSoFar ” out of a total share count of ” $SourceServerShares.count
    }
}
write-host “Total Shares processed = ” $SourceServerShares.count

More to come…

Comments are welcomed.

==================================================================

Summary

I hope this helps!

Published 10/3/2015

Ace Fekay
MVP, MCT, MCSE 2012, MCITP EA & MCTS Windows 2008/R2, Exchange 2013, 2010 EA & 2007, MCSE & MCSA 2003/2000, MCSA Messaging 2003
Microsoft Certified Trainer
Microsoft MVP – Directory Services

clip_image002622[2][2] clip_image004622[2][2] clip_image006622[2][2] clip_image008622[2][2] clip_image010622[2][2] clip_image012622[2][2]

Complete List of Technical Blogs: http://www.delawarecountycomputerconsulting.com/technicalblogs.php

This posting is provided AS-IS with no warranties or guarantees and confers no rights.

Office 365 PowerShell Fun with Calendars

Published 9/13/2015

Prologue

Ace Fekay here again.

You might say to yourself this is some really simple stuff. Sure, it might be, for the pro. As many of you know, I’m an avid Active Directory and Exchange server engineer/architect, and an MVP in Active Directory.

Therefore with AD, Exchange, and Office 365, you will find that scripting comes into play more and more with your daily tasks.  The main reason I’m posting simple scripts is that to get the job done, I just needed an arsenal of simple quickie scripts when called upon a simple task, such as this one, dealing with mailbox permissions.

I hope this blog and my future scripts blogs, especially with Office 365, help you out.

Scope

These are a few examples of dealing with every day requests for calendar administration. Sure, you can do it from your web based, Office 365 tenant dashboard, but what fun is that?

And yes, this is simple stuff. The main reason I’m posting this, and I will be posting much more, including Office 365 scripts, is that I had to look it up. I’ve found various websites that provide how-tos, but when it comes to handling variables and piping, I’ve found there is no one place to get various examples and have found myself looking at multiple places to get this info, including my colleagues, who are extremely adept at scripting. With many place, I also see elaborate scripts that do more than what I need. They are fabulous blogs and websites, but sometimes I need the simple one-liners to perform day to day stuff.

Open PowerShell session and Login – Of course you first have to open a PowerShell session to your tenant account

Open a PowerShell window.
Run the following:
$MySession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell/ -Credential $AceCred -Authentication Basic -AllowRedirection

This will prompt you to login using your credentials.
Then run:
import-pssession $MySession

To be able to run Start-OnlineCoexistenceSync Dirsync – on a DC

After you make any changes in your local AD, instead of waiting for the dirsync schedule to run, you can manually run a dirsync on your onprem AD to force a sync:

Command Prompt
cd “C:\Program Files\Microsoft Online Directory Sync”
Run:
.\DirSyncConfigShell.psc1

Or just run:
“C:\Program Files\Microsoft Online Directory Sync\DirSyncConfigShell.psc1”
Then run:
Start-OnlineCoexistenceSync  or invoke-dirsync

To view the dirsync log, click on the DirSync icon in task bar that opens the Synchronization Service Manager. If it’s not on the task bar, it can be found in:

“C:\Program Files\Microsoft Online Directory Sync\SYNCBUS\Synchronization Service\UIShell\miisclient.exe”

===========================================================

General Calendar Commands

To view the rights on a calendar:

get-mailboxfolderpermission MarySmith@contoso.com:\Calendar

To add rights to a calendar for a user, JohnDoe, and providing him “Editor” access rights:

Add-MailboxFolderPermission -Identity Office.Vacation.Calendar@contoso.com:\Calendar -User JohnDoe@contoso.com -AccessRights Editor

To remove JohnDoe’s rights from a calendar:

remove-mailboxfolderpermission -Identity Office.Vacation.Calendar@contoso.com:\Calendar -User JohnDoe@contoso.com

Rule to move anything with subject, “Sent by Microsoft Exchange Server 2013” to a folder called, “Rejected Calendar Notifications”

New-InboxRule “Sent by Exchange 2013” -Mailbox MarySmith@contoso.com -MyNameInToBox $true -FlaggedForAction Any -SubjectOrBodyContainsWords “Sent by Microsoft Exchange Server 2013” -MoveToFolder “Rejected Calendar Notifications” -StopProcessingRules

New-InboxRule “SendOnBehalf Sent by Exchange 2013” -Mailbox JohnDoe -MyNameInToBox $true -FlaggedForAction Any -SubjectOrBodyContainsWords “Sent by Microsoft Exchange Server 2013” -MoveToFolder “Rejected Calendar Notifications” –StopProcessingRules

Create a shared calendar in Office 365 without creating it in our Active Directory so we don’t get charged for a license.

This is an example for creating a shared calendar called “Ace’s Cancelled Meetings” with a username of AceCancelledMeetings.

1. New-Mailbox -Name “AceCancelledMeetings” -DisplayName “Ace’s Cancelled Meetings” -Share

If required:
2.  UserPrincipalName: AceCancelledMeetings@YourDomain.onmicrosoft.com

Give permissions for Mary Smith (MarySmith) to access the calendar.
3.  Add-MailboxfolderPermission AceCancelledMeetings:\Calendar -user “MarySmith” -AccessRights editor  

Give permissions for John Doe (JohnDoe) to access the calendar.
4.  Add-MailboxfolderPermission AceCancelledMeetings:\Calendar -user “JohnDoe” -AccessRights editor  

Give permissions for John Smith (JohnSmith) to access the calendar:
5. Add-MailboxfolderPermission AceCancelledMeetings:\Calendar -user “JohnSmith” -AccessRights editor

Get permissions Examples for a calendar:

PS C:\Windows> (Get-MailboxFolderPermission JohnDoe:\Calendar) | select user

Output:

User
—-
Default
User One
User Two
User Three
User Four
User Five
User Six
User Seven
User Eight

To display the accessrights for a calendar:

PS C:\> (Get-MailboxFolderPermission JohnDoe:\Calendar) | select user,accessrights

User                AccessRights
—-                ————
Default                {AvailabilityOnly}
User One            {Reviewer}
User Two            {Reviewer}
User Three            {Reviewer}
User Four            {Reviewer}
User Five            {Reviewer}
User Six            {Editor}
User Seven            {Editor}
User Eight            {Editor}
User Nine            {Owner}

PS C:\> get-MailboxFolderPermission -Identity ConfRoom1:\Calendar

FolderName           User        AccessRights
———-           —-        ————
Calendar             Default        {AvailabilityOnly}
Calendar             Anonymous        {None}
Calendar             Ace Fekay        {Editor}
Calendar             User One        {PublishingEditor}
Calendar             User Two        {PublishingEditor}
Calendar             User Three        {PublishingEditor}
Calendar             User Four        {PublishingEditor}
Calendar             User Five        {Editor}

Office 365 Alias issues

If the user’s alias, such as “JohnDoe,” doesn’t work, run the following to find and use the identifier Microsoft assigned to the user:
get-mailbox JohnDoe@contoso.com
    For example, the above query returned:   
        JohnDoe_8672d315f2
    Therefore, I had to run the following command to add permissions for that user:
    Add-MailboxFolderPermission -Identity ConfRoom22:\Calendar -User “JohnDoe_8672d315f2” -AccessRights Reviewer

Command to Add permissions to one Calendar for multiple users (list of users) importing a list of users in a text file and piping the command:

Get-Content c:\Scripts\users.txt | foreach {Add-MailboxFolderPermission -Identity Classroom2:\calendar -User $_ -AccessRights Editor}

Content of “users.txt:”
UserOne@contoso.com
UserTwo@contoso.com
UserThree@contoso.com
UserFour@contoso.com
UserFive@contoso.com
UserSix@contoso.com
UserSeven@contoso.com
UserEight@contoso.com

If you need to change the permissions on the calendar for a set of user, use the same format except use the ‘set-calendar’ command:

Get-Content c:\Scripts\users.txt | foreach {Set-MailboxFolderPermission -Identity Classroom2:\calendar -User $_ -AccessRights Editor}

If you need to give a single user permissions to multiple calendars:

This is giving MikeSmith@contoso.com access to multiple calendars

Get-Content C:\Scripts\ListOfCalendars.txt | foreach {Add-MailboxFolderPermission -Identity $_ -User MikeSmith@contoso.com -AccessRights Editor}

Content of “ListOfCalendars.txt:”

HospitalFloor1West@contoso.com:\Calendar
HospitalFloor1East@contoso..com:\Calendar
HospitalFloor1South@contoso..com:\Calendar
HospitalFloor1North@contoso..com:\Calendar
HospitalFloor2West@contoso..com:\Calendar
HospitalFloor2East@contoso..com:\Calendar
HospitalFloor2South@contoso..com:\Calendar
HospitalFloor2North@contoso..com:\Calendar

To provide permissions to multiple calendars for a list of users.

There are two variables in this scenario.

First you must bring in the list of users into memory. In this case, the users are in filename, “ListOfUsers.txt.” Now run the following to bring the users

Pull the list into memory:
PS C:\> $users= get-content C:\Scripts\ListOfUsers.txt

If you like, you can double check and see what’s in the file you just pulled in by simply typing in the variable name and hit enter:

PS C:\> $users
UserOne@contoso.com
UserTwo@contoso.com
UserThree@contoso.com
UserFour@contoso.com
UserFive@contoso.com
UserSix@contoso.com
UserSeven@contoso.com
UserEight@contoso.com
etc

You can also run the following format to get the same info on the file:

PS C:\> $users | get-member
UserOne@contoso.com
UserTwo@contoso.com
UserThree@contoso.com
UserFour@contoso.com
UserFive@contoso.com
UserSix@contoso.com
UserSeven@contoso.com
UserEight@contoso.com
etc
 
Then you bring the list of rooms into memory, “ListOfRooms.txt”
PS C:\> $resources = get-content c:\Scripts\ListOfRooms.txt

Then to see what’s in the file, run:
PS C:\> $resources

ConfRoom1
ConfRoom2
ConfRoom3
ConfRoom4
ConfRoom5
ConfRoom6
ConfRoom7
ConfRoom8
etc

Now let’s take a look at what the calendar processsing is for one of the rooms:
    PS C:\>  Get-CalendarProcessing ConfRoom1

Identity                                                     AutomateProcessing
——–                                                     ——————
ConfRoom1                                                    AutoUpdate

To get more information about the calendar processing data for the room:
    PS C:\> Get-CalendarProcessing ConfRoom1 | fl

RunspaceId                          : <snipped>
AutomateProcessing                  : AutoUpdate
AllowConflicts                      : False
BookingWindowInDays                 : 180
MaximumDurationInMinutes            : 1440
AllowRecurringMeetings              : True
EnforceSchedulingHorizon            : True
ScheduleOnlyDuringWorkHours         : False
ConflictPercentageAllowed           : 0
MaximumConflictInstances            : 0
ForwardRequestsToDelegates          : True
DeleteAttachments                   : True
DeleteComments                      : True
RemovePrivateProperty               : True
DeleteSubject                       : True
AddOrganizerToSubject               : True
DeleteNonCalendarItems              : True
TentativePendingApproval            : True
EnableResponseDetails               : True
OrganizerInfo                       : True
ResourceDelegates                   : {}
RequestOutOfPolicy                  : {}
AllRequestOutOfPolicy               : False
BookInPolicy                        : {}
AllBookInPolicy                     : True
RequestInPolicy                     : {}
AllRequestInPolicy                  : False
AddAdditionalResponse               : False
AdditionalResponse                  :
RemoveOldMeetingMessages            : True
AddNewRequestsTentatively           : True
ProcessExternalMeetingMessages      : False
RemoveForwardedMeetingNotifications : False
MailboxOwnerId                      : ConfRoom1
Identity                            : ConfRoom1
IsValid                             : True
ObjectState                         : Changed

And now the moment you’ve been waiting for: Run the following command to set Calenar Processing settings for multiple users for multiple calendars:

PS C:\> $resources | foreach {Set-CalendarProcessing $_ -AutomateProcessing autoaccept -bookinpolicy $users}

Another example providing Editor rights to a list of calendars

This is for the IT-Rooms where we must give a list of users “Editor” permissions to a list mailbox Calendars.

List of users are in file:    c:\Scripts\ListOfUsers.txt
List of mailbox room calendars    c:\ListOfRooms.txt

=====
1. Pull the list of users into memory first:
$users= get-content c:\Scripts\ListOfUsers.txt

Run $users to see what’s in the file to be sure:
$users
or
$users | get-member

=====
2. Pull in the rooms or calendars into memory:
$resources = get-content c:\ListOfRooms.txt

If you want, run this to see what’s in that file:
$resources
or
$resources | get-member

If you want, run this to see what calendar processing is currently set on one of the rooms:
get-CalendarProcessing ConfRoom1 | fl

=====
3. Run it:

$resources | foreach {Add-MailboxFolderPermission -Identity $_:\calendar -User $Users -AccessRights Editor}

=====
Or just create a DL, and add the list of users to the DL, then run the following:

This gives the group ConfRoomSchedulers@contoso.com “Editor” access rights on the rooms listed in the file ListOfRooms.txt:

Get-Content ListOfRooms.txt | foreach {Add-MailboxFolderPermission -Identity $_ -User ConfRoomSchedulers@contoso.com -AccessRights Editor}

ListOfRooms.txt contains:
ConfRoom1@contoso.com:\calendar
ConfRoom2@contoso.com:\calendar
ConfRoom3@contoso.com:\calendar
ConfRoom4@contoso.com:\calendar
ConfRoom5@contoso.com:\calendar

Change the “Default” user on a list of calendars (rroms) or users to “None.”

Get-Content c:\Scripts\ListOfRooms.txt | foreach {Set-MailboxFolderPermission -Identity $_:\Calendar -User Default -AccessRights None}

Removing Permissions for a folder (calendar in this example)

Remove-MailboxFolderPermission -Identity <mailbox>:\Calendar –User <Mailbox-that-will-be-removed-from-Calendar-Permissions>
remove-MailboxfolderPermission ConferenceRoom1 -user “John Doe” -AccessRights editor
remove-MailboxfolderPermission ConferenceRoom1:\Calendar -user “JohnDoe”

Then confirm with:
get-MailboxFolderPermission -Identity ConferenceRoom1:\Calendar

Create a conference room. Do not allow anyone to book the room other than the people that have access rights to the room:

Set-Calendarprocessing VeryImportantConfRoom7thFloor@contoso.com -AddAdditionalResponse $true -AdditionalResponse “<p><strong><font color=red

size=4>Scheduling request denied.</strong><font></p><p><font color=blue size=4>Reason code: You are not authorized to schedule meetings or

appointments in the Very Important Conference Room 7th Floor. If you must book an entry in the room, please submit a request to either Mary Smith,

John Doe, or Robert Redford. Thank you.</p><p>Your Company’s IT Department.</font></p>”

More to come…

Comments are welcomed.

==================================================================

Summary

I hope this helps!

Published 9/13/2015

Ace Fekay
MVP, MCT, MCSE 2012, MCITP EA & MCTS Windows 2008/R2, Exchange 2013, 2010 EA & 2007, MCSE & MCSA 2003/2000, MCSA Messaging 2003
Microsoft Certified Trainer
Microsoft MVP – Directory Services

clip_image002622[2] clip_image004622[2] clip_image006622[2] clip_image008622[2] clip_image010622[2] clip_image012622[2]

Complete List of Technical Blogs: http://www.delawarecountycomputerconsulting.com/technicalblogs.php

This posting is provided AS-IS with no warranties or guarantees and confers no rights.

Office 365 PowerShell Fun with Mailbox Permissions

Published 9/11/2015

Prologue

Ace Fekay here again.

You might say to yourself this is some really simple stuff. Sure, it might be, for the pro. As many of you know, I’m an avid Active Directory and Exchange server engineer/architect, and an MVP in Active Directory.

Therefore with AD, Exchange, and Office 365, you will find that scripting comes into play more and more with your daily tasks.  The main reason I’m posting simple scripts is that to get the job done, I just needed an arsenal of simple quickie scripts when called upon a simple task, such as this one, dealing with mailbox permissions.

I hope this blog and my future scripts blogs, especially with Office 365, help you out.

Scope

These are a few examples of dealing with every day requests for mailbox delegation and permissions administration. Sure, you can do it from your web based, Office 365 tenant dashboard, but what fun is that?

And yes, this is simple stuff. The main reason I’m posting this, and I will be posting much more, including Office 365 scripts, is that I had to look it up and there is no one place to get all of this at the simple level. All I see are elaborate scripts that do more than what I needed. Hence, my posts.

Open PowerShell session and Login – Of course you first have to open a PowerShell session to your tenant account

Open a PowerShell window.
Run the following:
$MySession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell/ -Credential $AceCred -Authentication Basic -AllowRedirection

This will prompt you to login using your credentials.

Then run:
import-pssession $MySession

To be able to run Start-OnlineCoexistenceSync Dirsync – on a DC

After you make any changes in your local AD, instead of waiting for the dirsync schedule to run, you can manually run a dirsync on your onprem AD to force a sync:

Command Prompt
cd “C:\Program Files\Microsoft Online Directory Sync”
Run:
.\DirSyncConfigShell.psc1

Or just run:
“C:\Program Files\Microsoft Online Directory Sync\DirSyncConfigShell.psc1”
Then run:
Start-OnlineCoexistenceSync  or invoke-dirsync

To view the dirsync log, click on the DirSync icon in task bar that opens the Synchronization Service Manager. If it’s not on the task bar, it can be found in:

“C:\Program Files\Microsoft Online Directory Sync\SYNCBUS\Synchronization Service\UIShell\miisclient.exe”

===========================================================

To find who has been delegated to a mailbox

Get-Mailbox JohnDoe@contoso.com | fl displayname, GrantSendOnBehalfTo

To see the whole list of delegated users:

PS C:\Windows> Get-Mailbox JohnDoe@contosl.com | select -expandproperty GrantSendOnBehalfTo
Output:
user1
user2
user3
user4
user5
user6

Or you can run this, too:

PS C:\Windows> (Get-Mailbox JohnDoe@contoso.com|).grantsendonbehalfto
Output:
user1
user2
user3
user4
user5
user6

 

Remove Mike Smith as a delegate – example:

First find the permission:

This will give you a summary list:
get-mailboxpermission –identity Dept1-Shared-Mailbox | ft

This will give you a full list:
Get-MailboxPermission -identity Dept1-Shared-Mailbox | fl

Then remove it:

Remove-mailboxpermission -identity Dept1-Shared-Mailbox -user NAMPRD999\Mike.Smith8047888747747123 -AccessRights FullAccess -Inheritance All

Remove-mailboxpermission -identity Dept1-Shared-Mailbox -user NAMPRD999\Mike.Smith8047888747747123 -AccessRights SendAs -Inheritance All

To find who has FullAccess Permissions on a Mailbox

There are two ways the results can be displayed:

  • FT – Format Table – One big summarized list
  • FL – Format List – in sections with detail

using FT

get-mailboxpermission JohnDoe@contoso.com | ft

Output example:

Identity                   User                 AccessRights        IsInherited Deny
——–                    —-                      ————        ———– —-
JohnDoe               NT AUTHORITY\SELF    {FullAccess, Rea… False       False
JohnDoe               S-1-5-21-24478488… {FullAccess}        False       False
JohnDoe               NAMPRD05\jar02546… {FullAccess}        False       False
JohnDoe               NAMPRD05\FullAcce… {FullAccess}        False       False
JohnDoe               NAMPRD05\Administ… {FullAccess}        True        True
JohnDoe               NAMPRD05\Domain A… {FullAccess}        True        True
JohnDoe               NAMPRD05\Enterpri… {FullAccess}        True        True
JohnDoe               NAMPRD05\Organiza… {FullAccess}        True        True
JohnDoe               NT AUTHORITY\SYSTEM  {FullAccess}        True        False
JohnDoe               NT AUTHORITY\NETW… {ReadPermission}    True        False
JohnDoe               PRDMGT01\View-Onl… {ReadPermission}    True        False
JohnDoe               NAMPRD05\Administ… {FullAccess, Del… True        False
JohnDoe               NAMPRD05\Domain A… {FullAccess, Del… True        False
JohnDoe               NAMPRD05\Enterpri… {FullAccess, Del… True        False
JohnDoe               NAMPRD05\Organiza… {FullAccess, Del… True        False
JohnDoe               NAMPRD05\Public F… {ReadPermission}    True        False
JohnDoe               NAMPRD05\Exchange… {FullAccess, Rea… True        False
JohnDoe               NAMPRD05\Exchange… {FullAccess, Del… True        False
JohnDoe               NAMPRD05\Managed … {ReadPermission}    True        False

using FL

get-mailboxpermission JohnDoe@contoso.com | fl

Output Example:

RunspaceId      : aaa56ea5-574b-45dc-8489-d85a2013bc58
AccessRights    : {FullAccess, ReadPermission}
Deny            : False
InheritanceType : All
User            : NT AUTHORITY\SELF
Identity        : JohnDoe
IsInherited     : False
IsValid         : True
ObjectState     : Unchanged

RunspaceId      : aaa56ea5-574b-45dc-8489-d85a2013bc58
AccessRights    : {FullAccess}
Deny            : False
InheritanceType : All
User            : S-1-5-21-2447848828-1310731447-1641304557-6207581
Identity        : JohnDoe
IsInherited     : False
IsValid         : True
ObjectState     : Unchanged

RunspaceId      : aaa56ea5-574b-45dc-8489-d85a2013bc58
AccessRights    : {FullAccess}
Deny            : False
InheritanceType : All
User            : NAMPRD05\jar02546711232540629
Identity        : JohnDoe
IsInherited     : False
IsValid         : True
ObjectState     : Unchanged

RunspaceId      : aaa56ea5-574b-45dc-8489-d85a2013bc58
AccessRights    : {FullAccess}
Deny            : False
InheritanceType : All
User            : NAMPRD05\FullAccessAdmin
Identity        : JohnDoe
IsInherited     : False
IsValid         : True
ObjectState     : Unchanged

RunspaceId      : aaa56ea5-574b-45dc-8489-d85a2013bc58
AccessRights    : {FullAccess}
Deny            : True
InheritanceType : All
User            : NAMPRD05\Administrator
Identity        : JohnDoe
IsInherited     : True
IsValid         : True
ObjectState     : Unchanged

etc

Other tidbits:

===========================

To display FullAccess on a Mailbox

Get-MailboxPermission JohnDoe | Where { ($_.IsInherited -eq $False) -and -not ($_.User -like “NT AUTHORITY\SELF”) } | Select Identity,user,AccessRights | fl

===========================

This will display SendOnBehalf:

Get-RecipientPermission JohnDoe | Where { ($_.IsInherited -eq $False) -and -not ($_.Trustee -like “NT AUTHORITY\SELF”) } | Select Trustee,AccessControlType,AccessRights | fl

 

===========================

View SendAs:

Get-RecipientPermission JohnDoe | where {($_.Trustee -ne ‘nt authority\self’) -and ($_.Trustee -ne ‘Null sid’)} | select Identity,Trustee,AccessRights | fl

==========================

View all “Send As permissions” you’ve configured in your organization

Careful running this on a really large tenant or you will tie up the bandwidth and get throttled.

Get-RecipientPermission | where {($_.Trustee -ne ‘nt authority\self’) -and ($_.Trustee -ne ‘Null sid’)} | select Identity,Trustee,AccessRights

============================

Display a list of recipient’s that have FULL ACCESS permission on other recipient’s

Get-RecipientPermission JohnDoe | Where { ($_.IsInherited -eq $False) -and -not ($_.Trustee -like “NT AUTHORITY\SELF”) } | Select Trustee,AccessControlType,AccessRights | fl

============================

Display a list of recipient’s that have FULL ACCESS permission on other recipient’s

$a = Get-Mailbox $a |Get-MailboxPermission | Where { ($_.IsInherited -eq $False) -and -not ($_.User -like “NT AUTHORITY\SELF”) -and -not ($_.User -like ‘*Discovery Management*’) } | Select Identity, user, AccessRights | fl

=============================

Revoke “Send As” Permissions

Remove-RecipientPermission <Identity>  -AccessRights SendAs -Trustee <Identity>
Remove-RecipientPermission John   -AccessRights SendAs -Trustee Suzan

Adjustments & Improvements – To avoid the need for confirmation, we can add the option: “-Confirm:$False”
Remove-RecipientPermission John -AccessRights SendAs -Trustee Suzan -Confirm:$False

 

More to come…

 

 

Comments are welcomed.

==================================================================

Summary

I hope this helps!

Published 8/17/2015

Ace Fekay
MVP, MCT, MCSE 2012, MCITP EA & MCTS Windows 2008/R2, Exchange 2013, 2010 EA & 2007, MCSE & MCSA 2003/2000, MCSA Messaging 2003
Microsoft Certified Trainer
Microsoft MVP – Directory Services

clip_image002622 clip_image004622 clip_image006622 clip_image008622 clip_image010622 clip_image012622 clip_image014622

Complete List of Technical Blogs: http://www.delawarecountycomputerconsulting.com/technicalblogs.php

This posting is provided AS-IS with no warranties or guarantees and confers no rights.