Setting up Local Administrator Password Solution (LAPS)

I decided to spend some time implementing LAPS in my lab as it is Microsoft’s solution to local administrator account password management. Why would I want something like this in my environment? Great question! Most organizations probably use the same password (maybe a slightly modified password based on each client…maybe) that ensures that the people who help manage the workstations have a way to log into the system should the computer lose its network configuration or some other issue where the only way to troubleshoot might he to log into the workstation using the local administrator account.

This is great until you someone such as an insider threat manages to get control of the password to the administrator account and now has a way to laterally move around the network from host to host until they can elevate their account to a domain admin. And at that point we know it is game over.

You might be saying “Boe,WTF?!? You are a PowerShell guy so why are you talking about something like this?”. Well, we are all responsible for securing our environment and this provides a great way to do so. Plus, there are PowerShell commands available to manage this service which makes it doubly awesome! Smile

Download the LAPS Install File and Review

You can find the files available to download from the following site: https://www.microsoft.com/en-us/download/details.aspx?id=46899

Included are some great documents that show how to setup and configure LAPS such as using Group Policy as well as extending the schema for the two (2) new attributes that are required for LAPS. In one of these attributes (ms-Mcs-AdmPwd) on each computer object you will find the password (!) for the local administrator account. Before you become too alarmed, these are called “Confidential Attributes” meaning that the attributes are protected by ACLs which are only accessible by the Domain Admins group and any other group that you specify. Standard users (who have Read access to AD) will not be able to view the attributes data and will only see blank information. Only the computer account can write to this location as well as to the other attribute (ms-Mcs-AdmPwdExpirationTime) which is used to determine if the password has expired and needs to be changed. With this in mind, any group that you provide access to the attributes should be monitored to ensure only those that need access, have access.

Installing LAPS Management

I am going to get things started by installing the management tools on one of my servers which includes the following items:

  • Client UI
  • PowerShell Module
  • GPO Templates

The process for the installation is pretty simple; all I do is double click on the msi file (LAPSx64.msi in this case) and run through the wizard, selecting all of the components for installation.

image

Once that is done, we can then move on to updating the schema by adding the two attributes that we talked about earlier using the AdmPwd.PS module that we just installed. But before we update the schema, now is a great time to review the module!

Reviewing the AdmPwd.PS Module

As mentioned, we can do a lot of our management via the AdmPwd.PS module for PowerShell. Yea, the name of the module probably could have been called LAPS in my own opinion, but that is all right Winking smile

Let’s take a quick look at the available cmdlets on this module.

Get-Command –Module AdmPwd.PS

image

Here we see that there our cmdlet to update the schema is called Update-AdmPwdSchema as well as other cmdlets to locate the password for a particular system, resetting a password and setting some permissions to for a variety of things.

Updating the Schema using PowerShell

Now that we know what commands are available to use, we should move forward in our configuration and get the schema updated so our computer account objects have the required attributes. How do we use this cmdlet? Time to check out the help file to learn what needs to be done.

Get-Help Update-AdmPwdADSchema

image

Well…there really isn’t much here to do at all. We simply just run the command and it should “just work”. Nothing wrong with that at all. The one thing that is a little odd is the lack of a –WhatIf parameter to simulate what would happen if we ran this. How do I know this?

image

Not really a major issue by any means, but typically if a command performs any change then it should use –WhatIf as part of its parameters.

I’ll go ahead and run this while using –Verbose just to see if we happen to have any sort of output.

Update-AdmPwdADSchema –Verbose

image

Whoops! Remember folks, if you are updating the Schema, you must be a member of Schema Admins first! Simply add your account to the group, log out and log back in and make the update.

image

image

No verbose output here, but we do get object output showing that the update was successful! Now we remove our account from Schema Admins and log out and back in and then move on to our next part.

image

Watching out for Extended Rights

The documentation mentions that you should be aware of any group or user that has the All Extended Rights access under an OU which has a computer account as they will be able to read the confidential attribute value meaning that they have access to the password. The accounts/groups that have this permission and do not need them should have it removed to prevent unauthorized access.

We can quickly create a report on what accounts and groups have this by using the Find-AdmPwdExtendedRights cmdlet. To make this even more useful, we can combine the output of Get-ADOrganizationUnit from the ActiveDirectory module and then massage the object that is outputted to see all of the accounts and groups with this permission.

Get-ADOrganizationalUnit -Filter *|Find-AdmPwdExtendedRights -PipelineVariable OU |ForEach{
$_.ExtendedRightHolders|ForEach{
[pscustomobject]@{
OU=$Ou.ObjectDN
Object = $_
}
}
}

image

Optionally, you could filter out System and Domain Admins if you wanted to make locating potential unauthorized accounts and groups easier to locate. In this case, I have nothing that concerns me at the moment but it is something that would be a good scheduled task to run daily to ensure nothing suspicious might be happening.

Installing the Client Side Extensions

Before we go too much deeper into setting up the permissions, we should look at installing the client side extensions on each client. In a larger environment you would probably use something like SCCM to install this on all of the systems. In my case, I am going the group policy route and will configure a GPO that will install the LAPSx64.msi file onto each system.

image

I really didn’t do anything special here other than just point this deployment package to a UNC path that was reachable by everyone on the network.

Once that has been completed and I assigned the GPO to my workstations OU. I proceeded to reboot the client and see what happens in hope that it installs correctly. Of course, that didn’t happen as I had package errors with error codes of %%2 and %%1274

image

Turns out the fix for this was to increase the GPO startup processing time to 30 seconds by going to the Computer Configuration>Administrative Templates>System>Group Policy and locating the Specify startup policy processing wait time and setting the value for this to 30 (seconds). Reboot the client and we now have a successful installation!

image

image

All ready to go now! As of right now, we haven’t actually enabled LAPS to begin setting the local administrator passwords just yet. We just need to work on some extra permissions and configure the group policy to enable and configure how LAPS will set the passwords.

Optional Installation

If you wanted a command line approach to installing the client side extension, you can use one of the following approaches to install it.

x64 machines

msiexec /q /i \\server\share\LAPS.x64.msi

x86 machines

msiexec /q /i \\server\share\LAPS.x86.msi

Deploy and Create an optional local administrator account

msiexec /q /i \\server\share\LAPS.x86.msi CUSTOMADMINNAME=NewLocalAdmin

Configure Permissions for the Computer to Update its Attributes

Next up is to ensure that the systems which will be managed by LAPS will be able to update the new attributes on their active directory computer account object. To make this process as easy as we can, we will make use of the Set-AdmPwdComputerSelfPermission cmdlet which we can assign to the OU where the computer accounts reside at. Using this cmdlet is simple: simply point it towards an OU and it will assign the necessary permissions.

Set-AdmPwdComputerSelfPermission –Identity ManagedWorkstations –Verbose

image

This will ensure that this OU and any sub-OU will assign SELF the ability to update the new attributes that we have added to the computer object.

Unfortunately, there isn’t a Remove-AdmPwdComputerSelfPermission cmdlet that can remove this permission from an OU. So if you need to perform this action, you will have to do it another way.

Granting Rights to User or Groups to Read and Reset the Password

With this completed, out next step is to configure the rights for a user (or members of a group) to have the rights to read the password from the confidential attributes as well as writing to the password expiration date attribute. Note that there are two (2) cmdlets that will set this up:

  • Set-AdmPwdReadPasswordPermission
  • Set-AdmPwdResetPasswordPermission

These cmdlets will allow you to set the permissions on a given OU (or OUs) to delegate the necessary permissions to either view the password or write to the ms-Mcs-AdmPwdExpirationTime attribute which will allow for the resetting of the system’s password.

I am going to grant my WorkstationPwdAdmins the ability to read and reset the password on the computers under the ManagedWorkstation OU.

Set-AdmPwdResetPasswordPermission –Identity ManagedWorkstations –AllowedPrincipals rivendell.local\WorkstationPwdAdmins –Verbose

Set-AdmPwdReadPasswordPermission –Identity ManagedWorkstations –AllowedPrincipals rivendell.local\WorkstationPwdAdmins –Verbose

image

At this point we are pretty much ready to go! All that is left to do is enable LAPS via our GPO and make a couple more configurations to set the password policy and we will be able to give this a spin and see if it works!

Configuring the GPO to Enable and Set Password Policy

First off, we need to ensure that whatever system we are going to be updating the policy on has the AdmPwd.admx file located under C:\Windows\PolicyDefinitions and the AdmPwd.adml under C:\Windows\PolicyDefinitions\en-us folder. That way when we open up the GPO, we can find LAPS under Computer configuration>Administrative Templates.

image

From here I will set the Password Settings first.

image

I’ve opted to keep password complexity at the default of using Upper and Lower case lettings, numbers and special characters. For the Password length and Password age, you should check your domain password policy to ensure that you are not stepping out of bounds. Setting a password length that is shorter than what is allowed will cause the process to fail.

image

Since I do not have a second administrator account that is locally on my systems, I am going to leave this in an non-configured state. By default, LAPS will reset the password on the Administrators account by looking at the well known SID but we do have the option of being able to reset a second administrator account if we choose to do so.

image

Here I want to ensure that if a system has gone longer than the password expiration setting then it will be changed immediately.

image

At this point, I am telling LAPS to begin management of the local administrator account passwords. Once this is set, the next time that group policy refreshes on the local systems, their password will be reset.

Validating that the Password is being Managed

So far, we can see that the password is not being managed by looking for the two attributes from my account which has the necessary rights.

image

I’ll initiate a group policy refresh on the client and then we should see the attributes show up with values.

Invoke-GPUpdate –Computer Client1A –Verbose

After a short wait, we will re-run our ADComputer cmdlet again and see what shows up now.

SNAGHTML1f165a51

My clients are now being managed by LAPS and I can view the password as well with my admin account. So what happens if an account that doesn’t have the rights to view the password tries the same command? Let’s find out!

SNAGHTML1f18e736

While the account can tell when the password expires next, they cannot read the password as this particular account doesn’t have access to the confidential attribute.

So what about that datestamp for the expiration time of the password? How in the world can we read this thing? Simple! We make use of the FromFileTime() method of [DateTime] and supply that string as the parameter and we will  instantly know when the password will expired and be reset.

$Computer = (Get-ADComputer –Identity client1a -prop ms-Mcs-AdmPwd,ms-Mcs-AdmPwdExpirationTime)
[datetime]::FromFileTime($Computer."ms-Mcs-AdmPwdExpirationTime")

image

Of course, there is always an easier way to accomplish things like this in PowerShell and the way here comes courtesy of the Get-AdmPwdPassword cmdlet. The nice thing here is that the password is also converted for us to a more human readable time.

Get-AdmPwdPassword –Computername Client1A

image

 

Forcing a Password Reset

What if something happens and we need to force a password reset on a local system? Yes, there is the fat client that you can use, but we know that every is better in the PowerShell console, right? With the ActiveDirectory module and Set-ADComputer cmdlet,  we can quickly knock out a password reset on 1 or more systems.

The key to this is being able to change the data in the ms-Mcs-AdmPwdExpirationTime attribute. Remember that the value translates to a date down the road that the machine will read upon its group policy refresh and determine if it is time to reset the admin account password. With that in mind,we can just set that value to 0 which will then initiate the process at the next policy refresh.

Set-ADComputer –Identity Client1A –Replace @{"ms-Mcs-AdmPwdExpirationTime"=0}

A quick check of the object shows that it has been set to 0.

image

We aren’t done yet. As I have mentioned a couple of times, this only sets the attribute but doesn’t actually initiate anything until the group policy is refreshed. So with that I will initiate the refresh using Invoke-GPUpdate against the client and we should then see the attribute update with a new expiration time.

image

And now we can see that the password was reset. We can further verify this by comparing it against the previous password that I had shown earlier.

image

Now this is a great approach when you are on a different system where you might not have the AdmPwd.PS module available, but if you do happen to have it, well then you get the benefit of using Reset-AdmPwdPassword cmdlet at your disposal! You can supply a computername and the date when the password should expire (called WhenEffective) and you will have the same results that we had with the previous example with the expectation that you will force a policy refresh after.

Reset-AdmPwdPassword –Computer Client1A –WhenEffective (Get-Date).AddDays(-1)

By specifying yesterdays date, the computer will see that the time has expired and will then begin the process of resetting the password.

You can definitely perform the same actions by using the client tool as we have done in PowerShell but we will still have the same results of needing the policy to be refreshed manually.

image

Personally, I thing that both the UI and the cmdlet in the AdmPwd.PS module should have a way to force policy to refresh (maybe as an additional parameter) and the UI could use a checkbox or something similar. An issue with the UI is that it only works with a single machine at a time, so scaling that out to your enterprise may not work too well.

So that wraps up my post on installing and configuring LAPS in your environment and using PowerShell as a means to accomplish most of that configuration. If haven’t considered a means to keep your local administrator passwords different from one another and need an automated approach, then I would recommend that you give LAPS a try.

References

https://adsecurity.org/?p=1790

https://www.microsoft.com/en-us/download/details.aspx?id=46899

https://technet.microsoft.com/en-us/library/security/3062591.aspx?f=255&MSPPError=-2147217396

This entry was posted in powershell and tagged , , . Bookmark the permalink.

17 Responses to Setting up Local Administrator Password Solution (LAPS)

  1. Aaron says:

    Is it not a good idea to install this on a DC? I read this on another guide “Don’t install the LAPS client on a Domain Controller (and have the LAPS GPO configured at the domain level) since LAPS will start changing the default Administrator account (RID 500) for the domain.”

    Should i setup on standalone server?

    Thanks!

  2. Mohan K says:

    Hello,
    Will i be able to set a one password for more number machines (600+) using laps ?

  3. Mike says:

    Did you manually set the password? On my end the ms-Mcs-AdmPwdExpirationTime changes after following your steps. I then run gpupdate on the client machine, but the password is never automatically changed.

  4. R says:

    I’m trying to understand here. Does LAPS automatically generated the password or you set it up and where? Please help

  5. Keith Eves says:

    Can LAPS administer two local administrator accounts?
    Microsoft give the impression that it can only manage one. We have the default and we create one as part of the build process. It would be useful if it did manage two.

  6. Kevin says:

    IS there any way to set the special characters used?

  7. Thank you. This is a great post on LAPS. I think others might find it important add another detail around access to the password as the owner of a computer account – can often be from delegated creation permissions. The post details the issue and a work around: https://blogs.msdn.microsoft.com/laps/2015/07/17/laps-and-permission-to-join-computer-to-domain/

  8. Thank your for the very in-depth article. When my company deployed LAPS I never knew about the AdmPwd module, so I wrote this simple function for quick extraction of the LAPS-added attributes:
    https://github.com/piotrbanas/PBFunkcje/blob/ENG/get-adminPass.ps1

  9. Meganathan Kumar says:

    i would recommend deploy Admpwd.dll file through SCCM instead of MSI installation, if user uninstalled LAPS MSI, LAPS wouldn’t work. I deployed this solution more than 100K endpoints

    • Boe Prox says:

      Thanks for the feedback! SCCM would be the best choice for a large scale environment but in this case I went with a GPO as SCCM was not readily available. As far as a user being able to uninstall the software, it depends on the level of rights that you are granting them to allow them to uninstall software. Either approach (and there are several) should be carefully considered before beginning to roll out a large scale deployment.

  10. Henry says:

    Wondering your thoughts are on managing password history? When recovering an image based backup we’ve had a mismatch.. password changed after backup!

    • LAPS is not managed any of the password history, you can just fetch the password from LAPS UI console or powershell cmdlet, i’ve set a password backup using task scheduler every day in particular OU container

  11. Pingback: Local Administrator Password Solution with Powershell - shell {&} co

  12. Neil says:

    Thanks so much for such a detailed post on this. I’m planning on deploying LAPS in a month or two, and it’s good to have a write-up on an actual experience rather than just conjecture and TechNet articles.

Leave a comment