Saturday, 18 May 2019

vCenter Server 6.7 - Error trying to join AD, error code [41887]


When trying to join vCenter to the Active Directory domain for Single Sign on, the following error is displayed:

idm client exception: Error trying to join AD, error code [41887], user [username@domain], domain [domain.local], orgUnit []


Joining Active Directory fails in vCenter due to the user attempting to authenticate using a logon name that is not their user principal name (UPN.) Check the user's account object in Active Directory Users & Computers - user logon name - in Account tab.


Use the user's UPN to authenticate to AD and the configuration should succeed.

Wednesday, 3 April 2019

Creating Custom Azure RBAC Roles with PowerShell

Custom Azure RBAC Role


Azure has a bunch of built in roles but sometimes you need someone or something to be able to do a single task and don’t want to over permission their account.

Azure RBAC allows you to define a custom role with really granular permissions. To do this you can use PowerShell to pull one of Azure’s pre-defined templates, modify it in a text editor using JSON, then push it back as a custom defined role to assign to your user.

My example will be to create a user role that’s able to read BGP status information from the subscription. Initially I created a user and gave it the ‘Reader’ role but I hit the following error.


Take a note of the permission (Action) required, as this will be used to create the new role definition.


Find a suitable role to copy

Check the list of RBAC roles by attempting to add role to a user on a subscription, resource group or resource in the portal. You can also run the following PowerShell command to get a list of all the resources in your subscription.


Once you’ve selected a template that’s similar to what you want, then get the definition and view the current permissions. I’m just using the ‘Reader’ role as it’s really simple and I only need a couple of additional permissions.

Get-AzureRmRoleDefinition "Reader"


You can now export the definition to a JSON file for editing

Get-AzureRmRoleDefinition "Reader" | ConvertTo-Json | Out-File C:\Temp\CustomReader.json

Edit the file in a text editor. You need to remove the id tag and change IsCustom to true. Change the Name, Description and add in the Actions required.

    "Name":  "Reader",
    "Id":  "f3323452-47a2-4221-bc0c-d66f17e14e98",
    "IsCustom":  false,
    "Description":  "Can read all monitoring data.",
    "Actions":  [
    "NotActions":  [
    "AssignableScopes":  [

And here is my custom file, note I have set this to be limited to a subscription. Also, I have modified the Action to include all actions for virtualNetworkGateways.

"Name":  "BGP Status Reader",
"IsCustom":  true,
"Description":  "Can read BGP Status data.",
"Actions":  [
"NotActions":  [

"AssignableScopes":  [

Once you’re happy with the modifications, you can use it to create a custom role definition.

New-AzureRmRoleDefinition -InputFile C:\Temp\CustomReader.json

You can now assign this role definition to your user account.


And re-run the problematic command.


If you have difficulty and need to remove your custom role, you can run the following command.

Get-AzureRmRoleDefinition | 
	Where-Object { $_.isCustom } | 
	Where-Object { $_.Name -eq 'BGP Status Reader' } | 

Once the role is removed you can recreate it with the above commands. There is also a Set-AzureAzureRmRoleDefinition but this may require modifying your JSON.


Written with StackEdit.

Wednesday, 16 January 2019

One-Liner's for AD Time Synchronisation Information

After finding that some of my domain controller VMs were set to sync with the host, I had a time synchronisation issue across my domiain. Here are a couple of commands that assisted in resolving the problem.

Show all Domain Controller times with 1 sample

(Get-ADForest).GlobalCatalogs | sort | % { Write-Host "$($_): " -foregroundcolor Yellow -nonewline ; w32tm /stripchart /computer:$_ /dataonly /samples:1 | Select -Last 1}

The first column is the DC name, 2nd is local time (machine you're running the command from) and the 3rd is the DC's offset from local time

Force Sync on all DCs

(Get-ADForest).GlobalCatalogs | % { w32tm /resync /computer:$_ /nowait}

Slightly more full featured script: