28 February 2022

Azure ADConnect Access is Denied error code 5 - Azure ADConnect not syncing password hashes anymore

 After receiving a warning from Azure that the password sync has not run for 1 hour I started checking where this could come from.

The first place is to check the Office365 portal "Directory sync status" page under "Health":

https://admin.microsoft.com/Adminportal/Home?#/dirsyncmanagement

The second place is to check the "Azure AD Connect" page in the Azure portal:

https://portal.azure.com/#blade/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/AzureADConnect

Now you know that there is a problem, the next step is to check the Azure ADConnect server itself.
After opening the Synchronization Service Manager you are greated with this error, well in my case anyway:

The thing to check is the account that is being used to sync with:

Import-Module
"C:\Program Files\Microsoft Azure Active Directory Connect\AdSyncConfig\AdSyncConfig.psm1" Get-ADSyncADConnectorAccount Copy the "ADConnectorAccountName"

Copy the "ADConnectorAccountName"

Run the following commandlet's with your ADConnectorAccountName value:
Set-ADSyncMsDsConsistencyGuidPermissions -ADConnectorAccountName "MSOL_1234abcd1234" -ADConnectorAccountDomain domain.ads

Set-ADSyncPasswordHashSyncPermissions -ADConnectorAccountName "MSOL_1234abcd1234" -ADConnectorAccountDomain domain.ads

Set-ADSyncPasswordWritebackPermissions -ADConnectorAccountName "MSOL_1234abcd1234" -ADConnectorAccountDomain domain.ads

Set-ADSyncUnifiedGroupWritebackPermissions -ADConnectorAccountName "MSOL_1234abcd1234" -ADConnectorAccountDomain domain.ads

And now run a full sync

Start-ADSyncSyncCycle -PolicyType Initial -Verbose

17 February 2022

Reset the Teamsmeetingpolicy to "Global" for all users

Some users reported that they couldn't use certain features, such as "transcription".

When comparing myself with the affected user I noticed that my Teamsmeetingpolicy had no policy set.
I would expected it to show "Global". Turns out the "Global policy" isn't a user policy and therefore doesn't show up with a name.

The affected user did have a policy set: "RestricetedAnonymousAccess".

Now I had to give those users the "Global" Teamsmeetingpolicy and came up with this:

 1
2
3
4
5
6
7
$users = Get-CsOnlineUser -ResultSize unlimited
foreach($User in $Users)
{
$userId = $User.UserPrincipalName
Write-Host $userId
Grant-CsTeamsMeetingPolicy -Identity $userId -PolicyName $Null -ErrorAction SilentlyContinue
}

This resets all users to no policy and thus the "Global" policy.

Maybe it is a bit much for large environments, it takes quite a long time to run.
With some filtering this could be done quicker.

 1
2
3
4
5
6
7
$users = Get-CsOnlineUser -ResultSize unlimited -Filter {Teamsmeetingpolicy -ne $null}
foreach($User in $Users)
{
$userId = $User.UserPrincipalName
Write-Host $userId
Grant-CsTeamsMeetingPolicy -Identity $userId -PolicyName $Null -ErrorAction SilentlyContinue
}

21 January 2022

Count your Active directory objects

When installing AADConnect you need to size your server according to this table:

Hardware requirements for Azure AD Connect

The following table shows the minimum requirements for the Azure AD Connect sync computer.


To quickly count all objects in your Active Directory do this:

1|
(Get-ADObject -SearchBase "dc=Mydomain,dc=com" -LDAPFilter "(objectCategory=*)").Count

This will show all objects.

If you want to know how many user, group, computer account, distribution group and security group objects there are do this:
1|
2|
3|
4|
5|
6|
7|
$ADUser = (Get-AdUser -Filter *).Count
$ADGroup = (Get-ADGroup -Filter *).Count
$ADComputer = (Get-ADComputer -Filter *).Count
$Distribution_Groups = (Get-ADGroup -Filter {GroupCategory -eq "Distribution"}).count
$Security_Groups = (Get-ADGroup -Filter {GroupCategory -eq "Security"}).count
$ADObjects = $ADUser + $ADGroup + $ADComputer + $Distribution_Groups + $Security_Groups
$ADObjects

13 January 2022

Enable TLS 1.3 on Windows Server 2022

HTTP/3 support is an opt-in option on Windows Server 2022 via a registry key named "EnableHttp3" with value 1 at "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\HTTP\Parameters".
Running this command from an elevated prompt will create the key:

reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\HTTP\Parameters" /v EnableHttp3 /t REG_DWORD /d 1 /f

Then restart the http.sys service or reboot Windows to apply the setting.

It is likely the web service will need to advertise it is available over HTTP/3 as well using “Alt-Svc” headers in HTTP/2 responses (though this can also be done using HTTP/2 ALTSVC frames). This allows clients who connect over HTTP/2 to learn the service’s HTTP/3 endpoint and use that going forward. This is done by sending an HTTP/3 ALPN (“Application-layer Protocol Negotiation”) identifier with HTTP/2 responses advertising a specific version of HTTP/3 to use for future requests. Sending the ALTSVC frame can be done by http.sys. That can be enabled by setting the “EnableAltSvc” registry key with the command below.

reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\HTTP\Parameters" /v EnableAltSvc /t REG_DWORD /d 1 /f

After that run the following in PowerShell:

Enable-TlsCipherSuite -Name TLS_CHACHA20_POLY1305_SHA256 -Position 0

Finally, add the HTTP/3 response header to your IIS website. 

Under the HTTP Response Headers, add a custom HTTP response header with the following information:
Name: alt-svc
Value: h3=":443"; ma=86400; persist=1


After adding the response header, enabling the cipher suites and merging the registry keys, reboot your Windows Server 2022 server.

06 January 2022

Set Outlook delegate permission with PowerShell

Sometimes my users ask things I didn't know existed.

The question I got was: Why can't I see the meeting invitations sent to the persons mailbox and calendar I manage in my own inbox? I knew it had to do with delegates, but thought that could only be set by the owner of the mailbox. Turns out I was wrong, it can be set by the admin with PowerShell.

It's always PowerShell 😜

First check the current permissions:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
Get-MailboxFolderPermission "TargetUser:\agenda"

FolderName           User                 AccessRights                           SharingPermissionFlags
----------           ----                 ------------                           ----------------------
Agenda               Default              {AvailabilityOnly}
Agenda               DestinationUser      {PublishingEditor}                     Delegate
Agenda               SomeUser             {Reviewer}
Agenda               SomeUser2            {LimitedDetails}
Agenda               TargetUser           {LimitedDetails}
Agenda               SomeUser3            {Editor}                               Delegate

Then remove all the existing permissions for the destination user:

 1
2
3
4
5
6
Remove-MailboxFolderPermission "TargetUser:\agenda" -User DestinationUser

Confirm
Are you sure you want to perform this action?
Removing mailbox folder permission on Identity:"TargetUser:\agenda" for user "DestinationUser".
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [?] Help (default is "Y"):

There's a few things to note before setting the permissions. To be able to grant the delegate permissions and all options the AccessRight has to be "Editor", the SharingPermissionsFlags need to be separated with a comma, and the option to SendNotificationToUser expects a boolean value so set a $False for no notification or $True to send a notification to the user:

 1
2
3
4
5
add-MailboxFolderPermission "TargetUser:\agenda" -User DestinationUser -SharingPermissionFlags delegate,canviewprivateitems -AccessRights editor -SendNotificationToUser $true

FolderName           User                 AccessRights                           SharingPermissionFlags
----------           ----                 ------------                           ----------------------
Agenda               DestinationUser      {Editor}                               Delegate, CanViewPrivateItems

That's it

17 December 2021

Microsoft.Exchange.Data.Storage.SendAsDeniedException: Can't transport send message - Set Send-As permission for on-prem mailbox

Unable to send as from on-prem as an Exchange online user? Chances are that your access rights aren't setup correctly.

First of all there is a known issue regarding "Send-As" and "Send on behalve" in Exchange Online:

Can't manage "Send as" and "Send on behalf" permissions for Exchange Online users in an on-premises hybrid environment
Exchange Online
Symptoms

You can’t find a user who was migrated to Exchange Online in the People Picker in the Exchange Admin Center (EAC). Additionally, the "Send as" and "Send on behalf" permissions can’t be added for legacy dedicated or on-premises mailboxes.
Cause

After mailboxes are moved from the on-premises environment to Exchange Online, they are represented as Remote Mailboxes. These remote mailboxes are not displayed in the EAC People Picker.
Workaround

This issue is being investigated by Microsoft. To work around this issue, run the following Remote PowerShell cmdlets to add these permissions:

"Send as" permission: Add-ADPermission

"Send on behalf" permission: Set-Mailbox


How to get around this?

Connect to Exchange Online PowerShell and run the following:
 1
2
3
4
5
6
7
8
9
Add-RecipientPermission -Identity sharedmailbox@domain.nl -Trustee firstname.Lastname@domain.nl -AccesConfirm
Are you sure you want to perform this action?
Adding recipient permission 'SendAs' for user or group 'Firstname.Lastname@domain.nl' on recipient
Identity:'sharedmailbox@domain.nl'.
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [?] Help (default is "Y"): A

Identity Trustee                  AccessControlType AccessRights Inherited
-------- -------                  ----------------- ------------ ---------
Klic     Lastname, Firstname (50439) Allow             {SendAs}     False

Check your settings:
1
2
3
4
5
6
7
Get-RecipientPermission -Identity sharedmailbox@domain.nl

Identity Trustee                      AccessControlType AccessRights Inherited
-------- -------                      ----------------- ------------ ---------
Klic     NT AUTHORITY\SELF            Allow             {SendAs}     False
Klic     Some.User@domain.nl          Allow             {SendAs}     False
Klic     Firstname.Lastname@domain.nl Allow             {SendAs}     False

And for a security group:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
Add-RecipientPermission -Identity sharedmailbox@domain.nl -Trustee YourSecurityGroupName -AccessRights sendas

Confirm
Are you sure you want to perform this action?
Adding recipient permission 'SendAs' for user or group 'sm.klic' on recipient Identity:'klic.klicdomain@domain.nl'.
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [?] Help (default is "Y"): A

Identity Trustee               AccessControlType AccessRights Inherited
-------- --------------------- ----------------- ------------ ---------
Klic     YourSecurityGroupName Allow             {SendAs}     False

13 December 2021

554 5.2.0 STOREDRV.Deliver.Exception:ObjectNotFoundException.MapiExceptionNotFound - NDR when users send mail in Exchange Online

 I had never heard of this before, so maybe this helps others.

After sending an e-mail you may receive a NDR 554 5.2.0 STOREDRV.Deliver.Exception:ObjectNotFoundException.MapiExceptionNotFound.

What this means is that there is something on in the users mailbox called "clutter".
I had to look this up in my OWA mailbox.

You will only see this option when you have "Focused Inbox" turned on.
The user itself could turn it off, but in many cases the user doesn't know how to or is out of the office or whatever.

So ofcourse this can be done with PowerShell:

First check to see the current setting
1
2
3
4
5
6
7
8
9
Get-Clutter -Identity username@domain.nl


RunspaceId      : 2a09c611-03b6-4926-8293-c1692c3bcb00
IsEnabled       : True
MailboxIdentity : username@domain.nl
Identity        :
IsValid         : True
ObjectState     : New

As you can see the setting "Clutter" is revered to as "IsEnabled"

Then set the value to $False

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
Get-Mailbox username@domain.nl | Set-Clutter -Enable $false


RunspaceId      : 2a09c611-03b6-4926-8293-c1692c3bcb00
IsEnabled       : False
MailboxIdentity : CN=username,OU=tenantname.onmicrosoft.com,OU=Microsoft Exchange Hosted
                  Organizations,DC=EURPR10A003,DC=PROD,DC=OUTLOOK,DC=COM
Identity        :
IsValid         : True
ObjectState     : New

01 December 2021

Move new mailbox from on-premises to Exchange Online with PowerShell - Exchange Hybrid new mailbox moves

If your running Exchange Hybrid then you need to create your mailboxes on premises first and then sync them to AzureAD/Office365/EXO. 

Now in my case this was a manual task, and ofcourse this was forgotten too often.
So I created this script, to automate the move.
I'm still looking for the way to let the moves be visible in the EAC, it's something with New-MigrationBatch and Start-MigrationBatch.
I just didn't find the time yet to mess with it.

If you have the right method to make this possible, drop a line below.

For now this is how I do it (this needs to run from an Exchange server on-premises or a management server with the Exchange Management Tools installed):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# Load Exchange modules and snapin
add-pssnapin microsoft.exchange.management.powershell.snapin
. $env:ExchangeInstallPath\bin\RemoteExchange.ps1

# Connect to local Exchange server
Connect-ExchangeServer -auto -AllowClobber

# Import EXO module
Import-Module -Name ExchangeOnlineManagement

# Get the current date
$Date = Get-Date -format dd-MM-yyyy

# Get mailboxes created in the last 7 days
$mailboxes = Get-Mailbox | Where-Object {$_.WhenCreated ge ((Get-Date).Adddays(-7))} `
| Select UserPrincipalName,identity,samaccountname

# Get on-prem credentials
$onpremcred = Get-Credential domain\username

# Set the proxy for the connection to EXO
netsh winhttp set proxy proxy-server="http=proxy.domain.lan;https=proxy.domain.lan:8080" `
bypass-list="*.domain.lan;10.*"

# Connect to EXO
Connect-ExchangeOnline -UserPrincipalName username@domain.nl

# Show the mailboxes to move
$mailboxes

# Create a move request per found mailboxes
foreach ($mailbox in $mailboxes)
{
$username = $mailbox.Samaccountname
$moverequestbatch = New-MoveRequest -Identity $mailbox.SamAccountName -remote `
-RemoteHostName hybridserver.domain.nl -TargetDeliveryDomain tenantname.mail.onmicrosoft.com `
-RemoteCredential $OnPremCred -BatchName "MigrationService:$username"

<# === This piece is experimental ===
#$migrationEndpointOnPrem = tenantname.domain.nl-endpoint
#$OnboardingBatch = New-MigrationBatch -Name $username -SourceEndpoint `
$MigrationEndpointOnprem.Identity -TargetDeliveryDomain tenantname.mail.onmicrosoft.com `
-CSVData ([System.IO.File]::ReadAllBytes("C:\Users\Administrator\Desktop\RemoteOnBoarding1.csv"))

#Start-MigrationBatch -AutoStart -Name -AutoComplete -Identity $OnboardingBatch.Identity
#>
}

# Reset the proxy
netsh winhttp reset proxy

<#
# Some command to check your moves
Get-MoveRequest
Get-moverequest | Get-moverequeststatistics
Get-MoveRequest | Select batchname
Get-MoveRequest -MoveStatus Completed | Remove-MoveRequest -confirm:$false
Get-MoveRequest -MoveStatus CompletedWithWarning | Remove-MoveRequest -confirm:$false
#>

22 October 2021

Teams Team not showing in Outlook groups - Microsoft 365 group not showing in Outlook groups

Learned something today.

If you create a Teams Team or a Microsoft 365 group, and these were created via Microsoft Teams, they are hidden from Outlook by default.
If you want them to show in both the Outlook left navigation and the address book, you can use Set-UnifiedGroup to flip -HiddenFromExchangeClientsEnabled to $false.

Connect to Exchange Online PowerShell.

To get a group and it's current settings:

Get-UnifiedGroup -id YourGroupName | select displayname,hidden*            
            
DisplayName        HiddenFromExchangeClientsEnabled HiddenGroupMembershipEnabled HiddenFromAddressListsEnabled            
____               ________________________________ ____________________________ _____________________________            
YourGroupName                                  True                        False                         False

To unhide a group:
Set-UnifiedGroup -Identity YourGroupName -HiddenFromExchangeClientsEnabled:$false
Check your adjustment:
Get-UnifiedGroup -id YourGroupName | select displayname,hidden*            
            
DisplayName        HiddenFromExchangeClientsEnabled HiddenGroupMembershipEnabled HiddenFromAddressListsEnabled            
____               ________________________________ ____________________________ _____________________________            
YourGroupName                                 False                        False                         False
Set all groups in your organization to be visible in Outlook:
Get-UnifiedGroup -ResultSize unlimited | Set-UnifiedGroup -HiddenFromExchangeClientsEnabled:$false
Be careful with the last one, if your users have a lot of memberships to Teams the list in Outlook may get very long.

15 October 2021

Skip TPM check Windows 11 installation (upgrading) on unsupported hardware with PowerShell

Run in an elevated PowerShell:

# Skip TPM check Windows 11
{
REG ADD "HKLM\SYSTEM\Setup\MoSetup" /vAllowUpgradesWithUnsupportedTPMOrCPU /t REG_DWORD /d 1 /f
REG QUERY "HKLM\SYSTEM\Setup\MoSetup"
}
Happy upgrading