19 April 2019

Enable Basic Authentication for one user - Exchange Online

Disable basic authentication, password spray attack, enable MFA, enable modern authentication now!!
These are the topics most blogs post about, Tweeters tweet about and Microsoft warns about.
Talk about a panic attack. Of course this is very important stuff and you should disable basic auth, enable modern auth with MFA, and implement password protection.

But what if you have an application made in 1990 that requires basic auth to access your Exchange Online environment?

You can bypass the modern auth requirement with a policy that allows you to turn on basic auth for one specific user. 😎

All this is done in Exchange Online PowerShell;
Create a policy:
New-AuthenticationPolicy -Name "Allow Basic Auth for some ancient application"
Specify what services are allowed to use basic auth:
Set-AuthenticationPolicy -Identity "Allow Basic Auth for some ancient application" -AllowBasicAuthWebServices:$true             
Set-AuthenticationPolicy -Identity "Allow Basic Auth for some ancient application" -AllowBasicAuthOutlookService:$true             
Set-AuthenticationPolicy -Identity "Allow Basic Auth for some ancient application" -AllowBasicAuthReportingWebServices:$true             
Set-AuthenticationPolicy -Identity "Allow Basic Auth for some ancient application" -AllowBasicAuthActiveSync:$true             
Set-AuthenticationPolicy -Identity "Allow Basic Auth for some ancient application" -AllowBasicAuthRest:$true             
Set-AuthenticationPolicy -Identity "Allow Basic Auth for some ancient application" -AllowBasicAuthPowershell:$true             
Set-AuthenticationPolicy -Identity "Allow Basic Auth for some ancient application" -AllowBasicAuthMapi:$true             
Set-AuthenticationPolicy -Identity "Allow Basic Auth for some ancient application" -AllowBasicAuthOfflineAddressBook:$true             
Set-AuthenticationPolicy -Identity "Allow Basic Auth for some ancient application" -AllowBasicAuthAutodiscover:$true             
Set-AuthenticationPolicy -Identity "Allow Basic Auth for some ancient application" -AllowBasicAuthRpc:$true
Check the policy settings:
Get-AuthenticationPolicy -Identity "Allow Basic Auth for some ancient application" | fl AllowBasicAuth*
AllowBasicAuthActiveSync           : True            
AllowBasicAuthAutodiscover         : True            
AllowBasicAuthImap                 : False            
AllowBasicAuthMapi                 : True            
AllowBasicAuthOfflineAddressBook   : True            
AllowBasicAuthOutlookService       : True            
AllowBasicAuthPop                  : False            
AllowBasicAuthReportingWebServices : True            
AllowBasicAuthRest                 : False            
AllowBasicAuthRpc                  : True            
AllowBasicAuthSmtp                 : False            
AllowBasicAuthWebServices          : True            
AllowBasicAuthPowershell           : True
As you can see in the example above we do not allow SMTP, POP and IMAP to use basic auth, but ofcourse you could by adding:
Set-AuthenticationPolicy -Identity "Allow Basic Auth for some ancient application" -AllowBasicAuthSmtp:$true            
Set-AuthenticationPolicy -Identity "Allow Basic Auth for some ancient application" -AllowBasicAuthImap:$true            
Set-AuthenticationPolicy -Identity "Allow Basic Auth for some ancient application" -AllowBasicAuthPop:$true
Then grant a specific user the created policy:
Set-User -Identity LegacyUser -AuthenticationPolicy "Allow Basic Auth for some ancient application"
And check if all went well:
Get-User -Identity LegacyUser | fl auth*            
AuthenticationPolicy : Allow Basic Auth for some ancient application
Name                 : LegacyUser
And there you have it, now that one user is able to use basic auth.
Document this properly as this does pose a security threat, and these little exceptions tend to be forgotten over time.

02 April 2019

The PowerShellGallery - Find - Install - Deploy - Updating

Discovering packages from the PowerShell Gallery

Find packages in the PowerShell Gallery by using the Search control on the PowerShell Gallery's home page.
By browsing through the Modules and Scripts from the Packages page.
Running the Find-Module, Find-DscResource, and Find-Script cmdlets, depending on the package type, with -Repository PSGallery.

Installing packages from the PowerShell Gallery

To download a package from the Gallery for inspection, run either the Save-Module or Save-Script cmdlet.
Install a package from the Gallery for use, run either the Install-Module or Install-Script cmdlet.

Updating packages from the PowerShell Gallery

To update packages installed from the PowerShell Gallery, run either the Update-Module or Update-Script cmdlet.
When run without any additional parameters, [Update-Module][] attempts to update all modules installed by running Install-Module.
To selectively update modules, add the -Name parameter.

List packages that you have installed from the PowerShell Gallery

To find out which modules you have installed from the PowerShell Gallery, run the Get-InstalledModule cmdlet.
To find out which scripts you have installed from the PowerShell Gallery, run the Get-InstalledScript cmdlet.

Some examples:
Search through all scripts in the GridView window and install the selected script in the currentuser environment variable ($env:USERPROFILE\Documents\WindowsPowerShell\Modules):
Find-Script | Out-Gridview -Title "Select Script to install" -PassThru | Install-Script -Force -Scope CurrentUser

Search through all modules in the GridView window and install the selected module in the currentuser environment variable:
Find-Module | Out-Gridview -Title "Select Modules to install" -PassThru | Install-Module -Force -Scope CurrentUser

Update all installed modules without interaction:
Update-Module -Force

Update all installed script without interaction:
Update-Script -Force

15 March 2019

Install RSAT for Windows Server 2019 and Windows 10 with PowerShell

Windows Server 2019

Run the cmdlet below with the -whatif switch to check what will is allready installed and will be installed:
Install-WindowsFeature -IncludeAllSubFeature RSAT -WhatIf
Get-WindowsFeature -Name RSAT* | where 'install state' -NE Installed
To install all the tools run the cmdlet below:
Install-WindowsFeature -IncludeAllSubFeature RSAT
Install-WindowsFeature -Name RSAT -IncludeAllSubFeature -IncludeManagementTools


Check whether RSAT components are installed on your computer:
Get-WindowsCapability -Name RSAT* -Online
View the status of installed RSAT components in a easy view:
Get-WindowsCapability -Name RSAT* -Online | Select-Object -Property DisplayName, State
You can use the Add-WindowsCapacity cmdlet to install these Windows features.
To install a specific RSAT tool, such as AD management tools (including the ADUC console), run the command:
Add-WindowsCapability –online –Name “Rsat.ActiveDirectory.DS-LDS.Tools~~~~”
To install the DNS management console only, run:
Add-WindowsCapability –online –Name “Rsat.Dns.Tools~~~~”
And all the other single install options:
Add-WindowsCapability -Online -Name Rsat.FileServices.Tools~~~~
Add-WindowsCapability -Online -Name Rsat.GroupPolicy.Management.Tools~~~~
Add-WindowsCapability -Online -Name Rsat.IPAM.Client.Tools~~~~
Add-WindowsCapability -Online -Name Rsat.LLDP.Tools~~~~
Add-WindowsCapability -Online -Name Rsat.NetworkController.Tools~~~~
Add-WindowsCapability -Online -Name Rsat.NetworkLoadBalancing.Tools~~~~
Add-WindowsCapability -Online -Name Rsat.BitLocker.Recovery.Tools~~~~
Add-WindowsCapability -Online -Name Rsat.CertificateServices.Tools~~~~
Add-WindowsCapability -Online -Name Rsat.DHCP.Tools~~~~
Add-WindowsCapability -Online -Name Rsat.FailoverCluster.Management.Tools~~~~
Add-WindowsCapability -Online -Name Rsat.RemoteAccess.Management.Tools~~~~
Add-WindowsCapability -Online -Name Rsat.RemoteDesktop.Services.Tools~~~~
Add-WindowsCapability -Online -Name Rsat.ServerManager.Tools~~~~
Add-WindowsCapability -Online -Name Rsat.Shielded.VM.Tools~~~~
Add-WindowsCapability -Online -Name Rsat.StorageMigrationService.Management.Tools~~~~
Add-WindowsCapability -Online -Name Rsat.StorageReplica.Tools~~~~
Add-WindowsCapability -Online -Name Rsat.SystemInsights.Management.Tools~~~~
Add-WindowsCapability -Online -Name Rsat.VolumeActivation.Tools~~~~
Add-WindowsCapability -Online -Name Rsat.WSUS.Tools~~~~
To install all the available RSAT tools at once, run:
Get-WindowsCapability -Name RSAT* -Online | Add-WindowsCapability –Online
To install only disabled RSAT components, run:
Get-WindowsCapability -Online |? {$_.Name -like "*RSAT*" -and $_.State -eq "NotPresent"} | Add-WindowsCapability -Online
If installing RSAT you encounter an error Add-WindowsCapability failed.
Error code = 0x800f0954, most likely your computer is configured to receive updates from the internal WSUS or SUP server.

To install RSAT components, you need to temporarily disable the update from the WSUS server in the registry.
Open the registry key HKLM\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU and change the UseWUServer to 0 and restart the Update Service.

Or run this script:
$currentWU = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" -Name "UseWUServer" | select -ExpandProperty UseWUServer
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" -Name "UseWUServer" -Value 0            
Restart-Service wuauserv            
Get-WindowsCapability -Name RSAT* -Online | Add-WindowsCapability –Online            
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" -Name "UseWUServer" -Value $currentWU
Restart-Service wuauserv

error code: dlg_flags_sec_cert_cn_invalid - The hostname in the website's certificate differs from the website you are trying to visit

This was one error that I couldn't find a definitive answer for after searching the error:

error code: dlg_flags_sec_cert_cn_invalid - The hostname in the website's certificate differs from the website you are trying to visit

Long story short, in my case this came down to the "Common name" or "CN" in the certificate.
I had created the cert with a CN and some SAN names like so:



Internet Explorer 11, Edge, Chrome and Firefox all tripped over the Common name.
If I typed in the browser: "https://application" the error did not appear. So my conclusion is that the webserver doesn't interpret the domain suffix stated in the common name.

So I recreated the certificate with the Common name: "application".
Binded it in IIS, iisrestart and reloaded the site in IE and behold no more errors.

04 March 2019

Install Office365 requirements with PowerShell - SkypeOnline - ExchangeOnline - AzureAD - SharepointOnline - Teams PowerShell modules

Updated - 04-03-2019

  • Added Teams PowerShell module
  • Added AZ PowerShell module
  • Added InTune PowerShell module

I came across a script by Chris Goosen to connect to all of the Office 365 services via PowerShell.
When I tried to run it errors were flying everywhere.
All of the requirements were missing on my system.

So that's what I came up with, a one stop way to get all of those requirements in one single go.
Install Office365 PowerShell Prerequisites
Downloads and installs the AzureAD, Sharepoint Online, Skype Online for Windows PowerShell

.Made by 
Edwin van brenk


Function InstallSharepointOnlinePowerShellModule() {

$SharepointOnlinePowerShellModuleSourceURL = "https://download.microsoft.com/download/0/2/E/02E7E5BA-2190-44A8-B407-BC73CA0D6B87/SharePointOnlineManagementShell_8525-1200_x64_en-us.msi"

$DestinationFolder = "C:\Temp"

     If (!(Test-Path $DestinationFolder))
         New-Item $DestinationFolder -ItemType Directory -Force
Write-Host "Downloading Sharepoint Online PowerShell Module from $SharepointOnlinePowerShellModuleSourceURL"

         Invoke-WebRequest -Uri $SharepointOnlinePowerShellModuleSourceURL -OutFile "$DestinationFolder\SharePointOnlineManagementShell_7414-1200_x64_en-us.msi" -ErrorAction STOP

$msifile = "$DestinationFolder\SharePointOnlineManagementShell_7414-1200_x64_en-us.msi"
$arguments = @(

Write-Host "Attempting to install $msifile"

         $process = Start-Process -FilePath msiexec.exe -Wait -PassThru -ArgumentList $arguments
         if ($process.ExitCode -eq 0)
             Write-Host "$msiFile has been successfully installed"
             Write-Host "installer exit code  $($process.ExitCode) for file  $($msifile)"

         Write-Host $_.Exception.Message


# Download and Install Visual Studio C++ 2017            
$VisualStudio2017x64URL = "https://download.visualstudio.microsoft.com/download/pr/11687625/2cd2dba5748dc95950a5c42c2d2d78e4/VC_redist.x64.exe"            
Write-Host "Downloading VisualStudio 2017 C++ from $VisualStudio2017x64"             
$DestinationFolder = "C:\Temp"            
Invoke-WebRequest -Uri $VisualStudio2017x64URL -OutFile "$DestinationFolder\VC_redist.x64.exe" -ErrorAction STOP            
Write-Host "Attempting to install VisualStudio 2017 C++, a reboot is required!"            
Start-Process "$DestinationFolder\VC_redist.x64.exe" -ArgumentList "/passive /norestart" -Wait            
Write-Host "Attempting to install VisualStudio 2017 C++"             
# Download and Install Skype Online PowerShell module            
$SkypeOnlinePowerShellModuleSourceURL = "https://download.microsoft.com/download/2/0/5/2050B39B-4DA5-48E0-B768-583533B42C3B/SkypeOnlinePowerShell.Exe"
$DestinationFolder = "C:\Temp"
     If (!(Test-Path $DestinationFolder))
         New-Item $DestinationFolder -ItemType Directory -Force

Write-Host "Downloading Skype Online PowerShell Module from $SkypeOnlinePowerShellModuleSourceURL"
Invoke-WebRequest -Uri $SkypeOnlinePowerShellModuleSourceURL -OutFile "$DestinationFolder\SkypeOnlinePowerShell.Exe" -ErrorAction STOP
Start-Process "$DestinationFolder\SkypeOnlinePowerShell.Exe" -ArgumentList "/quiet" -Wait             
# Register PSGallery PSprovider and set as Trusted source
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 -ErrorAction SilentlyContinue            
Set-PSRepository -Name psgallery -InstallationPolicy trusted

# Install modules from PSGallery
Install-Module -Name AzureAD -Force
Install-Module -Name MSOnline -Force
Install-Module -Name AZ -Force
Install-Module -Name MicrosoftTeams -Force
Install-Module -Name Microsoft.Graph.Intune -Force
# Manually install Exchange Online with MFA authentication support from the Exchange Online ECP            
Write-Host "Login, go to Hybrid and download the Exchange Online Powershell module"            
Start-Process https://outlook.office365.com/ecp/

Connect to all Azure & Office 365 services in one PowerShell window

We've all been there, when running some commandlets from Exchange online suddenly you need to switch to Sharepoint, AzureAD or Skype Online.

With this handy script you can connect to all services at once.
I personally always use the Exchange Online PowerShell module for this, as it will be updated when starting it so you always have the latest commandlets for Exchange Online.

There are some requirements that have to be met before hand:
  • .Net 4.5
  • Windows Management Framework 3.0 or 4.0
  • 64-bit version of Windows OS
Installed modules:
  • Azure Active Directory V2 module
  • SharePoint Online module
  • Skype for Business Online module
Execution policy needs to be at least "Remote Signed"

In the past I have created a script that installs all these requirements at once:
I try to keep this updated, so if anything fails leave me a comment.

Then you can run the lines below and connect to all the services in one PowerShell window.
Mind you, this is all for MFA enabled accounts.

# Azure Active Directory            
# SharePoint Online            
Connect-SPOService -Url https://vitens-admin.sharepoint.com            
# Skype for Business Online            
Import-Module SkypeOnlineConnector            
$sfboSession = New-CsOnlineSession -UserName "edwin.vanbrenk2@vitens.nl" -OverrideAdminDomain vitens.onmicrosoft.com            
Import-PSSession $sfboSession            
# Exchange Online            
Connect-Exopssession -UserPrincipalName edwin.vanbrenk2@vitens.nl            
# Microsoft Teams            
# AzureAD            
# Intune            

30 January 2019

Export AD OU's Users and Groups & Import to test AD with a new domain name

Well this was a fun task, export Active Directory OU's, all users and groups and import everything into a new test active directory with a different domain name.

First export every thing I need:
Get-ADOrganizationalUnit -filter * | select Name,DistinguishedName | Export-csv -path C:\temp\OUexport.csv -NoTypeInformation
-Users: (per specific OU)
Get-ADUser -Filter * -SearchScope OneLevel -SearchBase "OU=Users,DC=domain,DC=lan" -Properties CanonicalName,CN,DisplayName,GivenName,Name,Surname | Export-Csv "C:\Temp\PeopleExport.csv"
Get-ADUser -Filter * -SearchScope OneLevel -SearchBase "OU=External,OU=Users,DC=domain,DC=lan" -Properties CanonicalName,CN,DisplayName,GivenName,Name,Surname | Export-Csv "C:\Temp\ExternalExport.csv"
Get-ADUser -Filter * -SearchScope OneLevel -SearchBase "OU=Regular Accounts,OU=Users,DC=domain,DC=lan" -Properties CanonicalName,CN,DisplayName,GivenName,Name,Surname | Export-Csv "C:\Temp\RegularAccountsExport.csv"
Get-ADUser -Filter * -SearchScope OneLevel -SearchBase "OU=RandomName,OU=External,OU=Users,DC=domain,DC=lan" -Properties CanonicalName,CN,DisplayName,GivenName,Name,Surname | Export-Csv "C:\Temp\RandomNameExternalExport.csv"
Get-ADgroup -filter * | select Name,DistinguishedName,samaccountname,groupcategory,groupscope | Export-csv -path "C:\temp\GroupsExport.csv"
Then copy the .csv's to the new domain controller in C:\Temp.
Go through the files an find and replace the domainname to the new domainname.

You have to do something extra for the Group's.
In Notepad++ search and replace the CN- value for the DistinguishedName value.
It will look like this in the csv file:

But it needs to be:

This is because the CN does not exist yet.
To replace the "CN=*," value use this in notepad++: \CN=.*?,
Where "\CN=" searches for "CN=", "*" searches for everything between "=" and "," and "?," stops the search where the "," is found.

Then import:
#Import AD Module - RSAT must be installed or run from DC
Import-Module ActiveDirectory
#Varibale location for CSV file
$ous = Import-Csv -Path "C:\temp\OUexport.csv"
# For each function to create OU's 
foreach ($ou in $ous)  
# Function Variables
    $ouname = $ou.name
    $oudn = $ou.DistinguishedName
# Function
    New-ADOrganizationalUnit -Name $ouname -Path $oudn  -ManagedBy 'domain admins'
Import-Csv .\PeopleExport.csv | New-ADUser -Enabled $True -Path 'OU=People,DC=sapgrc,DC=local' -AccountPassword (ConvertTo-SecureString Pass123 -AsPlainText -force)            
Import-Csv .\externenExport.csv | New-ADUser -Enabled $True -Path 'OU=Externen,OU=People,DC=sapgrc,DC=local' -AccountPassword (ConvertTo-SecureString Pass123 -AsPlainText -force)            
Import-Csv .\algemeneaccountsexport.csv | New-ADUser -Enabled $True -Path 'OU=Algemene Accounts,OU=People,DC=sapgrc,DC=local' -AccountPassword (ConvertTo-SecureString Pass123 -AsPlainText -force)            
Import-Csv .\veiexternenExport.csv | New-ADUser -Enabled $True -Path 'OU=VEI,OU=Externen,OU=People,DC=sapgrc,DC=local' -AccountPassword (ConvertTo-SecureString Pass123 -AsPlainText -force)
#Import AD Module - RSAT must be installed or run from DC            
Import-Module ActiveDirectory            
#Import CSV            
$csv = Import-Csv -Path "C:\Temp\GroupsExport.csv"            
#Loop through all items in the CSV            
ForEach ($item In $csv)            
    #Create the group if it doesn't exist            
    $create = New-ADGroup -Path $item.DistinguishedName -SamAccountName $item.SamAccountName -GroupCategory $item.GroupCategory -GroupScope $item.GroupScope -Name $item.Name             
    Write-Host "Group $($item.Name) created!"            

And there you have it.

22 January 2019

The content cannot be displayed in a frame - Exchange On-Premises - Exchange Online - Exchange Hybrid

After setting up your Hybrid Exchange connection and logging in to the Exchange Control Panel trying to move your first mailbox to Exchange Online you need to login to Office365.

When you click the login button on the popup you receive the following error:
Now this is fairly easy to fix, just add the url https://outlook.office365.com to the trusted sites in Internet Explorer.
But then this:
The option is greyed out.

There are 2 ways to get around this, one through the registry and one through a group policy:
Add the following to a textfile and paste in:
Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMapKey]
Save as a .reg and execute.

This can also be stored in the HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMapKey.

The check if the settings are present run in PowerShell:

$(get-item "HKCU:\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMapKey").property            
$(get-item "HKLM:\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMapKey").property            

The group policy goes like this:
  • Start -> type gpedit.msc -> hit Enter
  • navigate to Computer Configuration -> Administrative Templates -> Windows Components -> Internet Explorer -> Internet Control Panel -> Security Page
  • in the right-hand panel, double-click on the Site to Zone Assignment List option, then click Show...
  • trusted sites are the ones with 2 in the Value column (1 = Intranet, 3 = Internet, 4 = Restricted)
If that doesn't work (that option is set to "Not Configured" or the list is empty), try the same, except instead of Computer Configuration, start with User Configuration.

03 January 2019

Enable audit logging on all mailboxes in your tenant - Optimize your SecureScore

If you want to achieve the highest Secure Score number you will be advised to enable mailbox auditing by the SecureScore actions list.
If you follow the link provided in the article you will land on a Github page that has a script to enable auditing on all mailboxes in a tenant.
But it was missing one type of mailbox, the SchedulingMailbox.
I added the missing mailbox type in the command below, now it works as it should.

First login to your tenant with global admin rights or Exchange Online admin privileges:
Check how your settings are now:
Get-Mailbox -ResultSize Unlimited | Select Name, AuditEnabled, AuditLogAgeLimit | Out-Gridview
Then turn on audit logging on all mailboxes:
Get-Mailbox -ResultSize Unlimited -Filter {RecipientTypeDetails -eq "UserMailbox" -or RecipientTypeDetails -eq "SharedMailbox" -or 
RecipientTypeDetails -eq "RoomMailbox" -or RecipientTypeDetails -eq "DiscoveryMailbox" -or RecipientTypeDetails -eq "SchedulingMailbox"}
 | Set-Mailbox -AuditEnabled $true -AuditLogAgeLimit 180 -AuditAdmin Update, MoveToDeletedItems, SoftDelete, HardDelete, SendAs, 
SendOnBehalf, Create, UpdateFolderPermission -AuditDelegate Update, SoftDelete, HardDelete, SendAs, Create, UpdateFolderPermissions, 
MoveToDeletedItems, SendOnBehalf -AuditOwner UpdateFolderPermission, MailboxLogin, Create, SoftDelete, HardDelete, Update, MoveToDeletedItems
Check again to be sure all mailboxes are enabled for audit logging:
Get-Mailbox -ResultSize Unlimited | Select Name, AuditEnabled, AuditLogAgeLimit | Out-Gridview

27 December 2018

Save disk space - Compact - NTFS compress your folders

In the ever ongoing search for disk space on Exchange servers it is possible to compress certain folders with NTFS compression.
You could do this through the file explorer and click yourself silly, or you can turn to PowerShell.
Actually it's just an old command prompt program, but we'll use it in PowerShell.

Now first things first:


This may seem like a no brainer but I don't want to hear that someone used it because I didn't warn them.
The only thing you can safely use this for is on log files, temp files, etl files and blg files.
If you've read my previous blog post about cleaning up certain logging folders used by exchange (which can be found here:

Here are the directories you can compress safely:
As always with scripts/code found on the internet, test it yourself on a test environment.

.\compact.exe /C /S /A /I "C:\Program Files\Microsoft\Exchange Server\V15\Logging\*"                        
.\compact.exe /C /S /A /I "C:\Program Files\Microsoft\Exchange Server\V15\Bin\Search\Ceres\Diagnostics\ETLTraces\*"                        
.\compact.exe /C /S /A /I "C:\Program Files\Microsoft\Exchange Server\V15\Bin\Search\Ceres\Diagnostics\Logs\*"                        
.\compact.exe /C /S /A /I "C:\Program Files\Microsoft\Exchange Server\V15\FIP-FS\Data\ProgramLogArchive\*"                        
.\compact.exe /C /S /A /I "C:\Program Files\Microsoft\Exchange Server\V15\TransportRoles\Logs\FrontEnd\Connectivity\*"                        
.\compact.exe /C /S /A /I "C:\Windows\System32\LogFiles\HTTPERR\*"