Randomize local admin password on AVD Session Hosts

We got a recommendation from a pentest for this. 
Local Admin accounts on all session hosts are the same. Can you create an option to randomize the local admin password when deploying a session hosts from an image?

-1

Comments (5 comments)

1
Avatar
Stefan Beckmann

Hi Jaco van Rijn (MostWare)
I would like to know where you see the added value of having a solution in Nerdio instead of using Windows LAPS? What is the use case? This will certainly also help the PMs to understand the reason for this request better.
https://www.youtube.com/watch?v=ZGCM-jRsboA

0
Avatar
Jaco van Rijn (MostWare)

Hello, since we are reimaging our session hosts every night (local AD joints) and Some session hosts turn on, others not, It would be great if this could be part of the reimaging actions on the Nerdio side

1
Avatar
Stefan Beckmann
(Edited )

Hi Jaco van Rijn (MostWare), OK, I understand the scenario. Just one more question, should it be possible to recover the password? If you could randomly generate a password, that would make sense at host pool level, wouldn't it?

I could contribute an idea as to how this could perhaps be solved in another way. Windows LAPS works with Microsoft Enra ID but also with Windows Server Active Directory-joined devices. If LAPS is set up, it should be possible to reset the password in a scripted action with the PowerShell command Reset-LapsPassword. This means that we have stored a static password in Nerdio, but during the VM creation process the password would be reset and updated again in the directory. And then with every deplyoment.

Here are a few links:
https://learn.microsoft.com/en-us/windows-server/identity/laps/laps-overview
https://learn.microsoft.com/en-us/powershell/module/laps/reset-lapspassword?view=windowsserver2022-ps

Another idea would be, if you no longer want to know the password, to create a script action that automatically changes the password but does not save it anywhere.

0
Avatar
Stefan Beckmann

Hi Jaco van Rijn (MostWare)

For the second variant, I have created a script that could theoretically be used as a scripted action. I haven't tested it completely, as it's already quite late for me. It simply creates a password and changes it from the user you have to enter above. You can also run the script on a VM and then display the password and test whether you can log in with it.

If you have any questions, just let me know.

Greetings
Stefan

$localAdminAccount = 'myadmin'

# https://learn.microsoft.com/en-us/answers/questions/734475/how-do-i-properly-create-a-random-password-or-init
Function GeneratePassword {
    [CmdletBinding()]
    param(
        [Parameter(ValueFromPipeline=$false)]
            [ValidateRange(1,256)]
            [int]$PWLength = 16,
        [Parameter(ValueFromPipeline=$false)]
            [char[]]$CharSet1 = 'abcdefghiklmnoprstuvwxyz'.ToCharArray(),
        [Parameter(ValueFromPipeline=$false)]
            [char[]]$CharSet2 = 'ABCDEFGHKLMNOPRSTUVWXYZ'.ToCharArray(),
        [Parameter(ValueFromPipeline=$false)]
            [char[]]$CharSet3 = '1234567890'.ToCharArray(),
        [Parameter(ValueFromPipeline=$false)]
            [char[]]$CharSet4 = '!"$%&/()=?}][{@#*+'.ToCharArray(),
        [Parameter(ValueFromPipeline=$false)]
            [ValidateRange(0,256)]
            [int]$Set1Num = 8,
        [Parameter(ValueFromPipeline=$false)]
            [ValidateRange(0,256)]
            [int]$Set2Num = 3,
        [Parameter(ValueFromPipeline=$false)]
            [ValidateRange(0,256)]
            [int]$Set3Num = 2,
        [Parameter(ValueFromPipeline=$false)]
            [ValidateRange(0,256)]
            [int]$Set4Num = 3
    )

        $password =  $CharSet1 | Get-Random -Count $Set1Num
        $password += $CharSet2 | Get-Random -Count $Set2Num
        $password += $CharSet3 | Get-Random -Count $Set3Num
        $password += $CharSet4 | Get-Random -Count $Set4Num

        Write-Verbose "Initial password: $(-join $password)"

        $Password = -join ($password | Get-Random -Count $PWLength)

        Write-Verbose "Final   password: $Password"

        Write-Output $password
}

$LcAlpha = 'abcdefghiklmnoprstuvwxyz'.ToCharArray()
$UcAlpha = 'ABCDEFGHKLMNOPRSTUVWXYZ'.ToCharArray()
$Numbers = '1234567890'.ToCharArray()
$NonAlphaNum = '!"$%&/()=?}][{@#*+'.ToCharArray()

# 8 character password, 5 lower-case, 1 upper-case, 1 digit, 1 punctuation
#GeneratePassword -Verbose 8 $LcAlpha $UcAlpha $Numbers $NonAlphaNum 5 1 1 1

# 16 character password, 8 lower-case, 3 upper-case, 2 digit, 3 punctuation
$passwordString = GeneratePassword
$password = ConvertTo-SecureString -AsPlainText $passwordString

$userAccount = Get-LocalUser -Name $localAdminAccount
$userAccount | Set-LocalUser -Password $password
1
Avatar
Dustin Plank

For us, to avoid needing to handle/manage the Nerdio admin account, we set the account name to match what we have with LAPS already. LAPS then takes care of the rest based it's configuration. Super easy.

Please sign in to leave a comment.