none
Unable to set Password Never Expires for Local Administrator Account RRS feed

  • Question

  • Hi,

    I am trying to

    • Set a new password for the built-in workgroup based Local Administrator Account
    • Disable to option: Password Never Expires for workgroup based Local Administrator Account

    I am running this on machines which do not have PowerShell 5.1 as in 5.1 we can easily set the properties using Set-LocalUser

    Below is the Code:

    if(Test-Path C:\Windows\Temp\GPO)
    {
        Remove-Item -Path C:\Windows\Temp\GPO  -Recurse -Force
    }
    Copy-Item -Path .\GPO -Destination C:\Windows\Temp -Recurse -Force
    $ErrorActionPreference = "Stop"
    $newpassword = 'Passw0rd@123'
    # Get Computer Name
    $computername = "$env:computername"
    
    # Create computer object
    $computer = [ADSI]"WinNT://$computerName,computer"
    
    # Get local users list
    $userList = $computer.psbase.Children | Where-Object { $_.psbase.schemaclassname -eq 'user' } 
    
    foreach ($user in $userList)
    {
        # Create a user object in order to get its SID
        $userObject = New-Object System.Security.Principal.NTAccount($user.Name)
        $userSID = $userObject.Translate([System.Security.Principal.SecurityIdentifier])
    
        # Look for local "administrator" SID 
        if(($userSID.Value.substring(0,6) -eq "S-1-5-") -and ($userSID.Value.substring($userSID.Value.Length - 4, 4) -eq "-500"))
        {
            # change password of local administrator account
            $Error.Clear() 
            try
            {
                $user.SetPassword($newpassword)
                $user.UserFlags = 65536 + 64
                $user.SetInfo()
            }
            catch [System.UnauthorizedAccessException]
            {
                Write-Host "Access Denied" -ForegroundColor Red
            }
    
        }
    }

    Default Parameters observed for the Local Administrator Account:

    • Account is Disabled
    • Password Never Expires

    I am referring to the article: Set Password Never Expires for a User Account via Powershell - ADSI

    After Setting: $user.UserFlags = 64 + 65536

    Parameters in effect: - User Cannot Changed Password - Password Never Expires

    After Setting: $user.UserFlags = 64

    Parameters in effect: - User Cannot Changed Password

    After Setting: $user.UserFlags = 65536

    Parameters in effect: - Password never expires

    Please advice on how to remove the checkbox/disable to option : Password never expires.

    Thanks in advance.


    Thanks, Rajiv Iyer



    • Edited by Rajiv IR Tuesday, June 18, 2019 4:03 PM
    Tuesday, June 18, 2019 12:49 PM

Answers

  • Just some clumsy bit manipulation stuff if the OP's really interested in manipulating bits:



    --- Rich Matheisen MCSE&I, Exchange Ex-MVP (16 years)

    Rich - Just use "-band" to clear any bit.

    if($user.UserFlags.Value  -band 64){$user.UserFlags.Value - 64}

    To set just reverse the logic.

    if(-not $user.UserFlags.Value  -band 64){$user.UserFlags.Value + 64}

    To use the bit number:

    $bitNum = 6
    $bitVal =  [math]::Pow(2,$bitNum)  # returns 64


    \_(ツ)_/

    • Marked as answer by Rajiv IR Thursday, June 20, 2019 7:29 AM
    Tuesday, June 18, 2019 4:24 PM
    Moderator
  • Thanks,

    I resolved the problem by specifying:

    $user.UserFlags = 513
    $user.SetInfo()

    I also noticed that to uncheck the password never expires, one must set a new password. In my script I am setting a new password.

    To get the value of the checkboxes with a single setting or a combination of options, one can get the value and apply the same:

    $user.UserFlags.Value 


    Thanks, Rajiv Iyer

    • Marked as answer by Rajiv IR Thursday, June 20, 2019 7:29 AM
    Thursday, June 20, 2019 7:29 AM

All replies

  • Set-LocalUser administrator -AccountNeverExpires -Password newpassword

    help set-localuser -online


    \_(ツ)_/

    • Proposed as answer by Richard MuellerMVP Tuesday, June 18, 2019 2:14 PM
    • Unproposed as answer by Rajiv IR Tuesday, June 18, 2019 2:21 PM
    Tuesday, June 18, 2019 1:27 PM
    Moderator
  • Also, using the -AccountNeverExpires parameter sets only the bit (setting) required. When you assign a numeric value to UserFlags, you step on any existing settings.

    Edit: Also, in order to modify the local Administrator account, your account must be a member of the local Administrators group. By default, if the computer is joined to a domain, the "Domain Admins" group is a member of the local Administrators group, so being a member of "Domain Admins" should be enough.


    Richard Mueller - MVP Enterprise Mobility (Identity and Access)


    Tuesday, June 18, 2019 2:17 PM
  • Just some clumsy bit manipulation stuff if the OP's really interested in manipulating bits:

    "BEGIN WITH ALL 1'S"
    [uint16]$x = 65535          # start with all 1's       
    [Convert]::ToString($x,2)
    
    $x = $x -bor 64             # turn it on (if it's already on, does nothing)
    "ON"
    [Convert]::ToString($x,2)
    
    $x = $x -bxor 64            # if it's on, turn it off; if it's off, turn it on
    "FLIP"
    [Convert]::ToString($x,2)
    
    $x = $x -bxor 64            # if it's on, turn it off; if it's off, turn it on
    "FLIP AGAIN"
    [Convert]::ToString($x,2)
                                # turn it off
    [char[]]$s=[Convert]::ToString($x,2)
    if ($s[9] -eq '1'){$s[9]='0'}
    "OFF"
    $x=[Convert]::ToUInt16(($s -join ''),2)
    [Convert]::ToString($x,2)


    --- Rich Matheisen MCSE&I, Exchange Ex-MVP (16 years)


    Tuesday, June 18, 2019 3:55 PM
  • Hi,

    I am running on the machines which do not have Powershell 5.1 and they are Windows 7 machines


    Thanks, Rajiv Iyer

    Tuesday, June 18, 2019 4:04 PM
  • Hi,

    I am running on the machines which do not have Powershell 5.1 and they are Windows 7 machines



    Thanks, Rajiv Iyer

    Tuesday, June 18, 2019 4:04 PM
  • Hi,

    I am running on the machines which do not have Powershell 5.1 and they are Windows 7 machines



    Thanks, Rajiv Iyer

    Download the local admin module. It works the same and works on W7 systems.

    Either localaccount or LocalAccountManagement

    Install-module LocalAccountManagement

    It works remotely to any system or OS.


    \_(ツ)_/

    Tuesday, June 18, 2019 4:11 PM
    Moderator
  • Just some clumsy bit manipulation stuff if the OP's really interested in manipulating bits:



    --- Rich Matheisen MCSE&I, Exchange Ex-MVP (16 years)

    Rich - Just use "-band" to clear any bit.

    if($user.UserFlags.Value  -band 64){$user.UserFlags.Value - 64}

    To set just reverse the logic.

    if(-not $user.UserFlags.Value  -band 64){$user.UserFlags.Value + 64}

    To use the bit number:

    $bitNum = 6
    $bitVal =  [math]::Pow(2,$bitNum)  # returns 64


    \_(ツ)_/

    • Marked as answer by Rajiv IR Thursday, June 20, 2019 7:29 AM
    Tuesday, June 18, 2019 4:24 PM
    Moderator
  • Using decimal arithmetic for bit manipulation gives me the heebie-jeebies! I envision someone omitting the conditional check and just "adjusting" the value willie-nillie (e.g., turning the bit 'off' more than once).

    Just a FYI: to convert some decimal value into a bit position:

    $dec = 64
    $bit=$null
    
    $bit =  if ( ([math]::Log($dec) / [math]::log(2)) -eq ([int]([math]::Log($dec) / [math]::log(2))) ){
                   [math]::Log($dec) / [math]::log(2)}
            else{
                   Throw "The value '$dec' is not an integer power of 2"
            }


    --- Rich Matheisen MCSE&I, Exchange Ex-MVP (16 years)

    Wednesday, June 19, 2019 1:50 AM
  • There is no decimal arithmetic here.  We are just leveraging logic and math to easily set/reset a bit.  It is done in programming all of the time since the first digital computer system.


    \_(ツ)_/

    Wednesday, June 19, 2019 2:12 AM
    Moderator
  • Omit the test (i.e., turn off the safety) of the bit before you subtract 64. Then subtract 64 again. That doesn't just turn off bit 6 twice.

    I get that computers don't actually do decimal arithmetic, but bit-wise operations such as turning on/off a bit by addition or subtraction, even though it works (if done correctly) just seems wrong. I'll admit to doing it, just as we've all done bit shifts using multiplication/division. Doesn't mean I like it.

    Converting the value to an array of characters and dealing with an indexed "bit" just seems (to me) to make the intent more clear, even if it's slower.


    --- Rich Matheisen MCSE&I, Exchange Ex-MVP (16 years)

    Wednesday, June 19, 2019 3:07 AM
  • Why would we do that?  The code pattern requires the test.  It is not arithmetic it is logic. 

    \_(ツ)_/

    Wednesday, June 19, 2019 11:07 AM
    Moderator
  • Here is a simple example of how safe this is for setting bits.

    function Set-Bit{
        Param(
            $number,
            $BitToSet
        )
        $number -bor ([System.Math]::Pow(2,$BitToSet))
    }
    $v = Set-Bit 0 5
    $v = Set-Bit $v 5
    We can run this as many times as we  like and the bit will only get set once.  We can do a "Clear-Bit" or a "Toggle-Bit" function the same way.


    \_(ツ)_/


    Wednesday, June 19, 2019 11:25 AM
    Moderator
  • Thanks,

    I resolved the problem by specifying:

    $user.UserFlags = 513
    $user.SetInfo()

    I also noticed that to uncheck the password never expires, one must set a new password. In my script I am setting a new password.

    To get the value of the checkboxes with a single setting or a combination of options, one can get the value and apply the same:

    $user.UserFlags.Value 


    Thanks, Rajiv Iyer

    • Marked as answer by Rajiv IR Thursday, June 20, 2019 7:29 AM
    Thursday, June 20, 2019 7:29 AM
  • The original question was how to disable (or set) "Password Never Expires" for a local user. But your solution that you marked as an answer assigns only the setting "Normal Account".

    Assigning an integer value to the UserFlags property will step on any existing settings. The proper procedure would be to toggle or set the specific bits of UserFlags for the settings you want. The -band operator can be used to test for a setting, while the -bxor operator will toggle a setting, and -bor will assign a setting (if it is not already set).

    To assign "Password Never Expires" to a local user account, code similar to below should work:

    $Flags = $User.UserFlags
    If (-Not ($Flags -band 65536))
    {
        $User.UserFlags = $Flags -bxor 65536
        $User.SetInfo()
    }
    

    To clear "Password Never Expires" for a local user account:

    $Flags = $User.UserFlags
    If ($Flags -band 65536)
    {
        $User.UserFlags = $Flags -bxor 65536
        $User.SetInfo()
    }
    

    This leaves any other existing settings unchanged.


    Richard Mueller - MVP Enterprise Mobility (Identity and Access)

    • Proposed as answer by jrvModerator Thursday, June 20, 2019 5:04 PM
    Thursday, June 20, 2019 4:41 PM
  • Even  better.  I forgot about bxor.  It wasn't in PS1 and I think not in PS2.


    \_(ツ)_/


    Thursday, June 20, 2019 5:04 PM
    Moderator
  • I have an old script dated 2011 where I used -bxor, so I believe it worked in PS2. What is annoying is that it seems to be no longer documented. It is mentioned in About_Operators, but it links to About_Comparison_Operators which no longer mentions any of the bitwise operators. It used to. I can now find no documentation.

    Richard Mueller - MVP Enterprise Mobility (Identity and Access)

    Thursday, June 20, 2019 5:56 PM
  • I know that when I first found it existed it didn't work correctly.  In V3 it did work so somewhere it was fixed. Yes the documentation is vague and limited about the bit operators although they are just standard.  Unfortunately many new to scripting never get to learn about bit ops.


    \_(ツ)_/

    Thursday, June 20, 2019 6:01 PM
    Moderator