“Mailbox size exceeds target quota 2.3 GB” when moving the mailbox between databases / servers.

When receiving such error please check you quota on mailboxdatabase:

[PS] D:\Exchange Server\V15\Bin>Get-MailboxDatabase | fl

RunspaceId : 5aa6941c-eadf-4c8e-b9fb-8163b7426622
JournalRecipient :
MailboxRetention : 30.00:00:00
OfflineAddressBook :
OriginalDatabase :
PublicFolderDatabase :
ProhibitSendReceiveQuota : <strong>2.3 GB</strong> (2,469,396,480 bytes)
ProhibitSendQuota : 2 GB (2,147,483,648 bytes)
RecoverableItemsQuota : 30 GB (32,212,254,720 bytes)
RecoverableItemsWarningQuota : 20 GB (21,474,836,480 bytes)

Set it up ou to your needs, in my case this database will be hosted only to export mailboxes to PST files:

 Get-MailboxDatabase WROMR0-DB001 | Set-MailboxDatabase -ProhibitSendReceiveQuota 120GB -ProhibitSendQuota 120GB 

Get pending windows updates status on ZABBIX using custom LLD (Low Level Discovery) and PowerShell

Just recently I got some time, and was rethinking the solution of reading windows updates.

At the beginning I thought I will use PowerShell to get update list and later use dependent items to parse the script output, but this wouldn’t be so nice, as I would need to manually work on parsing the file on the zabbix side, create items etc. + so far zabbix does not offer (I work on 3.4, at the time being 4.0 available) LLD on dependent items.

Well, why not use current LLD to read them?


You can do it – I will show you how.

Continue reading “Get pending windows updates status on ZABBIX using custom LLD (Low Level Discovery) and PowerShell”

Completely remove whole meetings’ SERIES using PowerShell and EWS.


Some time ago I’ve published here a way to remove meetings from calendars using EWS:


I got a bit upset that I needed to run the script from time to time to remove old stalled  cancelled meetings that were there before applying “AutoAccept” calendar processing. We got tons of them believe me, and I wanted to get rid of them completely! But how to remove the whole series and not just meetings for like two years, I wanted not to worry about the meetings even after 5 years, I just didn’t know how to remove the whole series as when people were mentioning about removing the series in the Internet articles, they were usually mentioning how to remove meetings for a long period of time and were calling it by removing a “series”.

Continue reading “Completely remove whole meetings’ SERIES using PowerShell and EWS.”

Does “New-ComplianceSearchAction -Purge” really purge the mailbox like it should?

New-ComplianceSearchAction -SearchName "GDPR Fuckups" -Purge

Are you sure you want to perform this action?
This operation will make message items meeting the criteria of the compliance search “Remove Vetting messages” completely inaccessible to users. There is no automatic method to undo the removal of these message items.
[Y] Yes [A] Yes to All [N] No [L] No to All [?] Help (default is “Y”): A


Continue reading “Does “New-ComplianceSearchAction -Purge” really purge the mailbox like it should?”

Harder, Better, Faster, Stronger…”-filter” vs. “where-object”


Some time ago I was measuring execution times of posh lines with -filter and where-object.

The difference is significant:

PS D:\AdminTools> measure-command {Get-remotemailbox -Filter {RecipientTypeDetails -eq "RemoteRoomMailbox" -and name -like "*people*"}}

Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 0
Milliseconds      : 756
Ticks             : 7564893
TotalDays         : 8,75566319444444E-06
TotalHours        : 0,000210135916666667
TotalMinutes      : 0,012608155
TotalSeconds      : 0,7564893
TotalMilliseconds : 756,4893

PS D:\AdminTools> measure-command {Get-remotemailbox | ? {$_.RecipientTypeDetails -eq "RemoteRoomMailbox" -and $_.name -like "*people*"}}

Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 18
Milliseconds      : 415
Ticks             : 184153984
TotalDays         : 0,000213141185185185
TotalHours        : 0,00511538844444444
TotalMinutes      : 0,306923306666667
TotalSeconds      : 18,4153984
TotalMilliseconds : 18415,3984

We can see here that commands with -filter can be significantly quicker – almost 3 times quicker.

Where does it come from you may ask? Well, the “-filter” tells the source to filter the results BEFORE sending back to the requester, whilst when using “where-object” tells the source to send ALL results to the requster and later the requester picks the right records.

New-ComplianceSearch not visible in Exchange Online despite being in “Discovery Management”

So just today I learned new thing, I was missing New-ComplianceSearch cmdlet, I was a bit frustrated because I was in all the relevant groups:

Technet was not mentioning a WORD about one thing, I was able to use compliance cmdlets only after I connected diffrently, so if this is your connection string:

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

Change it to:

$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.compliance.protection.outlook.com/powershell-liveid/ -Credential $Credential -Authentication Basic –AllowRedirection

This should do the trick.


Exchange Online and Microsoft.Exchange.Data.SharingPolicyAction is invalid error on Get-MailboxFolderPermission


Recently we got an issue on Exchagne Online, for one mailbox (yes 1! :)) we were not able to properly read permissions, the error was:

•	WARNING: An unexpected error has occurred and a Watson dump is being generated: Value specified for a parameter of type <span id="mce_SELREST_start" style="overflow:hidden;line-height:0;"></span>Microsoft.Exchange.Data.SharingPolicyAction is invalid<span id="mce_SELREST_end" style="overflow:hidden;line-height:0;"></span>: 0.
•	Parameter name: allowedActions
•	Value specified for a parameter of type Microsoft.Exchange.Data.SharingPolicyAction is invalid: 0.
•	Parameter name: allowedActions
•	    + CategoryInfo          : NotSpecified: (:) [Get-MailboxFolderPermission], EnumOutOfRangeException
•	    + FullyQualifiedErrorId : Microsoft.Exchange.ExchangeSystem.EnumOutOfRangeException,Microsoft.Exchange.Management.StoreTasks.GetMailboxFolderPermission
•	    + PSComputerName        : ps.outlook.com


After contacting Microsoft they suggested running following command:

Get-SharingPolicy | Set-SharingPolicy -Domains Anonymous:CalendarSharingFreeBusySimple,*:CalendarSharingFreeBusyDetail

After running the above command we were able to properly rad permissions. More details about sharing policies can be found here.


What if Optimize-StoragePool doesn’t work with the “-WhatIf” switch?

Just recently I was running optimization job on S2D pool, so lead by curiosity I wanted to start it with the “-whatif” witch, like this:

$UniqueId = (Get-StoragePool | Where {$_.IsPrimordial -eq $false}).UniqueId
Optimize-StoragePool -UniqueId $UniqueId -whatif

I have found it on this wonderful blog:

And guess what? It started to do the job…

So be aware about that once “testing” the Optimize-StoragePool cmdlet.

Exchange – two ways to create new role assignments.

Forgotten this recently and got caught spending some time investigating.

Boys and girls, remember one thing – if you create role assignments like this:

New-ManagementRoleAssignment -Name "ASSIGNMENT NAME" -Role "ApplicationImpersonation" -CustomRecipientWriteScope "IMPERSONATION USERS" -SecurityGroup "IMPERSONATION ADMINS"

where “IMPERSONATION ADMINS” is your a security group created by you – this role assignment will NOT be visible in your “admin roles” area in Exchange Console:


Instead, you need firstly create a Role Group and assign role to it, for instance


New-ManagementRoleAssignment -Name "ASSIGNMENT NAME" -Role "ApplicationImpersonation" -CustomRecipientWriteScope "IMPERSONATION USERS" -SecurityGroup "ROLE GROUP IMPERSONATION ADMINS"

Only assigning a role to a role group allows it to appear in the admin roles area.

Remember about that!



How to properly reboot machine with PowerShell.

Just today my wonderful colleague showed me a great way to restart machine and at the same time – test if it has came up and is operational (basically if PowerShell responds remotely).

Restart-Computer -ComputerName <COMPUTERNAME> -Wait -Protocol wsman -force

Use -force to forcely logoff any active sessions (savage!!!!)

After performing restart in above way, console waits and will not go further, unless PS on the remote machine responds!



Isn’t that cool!?