Today we will use PowerCLI to create a local user for ESXi hosts and exclude that user from Lockdown Mode. The challenge is to communicate both with vCenter and ESXi at the same time. As one should know by now using the cmdlet:
Connect-VIServer
by default, PowerCLI will talk to vCenter instead of the ESXi host. Also, you should know which folder you want to give permissions to for the local user. Let’s have a look at how to do it.
I came across two PowerCLI scripts tackling this issue, so I will not reinvent the wheel, but I will walk you through the process from those scripts.
Before we start you need to know what folder(s) you would like to give the local user access to. To find out your folder structure, please connect to your vCenter:
Connect-VIServer vCenterName
Next, execute:
Get-Folder
Furthermore, we need to find out what role we can assign to the newly created local account. To do so let’s execute:
Get-VIRole
NOTE: I used where issystem -eq TRUE to eliminate all the roles I customized and added
NOTE: Below script I found on Github and it is not my script: https://github.com/Magneet/Various_Scripts/blob/master/create_esxi_local_user.ps1
Now, once we have selected our folder and role we can start to put our script together.
First thing let’s provide some information necessary for the process of connecting to vCenter, ESXi, and adding a new user:
$vcenter=Read-Host "Enter vCenter server name"
$Target = Read-Host "Which hosts? (i.e. server*)"
$rootpassword = Read-Host "Enter root Password" -AsSecureString
$accountName = Read-Host "Enter New Username"
$accountDescription = Read-Host "Enter New User description"
$accountPswd = Read-Host "Enter New User Password" -AsSecureString
$rootuser="root"
- Read-Host – will display text and wait for input
- -AsSecureString – will mask input
- $rootuser=”root” – will automatically log as root user. If you don’t want it, change this to $rootuser= Read-Host “Provide user for login”
Alternatively, we can use parameters to collect information:
param(
[parameter(Mandatory = $true)]
[String]$vcenter,
[parameter(Mandatory = $true)]
[String]$Target,
[parameter(Mandatory = $true)]
[String]$accountName,
[parameter(Mandatory = $true)]
[String]$accountDescription,
[parameter(Mandatory = $true)]
[String]$rootuser,
[parameter(Mandatory = $true)]
[String]$rootpassword,
[parameter(Mandatory = $true)]
[String]$accountPswd
)
Once we have that information, we need to establish the connection to vCenter:
$connectedvCenter = $global:DefaultVIServer
if($connectedvCenter.name -ne $vcenter){
Connect-VIServer $vCenter -wa 0 | Out-Null
Write-Host "Connected"
Write-Host " "
}
Now that we are connected to vCenter, let’s list our inventory of ESXi hosts:
$vmhosts = Get-VMHost $Target | Sort Name
Before we can add a new local account we need to disable Lockdown Mode:
foreach($vmhost in $vmhosts){
try {
(get-vmhost $vmhost | get-view).ExitLockdownMode()
write-host "Lockdown disabled for $vmhost" -foregroundcolor green
}
catch {
write-host "can't disable lockdown for $vmhost maybe it's already disabled" - foregroundcolor Red
}
This is the time for us to connect to the ESXi host. As we are connecting with the password provided at the beginning of the script, there is some encryption ongoing here to avoid having passwords in plain text.
connect-viserver -server $vmhost -user $rootuser -password ([Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($rootpassword))) -wa 0 -notdefault | Out-Null
At this stage, we are ready to add a local user. However, it is worth adding a condition to check if the user already exists. This part of the code checks if the account exists and then sets the password and description.
Try {
$account = Get-VMHostAccount -server $vmhost.name -Id $accountName -ErrorAction Stop |
Set-VMHostAccount -server $vmhost.name -Password ([Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($accountPswd))) -Description $accountDescription
}
If the user doesn’t exist, this part of the code will create the new user, set the password, and descritopn.
Catch {
$account = New-VMHostAccount -server $vmhost.name -Id $accountName -Password ([Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($accountPswd))) -Description $accountDescription -UserAccount -GrantShellAccess
}
The creation of a new local user will not work if we won’t give permission to a specific folder and assign the role.
$rootFolder = Get-Folder -server $vmhost.name -Name ha-folder-root
New-VIPermission -server $vmhost.name -Entity $rootFolder -Principal $account -Role admin
Of course, the folder in the example is a custom one, hence we run the Get-Folder
command at the very beginning to find out what folders are in our environment and what role to assign Get-VIRole
.
At this stage only one task left to do, adding the user to the Lockdown Mode exception list:
$HostAccessManager = Get-View -Server $vCenter $vmhost.ExtensionData.ConfigManager.HostAccessManager
$HostAccessManager.UpdateLockdownExceptions($accountName)
Don’t forget to put Lockdown Mode back on and disconnect from the ESXi and vCenter:
Disconnect-VIServer $vmhost.name -Confirm:$false
try {
(get-vmhost $vmhost | get-view).EnterLockdownMode()
write-host "Lockdown enabled for $vmhost" -foregroundcolor green
}
catch {
write-host "can't disable lockdown for $vmhost maybe it's already Enabled?" -foregroundcolor Red}
}
}
Disconnect-VIServer -Confirm:$false
The full script can be found here: https://github.com/Magneet/Various_Scripts/blob/master/create_esxi_local_user.ps1
Please like and share to spread the knowledge in the community.
If you want to chat with me please use Twitter: @AngrySysOps
Join my VMware Knowledge Base Group: https://bit.ly/3w54tbc
Visit my FB page: https://www.facebook.com/AngrySysOps
Subscribe to my channel: https://bit.ly/3vY16CT