de-DEen-GB
 
rss

Just can't get enough of IT

This blog is about mostly anything in IT. But the primary focuses are Microsoft Technologies like Exchange, Office 365, Azure and Cloud Security.

The PowerShell script to Set mailbox quotas at database or mailbox level the simple way has been updated to Version 1.4.

The code has been refactored to functions and has received some PowerShell hygiene patters.

Please report any issues directly at Github.

If you like the script, please rate the script at TechNet Gallery.

Enjoy!

 

 

Read More »
Last updated: 2017-03-18

Exchange Server 2013Exchange Server 2016Problem

You implement shared mailboxes as part of a legacy public folder migration. Access to the shared mailbox provided by dedicated security groups which, in this case, provide access to dedicated sub folders within the mailbox.

The migrated legacy public folder content contained items marked as private.

When you access a shared mailbox as a group member you are not able to see or access private items.

The following two screenshots are used to demontraste the issue:

The Inbox node shows three unread items:

Screenshot Inbox showing 3 unread items

The Inbox detail pane just shows a single read message:

Screenshot showing an Inbox with a single read message

So how to access items marked as private?

 

Solution

The privacy level (Sensitivity) of a mailbox item is controlled by MAPI extended property 0x36.

  • 0x36 = 0, sensitivity = normal
  • 0x36 = 2, sensitivity = private

When an item does have an extended property 0x36, the value is set to 0.

A mailbox is accessed using Exchange Web Services. The EWS endpoint is discovered using AutoDiscover for the selected mailbox.

The item modificatiuon is handled by the following code segment:

var extendedPropertyDefinition = new ExtendedPropertyDefinition(0x36, MapiPropertyType.Integer);
int extendedPropertyindex = 0;

foreach (var extendedProperty in Message.ExtendedProperties)
{
	if (extendedProperty.PropertyDefinition == extendedPropertyDefinition)
	{
		if (log.IsInfoEnabled)
		{
			log.Info(string.Format("Try to remove private flag from message: {0}", Message.Subject));
		}
		else
		{
			Console.WriteLine("Try to remove private flag from message: {0}", Message.Subject);
		}

		// Set the value of the extended property to 0 (which is Sensitivity normal, 2 would be private)
		Message.ExtendedProperties[extendedPropertyindex].Value = 0;

		// Update the item on the server with the new client-side value of the target extended property.
		Message.Update(ConflictResolutionMode.AlwaysOverwrite);
	}
	extendedPropertyindex++;
}

 

Usage

RemovePrivateFlags.exe -mailbox user@domain.com [-logonly] [-foldername "Inbox"] 

Search through the mailbox and ask for changing a item if -logonly is not set to true.
If -foldername is given the folder path are compared to the folder name.
If -logonly is set to true only a log will be created.

 

RemovePrivateFlags.exe -mailbox user@domain.com [-foldername "Inbox"] [-noconfirmation]

Search through the mailbox, if -noconfirmation is set to true all items will be altered without confirmation.

 

Note

It should be noted that this solution is intended for use in migration scenarios.

When providing access to mailbnox delegates you can enable access to your private elements as well. But access to shared mailboxes is not configured using the delegation workflow.

The code has been tested using Exchange Server 2013 CU15.

The program utilizes log4net to log detailed information to the file system. The configuration is controlled by the application's config file.

Updates

  • 2017-03-17: Release 1.1.0.0, Parameter changes
  • 2017-03-09: Release 1.0.0.0

Links

Any issues or feature requests? Use Github.

Like the code? Leave a note.

 

Read More »

Exchange Server 2013Exchange Server 2016Description

This script removes Active Directory objects for HealthMailboxes or SystemMailboxes in the Microsoft Exchange System Objects (MESO) container that do not have a homeMDB attribute set.

It is highly recommended to run the script with -WhatIf parameter to check objects first.

Information about accounts deleted or supposed to be deleted are written to a log file.

Requirements

Examples

# EXAMPLE 
# Perform a WhatIf run in preparation to removing SystemMailboxes having an empty database attribute
.\Remove-OrphanedMailboxAccounts.ps1 -SystemMailbox -WhatIf
    
# EXAMPLE 
# Remove HealthMailbox(es) having an empty database attribute
.\Remove-OrphanedMailboxAccounts.ps1 -HealthMailbox

Example log file

2017-02-10 10:18: 11488      - Info     - Script started
2017-02-10 10:18: 11488      - Info     - WhatIf Preference: True
2017-02-10 10:18: 11488      - Info     - Cleaning HealthMailboxes | 10 objects found
2017-02-10 10:18: 11488      - Info     - Cleaning HealthMailboxes | Delete CN=HealthMailboxd32b165a6adf45518c8498fba3c7c93a,CN=Monitoring Mailboxes,CN=Microsoft Exchange System Objects,DC=granikoslabs,DC=de
2017-02-10 10:18: 11488      - Info     - Cleaning HealthMailboxes | Delete CN=HealthMailbox6b66930902d8430e831df7b086bfd49b,CN=Monitoring Mailboxes,CN=Microsoft Exchange System Objects,DC=granikoslabs,DC=de
2017-02-10 10:18: 11488      - Info     - Cleaning HealthMailboxes | Delete CN=HealthMailbox6bf99bdc31474217a6fdc4cd83260e88,CN=Monitoring Mailboxes,CN=Microsoft Exchange System Objects,DC=granikoslabs,DC=de
2017-02-10 10:18: 11488      - Info     - Cleaning HealthMailboxes | Delete CN=HealthMailboxd4410bf131b34907b6a96a7e65263db1,CN=Monitoring Mailboxes,CN=Microsoft Exchange System Objects,DC=granikoslabs,DC=de
2017-02-10 10:18: 11488      - Info     - Cleaning HealthMailboxes | Delete CN=HealthMailbox98f334580dbf457ca2a6d1a19fdf49d1,CN=Monitoring Mailboxes,CN=Microsoft Exchange System Objects,DC=granikoslabs,DC=de
2017-02-10 10:18: 11488      - Info     - Cleaning HealthMailboxes | Delete CN=HealthMailboxc16704bf98c94f5e8453c7955d7897b5,CN=Monitoring Mailboxes,CN=Microsoft Exchange System Objects,DC=granikoslabs,DC=de
2017-02-10 10:18: 11488      - Info     - Cleaning HealthMailboxes | Delete CN=HealthMailboxa64fe085bdff46a786d68782c5070bf1,CN=Monitoring Mailboxes,CN=Microsoft Exchange System Objects,DC=granikoslabs,DC=de
2017-02-10 10:18: 11488      - Info     - Cleaning HealthMailboxes | Delete CN=HealthMailbox6c56f94506974a1183c6b71eebb63406,CN=Monitoring Mailboxes,CN=Microsoft Exchange System Objects,DC=granikoslabs,DC=de
2017-02-10 10:18: 11488      - Info     - Cleaning HealthMailboxes | Delete CN=HealthMailbox9b6666d46aa746e3848f3240e418d731,CN=Monitoring Mailboxes,CN=Microsoft Exchange System Objects,DC=granikoslabs,DC=de
2017-02-10 10:18: 11488      - Info     - Cleaning HealthMailboxes | Delete CN=HealthMailboxb2bd3d4725b249bab81eeed35666de0f,CN=Monitoring Mailboxes,CN=Microsoft Exchange System Objects,DC=granikoslabs,DC=de
2017-02-10 10:18: 11488      - Info     - Script finished

Version History

  • 1.0, Initial community release

Links

Follow

 

Read More »
On February 15, 2017
0 Comment
430 Views

Problem

When querying mailbox statistics in an Exchange organization using the following cmdlet (example) you might receive a warning that the object has been corrupted, and it's in an inconsistent state.

Get-Mailbox USER | Get-MailboxStatistics

WARNING: The object 3d16fdbb-5584-436b-b6c2-ee89adab9b9f has been corrupted, and it's in an inconsistent state. The following validation errors
happened:
WARNING: Cannot extract the property value of 'DeletedItemCount'. Source: PropTag(DeletedMsgCount), PropType(Int), RawValue(-11),
RawValueType(System.Int32). Target: Type(System.Nullable`1[System.UInt32]), IsMultiValued(False). Error Details: <n/a>

Solution

Check whether the affected mailbox is a regular user mailbox or if the mailbox is in a disconnected state. If the mailbox is disconnected you can either ignore the warning or remove the mailbox from the mailbox store.

If the mailbox is a regular user check the corresponding identity and move the mailbox to a different database.

Get-Mailbox -Identity 3d16fdbb-5584-436b-b6c2-ee89adab9b9f

Name                      Alias                ServerName       ProhibitSendQuota
----                      -----                ----------       -----------------
JohnDoe                   johndoe              MX01             1.8 GB (1,932,735,488 bytes)

Get-Mailbox johndoe | New-MoveRequest -TargetDatabase DB01

Enjoy.

 

 

Read More »
On February 8, 2017
0 Comment
455 Views

Problem

Recently a colleague of mine found an interesting issue with an Exchange Server 2013 organization setup.

The local service desk personnel wasn't able to select a target organizational unit (OU) when creating new mailboxes. The ECP dialogue just showed an empty window.

Reason

By default the ECP OU picker result set contains 500 entries only.

The OU picker does not query the Active Directory with -ResultSize Unlimited.

Solution

Microsot Knowledge Base article 3038717 provides the solution for this issue.

When querying the local Active Directory for the overall number of organization units using the following command, it turned out that the Active Directory contained more than 4.000 OUs.

(Get-OrganizationUnit -ResultSize Unlimited).Count

Use this cmdlet to determine the current number of organization units and define a reasonable number for querying Active Directory.

Add a new key node to the ECP web.config file on each of your Exchange 2013 servers.

<appSettings>
	<!-- Provisioning Cache identification -->
	<add key="ProvisioningCacheIdentification" value="Ecp" />
	<!-- ALL OTHER LINES HAVE BEEN REMOVED AS THIS IS FOR REFERENCE ONLY -->
	<add key="AccountTerminationEnabled" value="false" />
	<!-- Enable legacy logout page. To enable new signoff page delete the entry. (3) -->
	<add key="LogonSettings.SignOutKind" value="LegacyLogOff" />
	<!-- Allow the OU picker for New-Mailbox to retrieve 5000 organization units from AD, default = 500 -->
	<add key="GetListDefaultResultSize" value="5000" />
</appSettings>

The ECP web.config file is located in

  • $exinstall\ClientAccess\ecp

Saving a modified web.config normally triggers an application pool restart. If required, use the following one-liner to restart the ECP application pool across all Exchange 2013 servers.

Get-ExchangeServer | ? { $_.AdminDisplayVersion -like '*15.*'} | % { Invoke-Command -ComputerName $_.Name -ScriptBlock {Restart-WebAppPool MSExchangeECPAppPool } }

Note

It has not yet been verified, if the issue is present with Exchange Server 2016 as well. If so, just let us know.

Links

Keep enjoying the oddities of Exchange Server.

 

 

 

 

Read More »