15 October 2019

How to set default retention policy for all existing and new users in Exchange Online - Set default retention policy for On-Premises users

In Exchange Online you can set a retention policy as the default for everyone within the tenant.
In Exchange On-Premises this isn't possible, therefore you have to set them every once in a while.

For Exchange Online:

To view all your retention policies:
Get-RetentionPolicy

The set the one you want as the default:
Set-RetentionPolicy "Company - Default Policy" -IsDefault:$true

For Exchange On-Premises:

To view all your retention policies:
Get-RetentionPolicy

To set the one you want as default for all existing users:
Get-Mailbox -Resultsize Unlimited | Set-Mailbox -RetentionPolicy "Company - Default Policy"

To check what the current retention policy is:
Get-Mailbox -ResultSize Unlimited | Select Retentionpolicy,Name

02 September 2019

Error: MigrationPermanentException: Cannot find a recipient that has mailbox GUID

Error: MigrationPermanentException: Cannot find a recipient that has mailbox GUID

After trying to move a mailbox from Exchange Online to Exchange On-premises the above error occurred.
This happend because the mailbox was created online and not on-premises, and therefore the GUID wasn't synced to AzureAD and vice versa.

Luckily there is a simple fix:

In Exchange Online PowerShell:
Get-Mailbox alias | FL ExchangeGUID

In the On-Premises Exchange PowerShell:
Set-RemoteMailbox Alias -ExchangeGUID 12345678-1234-1234-12345678
Then wait for replication to AzureAD and your mailbox move should go without a hitch.

02 July 2019

EdgeSync failed to decrypt the credential for Edge Transport - Eventid 1033 MSExchange EdgeSync - Renewed certificate lately?

EdgeSync failed to decrypt the credential for Edge Transport server sr-xxxx.domain.lan using the private key of the default Exchange certificate with exception Invalid provider type specified.
. The certificate's thumbprint is XXXXXXXXXXXXXXXXXXXX52F0283F5F8BDDD13058 and its subject is CN=autodiscover.domain.nl, OU=ICT, O=Company., L=City, S=State, C=NL.
Use either Enable-ExchangeCertificate or New-ExchangeCertificate to set the proper Exchange default certificate and re-subscribe the Edge Transport server sr-XXXX.domain.lan again.

Well...here we go again.
At least I'm not bored at work.

Quick recap, this was after renewing our old Exchange certificate that had the SMTP service assigned to it. The old certificate was an old SHA1 type, this is very important to keep in mind as it comes back later in the solution.

In my quest to solve this as quickly as possible I came across some other strange things, which I will list later on.
But first let me sum up all the steps needed to resolve this:

  1. On the Edge server request a new Exchange certificate:
    New-ExchangeCertificate
  2. Generate a new EdgeSubscription file:
    New-EdgeSubscription -FileName C:\Temp\Servername.xml
  3. Copy the EdgeSubscription file to an Exchange 2013 or 2016 or 2019 server (I'm assuming you installed multirole)
  4. Remove the current EdgeSubscription(s):
    Get-EdgeSubscription | select Name
    Remove-EdgeSubscription -Identity YourEdgesubscriptionName
  5. Find the current self signed Exchange Certificate with the servername as Subject. This certificate is created at installation. This certificate needs to get the SMTP service reassigned to it. Copy the thumbprint, we need it in the second command:
    Get-ExchangeCertificate | fl
    Enable-ExchangeCertificate -Thumbprint XXXXXXXXXXXXXXXXXX334EFEA37EFC7E5813 -DoNotRequireSsl -Services:SMTP
  6. Double check your existing subscription has been deleted:
    Get-EdgeSubscription
  7. Create a new Edge Subscription with the file copied in step 3:
    New-EdgeSubscription -FileData ([byte[]]$(Get-Content -Path "C:\Temp\Servername.xml" -Encoding Byte -ReadCount 0)) -Site YourSiteName
  8. Then start your newly created subscription:
    Start-EdgeSynchronization
  9. Test the EdgeSynchronization:
    Test-EdgeSynchronization
  10. The last step is to sync everything:
    Start-EdgeSynchronization -ForceUpdateCookie -ForceFullSync
The problem I had was the certificate that got renewed initialy was a SHA1 certificate.
The one it got replaced with was a SHA256 certificate. When trying to renew the Edge Subscription the following error popped up:
A special Rpc error occurs on server sr-xxxxx Invalid provider type specified
This the SHA1 part I mentioned earlier. The Edge Subscription only works with SHA1 certificates.
Strange and not very secure, eventho it is meant for internal Exchange server traffic only.
Hence the default certificate created at installation of Exchange itself is needed, which is SHA1.

Solved.



28 June 2019

Removing AccessRights - WARNING: An inherited access control entry has been specified and was ignored - WARNING: An inherited access control entry has been provided and was ignored

So this just happed:
Remove-MailboxPermission -Identity SharedMailboxAlias -User Username -AccessRights FullAccess -InheritanceType all
Confirm
Are you sure you want to perform this action?
Removing mailbox permission "SharedMailboxAlias" for user "UserName" with access rights "'FullAccess'".
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [?] Help (default is "Y"): y
WARNING: An inherited access control entry has been specified: [Rights: CreateChild, Delete, `
ReadControl, WriteDacl, WriteOwner, ControlType: Allow]  and was ignored on object `
"CN=SharedMailboxAlias,OU=Shared Mailboxes,OU=Mail,DC=Domain,DC=lan".
Checked to see what was keeping me from removing the access rights:
Get-MailboxPermission -Identity SharedMailboxAlias -User UserName

Identity             User                 AccessRights                 IsInherited Deny
========             ====                 ============                 =========== ====
Domain.lan/Mail/S... Domain\UserName      {FullAccess}                 True        True
Domain.lan/Mail/S... Domain\UserName      {FullAccess}, Delete...      True        False
And there it was, the "IsInherited" value True.
So its coming from above...

So I had to go through and remove some legacy permissions from Exchange. This can be added at multiple levels so it’s aways a diagnostic trail to where this was added. Go through each of these and if IsInherited is set to False you’ve found out where it’s being applied from.
Get-MailBoxPermission Domain\UserName

Get-MailboxDatabase | Get-ADPermission -User Domain\UserName

Get-ExchangeServer | Get-ADPermission -User Domain\UserName

Get-OrganizationConfig | Get-ADPermission -User Domain\UserName
Remove the Permissions per level with
Get-MailBoxPermission Domain\UserName | Remove-ADPermission

Get-MailboxDatabase | Get-ADPermission -User Domain\UserName | Remove-ADPermission

Get-ExchangeServer | Get-ADPermission -User Domain\UserName | Remove-ADPermission

Get-OrganizationConfig | Get-ADPermission -User Domain\UserName | Remove-ADPermission
Some of the permissions where also added from AD.

Open up ADSI Edit and Navigate to these :

In “Default Naming Context” OU=Microsoft Exchange Security Groups,DC=Domain,DC=lan
In “Default Naming Context” CN=Microsoft Exchange System Objects
In “Configuration” CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=Domain,DC=lan

Make sure the user is not in any of these.
After the User has been removed from any of these places its inheritance is gone is no longer listed.

18 June 2019

Disable/remove PowerShell V2.0 and why you should

Microsoft is planning to deprecate PowerShell V2.0 in the upcoming fall creator update.
The reason why you should remove or disable it is basically, it's old.
And old in computercountry doesn't work well when it comes to security.
Another reason to remove it is because PowerShell V2.0 can be used for lateral movement and persistence techniques with the same functionality. PowerShell V2.0’s extra value is that because it does not have native logging capabilities, it remains undetected and offers stealth in attacker operations.

PowerShell V2.0 was first seen on Windows XP and Server 2003 then on Vista and 7, Server 2008. When Windows PowerShell 3.0 was released as part of Windows 8, Server 2008 R2, and WMF 3.0, Windows PowerShell moved to a newer version of the .NET Framework (CLR4) that was not compatible older applications. In order to maintain backwards compatibility with these older applications, Microsoft kept Windows PowerShell 2.0 as an optional, side-by-side component in later versions of Windows and Windows Server.

As PowerShell Core 6.0 (and PowerShell 7 is in development) enters the marketplace, Microsoft will reduce the complexity of the PowerShell ecosystem. Removing an outdated version of .NET from the equation makes development easier for cmdlet and script authors by focusing on the .NET Standard ecosystem that includes only .NET Framework 4.6+ and .NET Core 2.0.

You can check whether Windows PowerShell 2.0 is installed by running the following (as an administrator).

On Windows 7/8.1/10, the following will return a State as either Enabled or Disabled:
Get-WindowsOptionalFeature -Online -FeatureName MicrosoftWindowsPowerShellV2

On Windows Server, the following will return an InstallState of either Installed or Removed:
Get-WindowsFeature PowerShell-V2

To disable PowerShell V2.0 run PowerShell with elevated privileges (run as administrator).

Enter the following:

Disable-WindowsOptionalFeature -Online -FeatureName MicrosoftWindowsPowerShellV2Root

This command should disable both "MicrosoftWindowsPowerShellV2Root" and "MicrosoftWindowsPowerShellV2" which correspond to "Windows PowerShell 2.0" and "Windows PowerShell 2.0 Engine" respectively in "Turn Windows features on or off".

PowerShell v.2 can be used for lateral movement and persistence techniques with the same functionality. PowerShell v.2’s extra value is that because it does not have native logging capabilities, it remains undetected and offers stealth in attacker operations.

14 June 2019

Prevent account discovery - AzureAD read access and how to block it

This is some serious stuff from Mauricio Velazco.

Account discovery is the technique that allows an adversary to enumerate domain accounts in order to obtain situational awareness on a target network.














This can easily be prevented:

(Assuming you installed the MSOnline module)
Connect-MsolService
Then Sign in with an account in Azure Active Directory that has the Global administrator role assigned.
Perform multi-factor authentication, when prompted.
Execute the following line of PowerShell to configure the Azure AD tenant:
Set-MsolCompanySettings -UsersPermissionToReadOtherUsersEnabled $false
Check to see the setting is active:
Get-MsolCompanyInformation | select UsersPermissionToReadOtherUsersEnabled            
            
UsersPermissionToReadOtherUsersEnabled            
            
                                 False

28 May 2019

Create a PowerShellISE and PowerShell profile

Load all your favorite modules at startup, set locations, clear screens, start transcripts in a smart way.

First create your profile if none exists.
Open the PowerShellISE and in the console window run:
if (!(test-path $profile)) {new-item -type file -path $profile -force}
This will create the profile file used by the PowerShellISE only.

If you run this from the regular PowerShell window a profile file will also be created but it will be used by the regular PowerShell only.

The PowerShellISE profile file is always located at:
%UserProfile%\Documents\WindowsPowerShell\Microsoft.PowerShellISE_profile.ps1

The PowerShell profile file is always located at:

%UserProfile%\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1
Notice this profile file has a different name

Then open this file and add the following:
Add-PSsnapin *Exchange* -ErrorAction SilentlyContinue
Import-Module IsePackV2 -Force
Set-Location C:\
[system.net.webrequest]::defaultwebproxy = new-object system.net.webproxy('http://proxy.domain.lan:8080')
[system.net.webrequest]::defaultwebproxy.credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials
[system.net.webrequest]::defaultwebproxy.BypassProxyOnLocal = $true
Start-Transcript -Path "\\domain.lan\someshare$\userhome\Transscripts\$env:computername.txt"

Add PSGallery, NuGet and Chocolatey to PowerShelISE on Windows Server 2012R2

By default the "Install-Module" command-let isn't available on Windows Server 2012 (R2).

But there's a way:
Update:
Since the PackageManagement PowerShell Modules Preview is nolonger available for download, you need to install the WMF5.1 or PowerShell 5.1:
https://www.microsoft.com/en-us/download/details.aspx?id=54616
Be sure to check the compatibility matrix to see if your application supports WMF5.1.
https://docs.microsoft.com/en-us/powershell/scripting/wmf/whats-new/compatibility?view=powershell-6

First install the "PackageManagement PowerShell Modules Preview - March 2016" from here;
https://www.microsoft.com/en-us/download/details.aspx?id=51451

Once installed run the following:

PS C:\windows\system32> Get-PackageProvider -Name Chocolatey

The provider 'chocolatey v2.8.5.130' is not installed.
chocolatey may be manually downloaded from https://onegetcdn.azureedge.net/providers/ChocolateyPrototype-2.8.5.130.exe
and installed.
Would you like PackageManagement to automatically download and install 'chocolatey' now?
[Y] Yes  [N] No  [S] Suspend  [?] Help (default is "Y"): y
            
Name                     Version          DynamicOptions
----                     -------          --------------
Chocolatey               2.8.5.130        SkipDependencies, ContinueOnFailure, ExcludeVersion, ForceX86, PackageSave...

Get-PackageProvider

Name                     Version          DynamicOptions            
----                     -------          --------------            
Chocolatey               2.8.5.130        SkipDependencies, ContinueOnFailure, ExcludeVersion, ForceX86, PackageSave...
msi                      3.0.0.0          AdditionalArguments            
msu                      3.0.0.0            
PowerShellGet            1.0.0.1          PackageManagementProvider, Type, Scope, InstallUpdate, NoPathUpdate, Packa...
Programs                 3.0.0.0          IncludeWindowsInstaller, IncludeSystemComponent            

Find-Package -Name Firefox

Name                           Version          Source                         Summary            
----                           -------          ------                         -------            
Firefox                        67.0             chocolatey                     Bringing together all kinds of awesom...

Get-PackageProvider -Name NuGet

The provider 'nuget v2.8.5.208' is not installed.
nuget may be manually downloaded from
https://onegetcdn.azureedge.net/providers/Microsoft.PackageManagement.NuGetProvider-2.8.5.208.dll and installed.
Would you like PackageManagement to automatically download and install 'nuget' now?
[Y] Yes  [N] No  [S] Suspend  [?] Help (default is "Y"): y

Name                     Version          DynamicOptions
----                     -------          --------------
NuGet                    2.8.5.208        Destination, ExcludeVersion, Scope, SkipDependencies, Headers, FilterOnTag...

Get-PackageProvider

Name                     Version          DynamicOptions
----                     -------          --------------
Chocolatey               2.8.5.130        SkipDependencies, ContinueOnFailure, ExcludeVersion, ForceX86, PackageSave...
msi                      3.0.0.0          AdditionalArguments
msu                      3.0.0.0            
NuGet                    2.8.5.208        Destination, ExcludeVersion, Scope, SkipDependencies, Headers, FilterOnTag...
PowerShellGet            1.0.0.1          PackageManagementProvider, Type, Scope, InstallUpdate, NoPathUpdate, Packa...
Programs                 3.0.0.0          IncludeWindowsInstaller, IncludeSystemComponent

Get-PSRepository
WARNING: Unable to find module repositories.

[system.net.webrequest]::defaultwebproxy = new-object system.net.webproxy('http://proxy.domain.lan:8080')
[system.net.webrequest]::defaultwebproxy.credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials
[system.net.webrequest]::defaultwebproxy.BypassProxyOnLocal = $true            

Register-PSRepository -Name PSGallery -SourceLocation https://www.powershellgallery.com/api/v2/-PublishLocation `
https://www.powershellgallery.com/api/v2/package/ -ScriptSourceLocation https://www.powershellgallery.com/api/v2/items/psscript/ `
-ScriptPublishLocation https://www.powershellgallery.com/api/v2/package/ -InstallationPolicy Trusted -PackageManagementProvider NuGet

Get-PSRepository

Name                      PackageManagementProvider InstallationPolicy   SourceLocation            
----                      ------------------------- ------------------   --------------            
PSGallery                 NuGet                     Trusted              https://www.powershellgallery.com/api/v2/

Install-Module IsePackV2 -Force
Install-Module ShowUI -Force
Install-Module RoughDraft -Force
Install-Module Pipeworks -Force
Install-Module EZOut -Force
Install-Module ScriptCop -Force
cd "C:\Program Files\WindowsPowerShell\Modules"
Import-Module ezout -Force
Import-Module isepackv2 -Force

Now you can install any module or package you want :-)

07 May 2019

PowerShell keyboard shortcuts - PowerShell ISE keyboard shortcuts

A list of all keyboard shortcuts for PowerShell ISE is in the table below.

But there is one I want to mention that I personally find awesome:
The officialname is "IntellisenseShortcut"

Get an overview of all options for a comandlet:
Get services -
Press CTRL and Spacebar and boom:



Name
Keyboard Shortcut
EditorUndoShortcut2
Alt+Backspace
EditorSelectNextSiblingShortcut
Alt+Down
ExitShortcut
Alt+F4
EditorSelectEnclosingShortcut
Alt+Left
EditorSelectFirstChildShortcut
Alt+Right
EditorRedoShortcut2
Alt+Shift+Backspace
EditorBoxSelectLineDownShortcut
Alt+Shift+Down
ToggleHorizontalAddOnPaneShortcut
Alt+Shift+H
EditorBoxSelectToPreviousCharacterShortcut     
Alt+Shift+Left
EditorBoxSelectToNextCharacterShortcut
Alt+Shift+Right
EditorTransposeLineShortcut
Alt+Shift+T
EditorBoxSelectLineUpShortcut
Alt+Shift+Up
ToggleVerticalAddOnPaneShortcut
Alt+Shift+V
EditorSelectPreviousSiblingShortcut
Alt+Up
ShowScriptPaneTopShortcut
Ctrl+1
ShowScriptPaneRightShortcut
Ctrl+2
ShowScriptPaneMaximizedShortcut
Ctrl+3
EditorSelectAllShortcut
Ctrl+A
ZoomIn1Shortcut
Ctrl+Add
EditorMoveCurrentLineToBottomShortcut
Ctrl+Alt+End
EditorMoveCurrentLineToTopShortcut
Ctrl+Alt+Home
BreakAllDebuggerShortcut
Ctrl+B
EditorDeleteWordToLeftShortcut
Ctrl+Backspace
StopExecutionShortcut
Ctrl+Break
StopAndCopyShortcut
Ctrl+C
GoToConsoleShortcut
Ctrl+D
EditorDeleteWordToRightShortcut
Ctrl+Del
EditorScrollDownAndMoveCaretIfNecessaryShortcut
Ctrl+Down
EditorMoveToEndOfDocumentShortcut
Ctrl+End
FindShortcut
Ctrl+F
ShowCommandShortcut
Ctrl+F1
CloseScriptShortcut
Ctrl+F4
GoToLineShortcut
Ctrl+G
ReplaceShortcut
Ctrl+H
EditorMoveToStartOfDocumentShortcut
Ctrl+Home
GoToEditorShortcut
Ctrl+I
Copy2Shortcut
Ctrl+Ins
ShowSnippetShortcut
Ctrl+J
EditorMoveToPreviousWordShortcut
Ctrl+Left
ToggleOutliningExpansionShortcut
Ctrl+M
ZoomOut3Shortcut
Ctrl+Minus
NewScriptShortcut
Ctrl+N
OpenScriptShortcut
Ctrl+O
GoToMatchShortcut
Ctrl+Oem6
ZoomIn3Shortcut
Ctrl+Plus
ToggleScriptPaneShortcut
Ctrl+R
EditorMoveToNextWordShortcut
Ctrl+Right
SaveScriptShortcut
Ctrl+S
ZoomIn2Shortcut
Ctrl+Shift+Add
GetCallStackShortcut
Ctrl+Shift+D
EditorSelectToEndOfDocumentShortcut
Ctrl+Shift+End
RemoveAllBreakpointsShortcut
Ctrl+Shift+F9
HideHorizontalAddOnToolShortcut
Ctrl+Shift+H
EditorSelectToStartOfDocumentShortcut
Ctrl+Shift+Home
ListBreakpointsShortcut
Ctrl+Shift+L
EditorSelectToPreviousWordShortcut
Ctrl+Shift+Left
ZoomOut4Shortcut
Ctrl+Shift+Minus
StartPowerShellShortcut
Ctrl+Shift+P
ZoomIn4Shortcut
Ctrl+Shift+Plus
NewRemotePowerShellTabShortcut
Ctrl+Shift+R
EditorSelectToNextWordShortcut
Ctrl+Shift+Right
ZoomOut2Shortcut
Ctrl+Shift+Subtract
EditorMakeUppercaseShortcut
Ctrl+Shift+U
HideVerticalAddOnToolShortcut
Ctrl+Shift+V
IntellisenseShortcut
Ctrl+Space
ZoomOut1Shortcut
Ctrl+Subtract
NewRunspaceShortcut
Ctrl+T
EditorMakeLowercaseShortcut
Ctrl+U
EditorScrollUpAndMoveCaretIfNecessaryShortcut  
Ctrl+Up
Paste1Shortcut
Ctrl+V
CloseRunspaceShortcut
Ctrl+W
Cut1Shortcut
Ctrl+X
EditorRedoShortcut1
Ctrl+Y
EditorUndoShortcut1
Ctrl+Z
F1KeyboardDisplayName
F1
HelpShortcut
F1
StepOverShortcut
F10
F10KeyboardDisplayName 
F10
StepIntoShortcut
F11
F11KeyboardDisplayName 
F11
F12KeyboardDisplayName 
F12
F2KeyboardDisplayName
F2
F3KeyboardDisplayName
F3
FindNextShortcut
F3
F4KeyboardDisplayName
F4
F5KeyboardDisplayName
F5
RunScriptShortcut
F5
F6KeyboardDisplayName
F6
F7KeyboardDisplayName
F7
F8KeyboardDisplayName
F8
RunSelectionShortcut
F8
F9KeyboardDisplayName
F9
ToggleBreakpointShortcut
F9
EditorDeleteCharacterToLeftShortcut
Shift+Backspace
Cut2Shortcut
Shift+Del
EditorSelectLineDownShortcut
Shift+Down
EditorSelectToEndOfLineShortcut
Shift+End
EditorInsertNewLineShortcut
Shift+Enter
StepOutShortcut
Shift+F11
FindPreviousShortcut
Shift+F3
StopDebuggerShortcut
Shift+F5
EditorSelectToStartOfLineShortcut
Shift+Home
Paste2Shortcut
Shift+Ins
EditorSelectToPreviousCharacterShortcut        
Shift+Left
EditorSelectPageDownShortcut
Shift+PgDn
EditorSelectPageUpShortcut
Shift+PgUp
EditorSelectToNextCharacterShortcut
Shift+Right
EditorSelectLineUpShortcut
Shift+Up