<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>PowerCLI on Cosmin.us</title><link>https://cosmin.us/tags/powercli/</link><description>Recent content in PowerCLI on Cosmin.us</description><generator>Hugo</generator><language>en-US</language><managingEditor>Cosmin Trif</managingEditor><lastBuildDate>Tue, 30 Jun 2026 15:45:00 +0000</lastBuildDate><atom:link href="https://cosmin.us/tags/powercli/index.xml" rel="self" type="application/rss+xml"/><item><title>Exporting and Restoring vCenter 8.x Permissions Before Breaking Enhanced Linked Mode</title><link>https://cosmin.us/exporting-and-restoring-vcenter-8-x-permissions-before-breaking-enhanced-linked-mode/</link><pubDate>Tue, 30 Jun 2026 15:45:00 +0000</pubDate><author>Cosmin Trif</author><guid>https://cosmin.us/exporting-and-restoring-vcenter-8-x-permissions-before-breaking-enhanced-linked-mode/</guid><description>&lt;p&gt;Breaking Enhanced Linked Mode is one of those changes where the technical command is not the hardest part. The hard part is making sure administrators, service accounts, and external products can still log in and do their jobs after the vCenters no longer share the same SSO domain.&lt;/p&gt;
&lt;p&gt;In this post I will walk through a repeatable way to export and restore vCenter 8.x RBAC data before splitting Enhanced Linked Mode. The focus is on three permission layers:&lt;/p&gt;</description><content:encoded>&lt;p&gt;Breaking Enhanced Linked Mode is one of those changes where the technical command is not the hardest part. The hard part is making sure administrators, service accounts, and external products can still log in and do their jobs after the vCenters no longer share the same SSO domain.&lt;/p&gt;
&lt;p&gt;In this post I will walk through a repeatable way to export and restore vCenter 8.x RBAC data before splitting Enhanced Linked Mode. The focus is on three permission layers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Custom roles&lt;/li&gt;
&lt;li&gt;Explicit object or inventory permissions&lt;/li&gt;
&lt;li&gt;Global permissions&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The short version is this: &lt;strong&gt;object permissions usually survive the split because they live in the vCenter database, but global permissions and SSO-domain objects need special handling&lt;/strong&gt;. If you depend on global permissions, do not start the split until you have exported them and have a plan to recreate or import them afterward.&lt;/p&gt;
&lt;h2 id="what-changes-when-you-split-elm"&gt;What Changes When You Split ELM&lt;/h2&gt;
&lt;p&gt;Enhanced Linked Mode lets multiple vCenter Server instances share one vCenter Single Sign-On domain. When you break that relationship, the vCenters stop sharing the same SSO namespace.&lt;/p&gt;
&lt;p&gt;That matters because not all permissions are stored the same way.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Item&lt;/th&gt;
					&lt;th&gt;What to expect&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Custom roles&lt;/td&gt;
					&lt;td&gt;Export and re-import them so role names and privilege sets are consistent.&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Object permissions&lt;/td&gt;
					&lt;td&gt;Usually remain on the vCenter inventory objects, but the principals must still resolve after the split.&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Global permissions&lt;/td&gt;
					&lt;td&gt;Must be exported and recreated/imported after the split.&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Local SSO users/groups&lt;/td&gt;
					&lt;td&gt;Must be recreated if they are still needed.&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;AD/LDAP identity sources&lt;/td&gt;
					&lt;td&gt;Must be recreated or verified on the standalone vCenter.&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Solution users/plugins&lt;/td&gt;
					&lt;td&gt;Usually need product-specific re-registration or repair.&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;If the environment is managed by VMware Cloud Foundation / SDDC Manager, stop and validate supportability first. Cross-domain repointing is not something I would treat as a casual vCenter-only operation in a VCF managed environment.&lt;/p&gt;
&lt;h2 id="download-the-helper-scripts"&gt;Download the Helper Scripts&lt;/h2&gt;
&lt;p&gt;I use three helper scripts for this workflow:&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Script&lt;/th&gt;
					&lt;th&gt;Purpose&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;a href="https://cosmin.us/downloads/vcenter-elm-rbac/Export-VCenterRbac.ps1"&gt;Export-VCenterRbac.ps1&lt;/a&gt;&lt;/td&gt;
					&lt;td&gt;Exports custom roles and explicit object permissions from a vCenter.&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;a href="https://cosmin.us/downloads/vcenter-elm-rbac/Convert-AuthzDoctorPermissions.ps1"&gt;Convert-AuthzDoctorPermissions.ps1&lt;/a&gt;&lt;/td&gt;
					&lt;td&gt;Converts &lt;code&gt;authz-doctor&lt;/code&gt; output into a clean CSV for global permissions.&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;a href="https://cosmin.us/downloads/vcenter-elm-rbac/Import-VCenterRbac.ps1"&gt;Import-VCenterRbac.ps1&lt;/a&gt;&lt;/td&gt;
					&lt;td&gt;Imports roles, optional global permissions, and object permissions after the split.&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The scripts assume PowerShell 7+ and PowerCLI:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;Install-Module&lt;/span&gt; &lt;span class="n"&gt;VMware&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;PowerCLI&lt;/span&gt; &lt;span class="n"&gt;-Scope&lt;/span&gt; &lt;span class="n"&gt;CurrentUser&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;Set-PowerCLIConfiguration&lt;/span&gt; &lt;span class="n"&gt;-InvalidCertificateAction&lt;/span&gt; &lt;span class="n"&gt;Warn&lt;/span&gt; &lt;span class="n"&gt;-Confirm:&lt;/span&gt;&lt;span class="vm"&gt;$false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Run the import with &lt;code&gt;-WhatIf&lt;/code&gt; first. This is especially important when restoring global permissions.&lt;/p&gt;
&lt;h2 id="before-you-export-anything"&gt;Before You Export Anything&lt;/h2&gt;
&lt;p&gt;Do the boring checks first. This is where most bad outcomes are avoided.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Confirm which vCenters are staying linked and which vCenters are being split.&lt;/li&gt;
&lt;li&gt;Confirm you have working SSO administrator access.&lt;/li&gt;
&lt;li&gt;Confirm you have root access to each VCSA so you can run &lt;code&gt;authz-doctor&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Take a file-based backup of each vCenter.&lt;/li&gt;
&lt;li&gt;Take powered-off snapshots of all ELM nodes at the same point in time if that is your rollback method.&lt;/li&gt;
&lt;li&gt;If vCenter HA is enabled, remove it before the split.&lt;/li&gt;
&lt;li&gt;Identify any local SSO users/groups that need to exist after the split.&lt;/li&gt;
&lt;li&gt;Identify all AD/LDAP identity sources that need to be recreated.&lt;/li&gt;
&lt;li&gt;Identify solution accounts for NSX, SRM, Aria, backup products, monitoring tools, and plugins.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I also like to create at least one explicit vCenter-root permission for a known AD admin group on each vCenter before the change. Do not rely only on global permissions for your break-glass path.&lt;/p&gt;
&lt;h2 id="step-1-export-roles-and-object-permissions"&gt;Step 1: Export Roles and Object Permissions&lt;/h2&gt;
&lt;p&gt;Create one export folder per vCenter. Do not mix them. The object paths and managed object references are specific to the vCenter they came from.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;&lt;span class="n"&gt;C:&lt;/span&gt;&lt;span class="p"&gt;\&lt;/span&gt;&lt;span class="n"&gt;temp&lt;/span&gt;&lt;span class="p"&gt;\&lt;/span&gt;&lt;span class="nb"&gt;vcenter-elm&lt;/span&gt;&lt;span class="n"&gt;-rbac&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;.\&lt;/span&gt;&lt;span class="nb"&gt;Export-VCenterRbac&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;ps1&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;-Server&lt;/span&gt; &lt;span class="n"&gt;vcsa01&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;example&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;com&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;-OutDir&lt;/span&gt; &lt;span class="p"&gt;.\&lt;/span&gt;&lt;span class="n"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;\&lt;/span&gt;&lt;span class="n"&gt;vcsa01&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;.\&lt;/span&gt;&lt;span class="nb"&gt;Export-VCenterRbac&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;ps1&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;-Server&lt;/span&gt; &lt;span class="n"&gt;vcsa02&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;example&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;com&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;-OutDir&lt;/span&gt; &lt;span class="p"&gt;.\&lt;/span&gt;&lt;span class="n"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;\&lt;/span&gt;&lt;span class="n"&gt;vcsa02&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;.\&lt;/span&gt;&lt;span class="nb"&gt;Export-VCenterRbac&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;ps1&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;-Server&lt;/span&gt; &lt;span class="n"&gt;vcsa03&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;example&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;com&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;-OutDir&lt;/span&gt; &lt;span class="p"&gt;.\&lt;/span&gt;&lt;span class="n"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;\&lt;/span&gt;&lt;span class="n"&gt;vcsa03&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Each export folder should contain:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;manifest.json
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;roles.json
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;object-permissions.json
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;object-permissions.csv
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;global-permissions.template.csv
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;roles.json&lt;/code&gt; is used for import. &lt;code&gt;object-permissions.json&lt;/code&gt; is also used for import. The CSV is there so you can review the permissions quickly in Excel or another editor.&lt;/p&gt;
&lt;p&gt;Open &lt;code&gt;manifest.json&lt;/code&gt; and make sure the count looks reasonable:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;Get-Content&lt;/span&gt; &lt;span class="p"&gt;.\&lt;/span&gt;&lt;span class="n"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;\&lt;/span&gt;&lt;span class="n"&gt;vcsa01&lt;/span&gt;&lt;span class="p"&gt;\&lt;/span&gt;&lt;span class="n"&gt;manifest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;json&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;ConvertFrom-Json&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="step-2-export-global-permissions-with-authz-doctor"&gt;Step 2: Export Global Permissions with authz-doctor&lt;/h2&gt;
&lt;p&gt;Global permissions are the part I care about most in an ELM split. They are easy to forget because they live under &lt;strong&gt;Administration &amp;gt; Access Control &amp;gt; Global Permissions&lt;/strong&gt;, not on the normal inventory tree.&lt;/p&gt;
&lt;p&gt;On each vCenter appliance, SSH in as &lt;code&gt;root&lt;/code&gt; and run:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/usr/lib/vmware-vpx/scripts/authz-doctor/authz-doctor.py permission_check &amp;gt; /tmp/authz-doctor-permissions.txt
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Copy the file back to the matching export folder:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;scp root@vcsa01.example.com:/tmp/authz-doctor-permissions.txt ./exports/vcsa01/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The permission rows in that file are pipe-delimited and look like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Principal | IsGroup | RoleId | RoleName | Propagate | Entity
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;VSPHERE.LOCAL\vpxd-extension-xxxx | False | -1 | Admin | True | Global
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;DOMAIN\vSphere-Admins | True | -1 | Admin | True | Global
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The converter detects these rows by their column layout, so it does not matter whether your vCenter build prints a leading &lt;code&gt;|&lt;/code&gt; on each row.&lt;/p&gt;
&lt;p&gt;Then convert the global permission rows into CSV:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;.\&lt;/span&gt;&lt;span class="nb"&gt;Convert-AuthzDoctorPermissions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;ps1&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;-InputFile&lt;/span&gt; &lt;span class="p"&gt;.\&lt;/span&gt;&lt;span class="n"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;\&lt;/span&gt;&lt;span class="n"&gt;vcsa01&lt;/span&gt;&lt;span class="p"&gt;\&lt;/span&gt;&lt;span class="nb"&gt;authz-doctor&lt;/span&gt;&lt;span class="n"&gt;-permissions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;txt&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;-OutputFile&lt;/span&gt; &lt;span class="p"&gt;.\&lt;/span&gt;&lt;span class="n"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;\&lt;/span&gt;&lt;span class="n"&gt;vcsa01&lt;/span&gt;&lt;span class="p"&gt;\&lt;/span&gt;&lt;span class="nb"&gt;global-permissions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;csv&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;-GlobalOnly&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Repeat this for each vCenter.&lt;/p&gt;
&lt;p&gt;The resulting file should have this shape:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Principal,IsGroup,RoleId,RoleName,Propagate,Entity
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;#34;DOMAIN\vSphere-Admins&amp;#34;,&amp;#34;True&amp;#34;,&amp;#34;-1&amp;#34;,&amp;#34;Admin&amp;#34;,&amp;#34;True&amp;#34;,&amp;#34;Global&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="step-3-review-principals-before-the-split"&gt;Step 3: Review Principals Before the Split&lt;/h2&gt;
&lt;p&gt;Do not blindly import the CSV later. Review it first.&lt;/p&gt;
&lt;p&gt;Pay special attention to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;administrator@vsphere.local&lt;/code&gt; or users from the old SSO domain&lt;/li&gt;
&lt;li&gt;Local SSO groups that will not exist after the split&lt;/li&gt;
&lt;li&gt;Solution users such as &lt;code&gt;vpxd-*&lt;/code&gt;, &lt;code&gt;vsphere-ui-*&lt;/code&gt;, NSX, SRM, backup, or monitoring accounts&lt;/li&gt;
&lt;li&gt;AD groups whose domain name or identity source alias may change&lt;/li&gt;
&lt;li&gt;Custom roles that exist on one vCenter but not another&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you are moving from a shared SSO domain to standalone SSO domains, a principal name that made sense before the split may not resolve afterward. The permission entry can exist, but it is useless if the identity source cannot resolve the user or group.&lt;/p&gt;
&lt;h2 id="step-4-add-temporary-object-level-admin-access"&gt;Step 4: Add Temporary Object-Level Admin Access&lt;/h2&gt;
&lt;p&gt;Before breaking ELM, add a direct permission at the root of each vCenter inventory for the admin group you will use after the split.&lt;/p&gt;
&lt;p&gt;In the vSphere Client:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Select the vCenter object at the top of the inventory.&lt;/li&gt;
&lt;li&gt;Go to &lt;strong&gt;Permissions&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Add your AD admin group.&lt;/li&gt;
&lt;li&gt;Assign the appropriate role, usually &lt;code&gt;Administrator&lt;/code&gt; for the migration window.&lt;/li&gt;
&lt;li&gt;Enable propagation.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This gives you a local object permission that is independent of Global Permissions. It is your practical safety net.&lt;/p&gt;
&lt;h2 id="step-5-break-enhanced-linked-mode"&gt;Step 5: Break Enhanced Linked Mode&lt;/h2&gt;
&lt;p&gt;Follow the supported vCenter 8.x ELM split procedure for your environment. At a high level, the flow is:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Shut down the vCenter being split from the SSO domain.&lt;/li&gt;
&lt;li&gt;From one of the remaining linked vCenters, unregister the powered-off node.&lt;/li&gt;
&lt;li&gt;Power on the vCenter being split.&lt;/li&gt;
&lt;li&gt;Repoint it to a standalone SSO domain.&lt;/li&gt;
&lt;li&gt;Validate that the vCenter no longer shows the other linked vCenters.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The key point for this post is timing: &lt;strong&gt;do not import permissions until the standalone vCenter has its identity source and SSO domain in the final state&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id="step-6-recreate-identity-sources-and-local-sso-objects"&gt;Step 6: Recreate Identity Sources and Local SSO Objects&lt;/h2&gt;
&lt;p&gt;After the vCenter is standalone, log in with the new SSO administrator and recreate or verify:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;AD/LDAP identity sources&lt;/li&gt;
&lt;li&gt;Local SSO users&lt;/li&gt;
&lt;li&gt;Local SSO groups&lt;/li&gt;
&lt;li&gt;Any SSO group nesting used by the exported permissions&lt;/li&gt;
&lt;li&gt;Certificates or trust needed for LDAPS&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Before importing permissions, test that the principal resolves. For example, search for the AD group in the vSphere Client permission picker. If the picker cannot resolve it, the import will not give you meaningful access.&lt;/p&gt;
&lt;h2 id="step-7-dry-run-the-import"&gt;Step 7: Dry-Run the Import&lt;/h2&gt;
&lt;p&gt;Start with a dry run:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;.\&lt;/span&gt;&lt;span class="nb"&gt;Import-VCenterRbac&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;ps1&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;-Server&lt;/span&gt; &lt;span class="n"&gt;vcsa01&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;example&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;com&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;-InDir&lt;/span&gt; &lt;span class="p"&gt;.\&lt;/span&gt;&lt;span class="n"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;\&lt;/span&gt;&lt;span class="n"&gt;vcsa01&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;-GlobalPermissionsCsv&lt;/span&gt; &lt;span class="p"&gt;.\&lt;/span&gt;&lt;span class="n"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;\&lt;/span&gt;&lt;span class="n"&gt;vcsa01&lt;/span&gt;&lt;span class="p"&gt;\&lt;/span&gt;&lt;span class="nb"&gt;global-permissions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;csv&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;-UsePrivateMobForGlobalPermissions&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;-WhatIf&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The import order is:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create or update custom roles.&lt;/li&gt;
&lt;li&gt;Import global permissions if a CSV is provided.&lt;/li&gt;
&lt;li&gt;Import object permissions.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The global permission import uses the vCenter MOB endpoint for &lt;code&gt;AuthorizationService.AddGlobalAccessControlList&lt;/code&gt;. That is why the switch is intentionally named &lt;code&gt;-UsePrivateMobForGlobalPermissions&lt;/code&gt;. I want it to be obvious that this is different from the normal object permission path through &lt;code&gt;AuthorizationManager&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If you only want to restore roles and global permissions first, skip object permissions:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;.\&lt;/span&gt;&lt;span class="nb"&gt;Import-VCenterRbac&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;ps1&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;-Server&lt;/span&gt; &lt;span class="n"&gt;vcsa01&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;example&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;com&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;-InDir&lt;/span&gt; &lt;span class="p"&gt;.\&lt;/span&gt;&lt;span class="n"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;\&lt;/span&gt;&lt;span class="n"&gt;vcsa01&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;-GlobalPermissionsCsv&lt;/span&gt; &lt;span class="p"&gt;.\&lt;/span&gt;&lt;span class="n"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;\&lt;/span&gt;&lt;span class="n"&gt;vcsa01&lt;/span&gt;&lt;span class="p"&gt;\&lt;/span&gt;&lt;span class="nb"&gt;global-permissions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;csv&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;-UsePrivateMobForGlobalPermissions&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;-SkipObjectPermissions&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;-WhatIf&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="step-8-run-the-import"&gt;Step 8: Run the Import&lt;/h2&gt;
&lt;p&gt;Once the dry run looks right, run it without &lt;code&gt;-WhatIf&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;.\&lt;/span&gt;&lt;span class="nb"&gt;Import-VCenterRbac&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;ps1&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;-Server&lt;/span&gt; &lt;span class="n"&gt;vcsa01&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;example&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;com&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;-InDir&lt;/span&gt; &lt;span class="p"&gt;.\&lt;/span&gt;&lt;span class="n"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;\&lt;/span&gt;&lt;span class="n"&gt;vcsa01&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;-GlobalPermissionsCsv&lt;/span&gt; &lt;span class="p"&gt;.\&lt;/span&gt;&lt;span class="n"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;\&lt;/span&gt;&lt;span class="n"&gt;vcsa01&lt;/span&gt;&lt;span class="p"&gt;\&lt;/span&gt;&lt;span class="nb"&gt;global-permissions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;csv&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;-UsePrivateMobForGlobalPermissions&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If you changed principal names during the split, edit &lt;code&gt;global-permissions.csv&lt;/code&gt; before running the import. For example, change:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;OLDSSO\vSphere Admins
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;to:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;CORP\vSphere Admins
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;or whatever the correct identity source now exposes.&lt;/p&gt;
&lt;h2 id="step-9-verify-access"&gt;Step 9: Verify Access&lt;/h2&gt;
&lt;p&gt;Do not stop after the script completes. Verify the permission model from both the API side and the user side.&lt;/p&gt;
&lt;p&gt;Run &lt;code&gt;authz-doctor&lt;/code&gt; again:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/usr/lib/vmware-vpx/scripts/authz-doctor/authz-doctor.py permission_check &amp;gt; /tmp/authz-doctor-permissions-after.txt
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Check Global Permissions in the vSphere Client:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Administration &amp;gt; Access Control &amp;gt; Global Permissions
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then test real logins:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Log out of the SSO administrator account.&lt;/li&gt;
&lt;li&gt;Log in as a user from the restored AD admin group.&lt;/li&gt;
&lt;li&gt;Confirm you can see the expected inventory.&lt;/li&gt;
&lt;li&gt;Confirm you can perform a low-risk administrative action.&lt;/li&gt;
&lt;li&gt;Test at least one non-admin role if you have delegated access.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For object permissions, you can also re-export and compare the count:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;.\&lt;/span&gt;&lt;span class="nb"&gt;Export-VCenterRbac&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;ps1&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;-Server&lt;/span&gt; &lt;span class="n"&gt;vcsa01&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;example&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="py"&gt;com&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;-OutDir&lt;/span&gt; &lt;span class="p"&gt;.\&lt;/span&gt;&lt;span class="n"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;\&lt;/span&gt;&lt;span class="nb"&gt;vcsa01-after&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;Compare-Object&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Import-Csv&lt;/span&gt; &lt;span class="p"&gt;.\&lt;/span&gt;&lt;span class="n"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;\&lt;/span&gt;&lt;span class="n"&gt;vcsa01&lt;/span&gt;&lt;span class="p"&gt;\&lt;/span&gt;&lt;span class="nb"&gt;object-permissions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;csv&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Import-Csv&lt;/span&gt; &lt;span class="p"&gt;.\&lt;/span&gt;&lt;span class="n"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;\&lt;/span&gt;&lt;span class="nb"&gt;vcsa01-after&lt;/span&gt;&lt;span class="p"&gt;\&lt;/span&gt;&lt;span class="nb"&gt;object-permissions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;csv&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;-Property&lt;/span&gt; &lt;span class="n"&gt;Principal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;RoleName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;Propagate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;EntityPath&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Some differences are expected if you intentionally changed principals or cleaned up stale entries. Unexpected missing admin groups are not expected.&lt;/p&gt;
&lt;h2 id="common-gotchas"&gt;Common Gotchas&lt;/h2&gt;
&lt;p&gt;The import cannot fix an identity source that does not exist. Recreate AD/LDAP first.&lt;/p&gt;
&lt;p&gt;Custom role IDs can change. The import script matches role names first because role IDs are not always stable across systems.&lt;/p&gt;
&lt;p&gt;Object permissions can point to objects that no longer exist. The script tries the original managed object reference first and then the inventory path. If neither resolves, review the CSV and decide whether the permission is still needed.&lt;/p&gt;
&lt;p&gt;Solution users are not normal human permissions. If NSX, SRM, Aria, a backup product, or a monitoring tool owns a registration, use that product&amp;rsquo;s supported reconnect or repair procedure instead of blindly restoring stale solution-user permissions.&lt;/p&gt;
&lt;p&gt;Global permissions are broad. Review them carefully before bringing them back into a standalone vCenter.&lt;/p&gt;
&lt;h2 id="references"&gt;References&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://knowledge.broadcom.com/external/article/370062/splitting-enhanced-linked-mode-elm.html"&gt;Broadcom KB 370062 - Splitting Enhanced Linked Mode&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://knowledge.broadcom.com/external/article/369938/using-the-authzdoctor-tool-to-identify-v.html"&gt;Broadcom KB 369938 - Using authz-doctor to identify vCenter permissions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://knowledge.broadcom.com/external/article/407544/vcls-vms-deployment-fails-vcenter-report.html"&gt;Broadcom KB 407544 - Repairing a global permission through the &lt;code&gt;AuthorizationService.AddGlobalAccessControlList&lt;/code&gt; MOB method&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.broadcom.com/xapis/vsphere-web-services-api/latest/vim.AuthorizationManager.html"&gt;vSphere Web Services API - AuthorizationManager&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The goal is not just to preserve a list of permissions. The goal is to preserve access that still resolves, still matches the right role, and still works after each vCenter stands on its own.&lt;/p&gt;</content:encoded></item></channel></rss>