Home > other >  Attribute PasswordNeverExpires & UserMayNotChangePassword in New-LocalUser function not working in P
Attribute PasswordNeverExpires & UserMayNotChangePassword in New-LocalUser function not working in P

Time:11-14

Attribute PasswordNeverExpires & UserMayNotChangePassword in New-LocalUser function not working.

These attributes where working until, I restarted the machine. After restarting, I found these functionalities were not working.

I had certain network issues in my computer so, I manually installed the LocalAccount module. Then, I checked the LocalAccount.psm1 file where these attributes where missing. I myself added these attributes but, I am not sure whether its syntactically correct or not.

Initial LocalAccount.psm1 file

function New-LocalUser
{
    [CmdletBinding()]
    [Alias()]
    [OutputType([int])]
    Param
    (
        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   Position=0)]
        [string[]]$Name,

        [Parameter(Mandatory=$false,
                   ValueFromPipelineByPropertyName=$true,
                   Position=1)]
        [string[]]$Computername = "$Env:computername",

        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   Position=2)]
        [ValidateScript({$_.GetType().Name -eq 'SecureString'})]
        [array][system.security.securestring]$Password,

        [Parameter(Mandatory=$false,
                   ValueFromPipelineByPropertyName=$true,
                   Position=3)]
        [string[]]$Description=' ',
    )

    Begin
    {
    }
    Process
    {
    $cred=New-Object -TypeName System.management.automation.pscredential -ArgumentList "null",$Password[0]
    $Plaintextpassword=$cred.GetNetworkCredential().password
    $computer = [ADSI]"WinNT://$($ComputerName[0]),computer"
    $user = $computer.Create("User", "$($Name[0])")
    $user.setpassword("$PlainTextPassword")
    $user.put("Description",$($Description[0]))  
    $user.SetInfo()    
    }
    End
    {
    }
} 

After modification

function New-LocalUser
{
    [CmdletBinding()]
    [Alias()]
    [OutputType([int])]
    Param
    (
        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   Position=0)]
        [string[]]$Name,

        [Parameter(Mandatory=$false,
                   ValueFromPipelineByPropertyName=$true,
                   Position=1)]
        [string[]]$Computername = "$Env:computername",

        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   Position=2)]
        [ValidateScript({$_.GetType().Name -eq 'SecureString'})]
        [array][system.security.securestring]$Password,

        [Parameter(Mandatory=$false,
                   ValueFromPipelineByPropertyName=$true,
                   Position=3)]
        [string[]]$Description=' ',

        [Parameter(Mandatory=$false,
                   ValueFromPipelineByPropertyName=$true,
                   Position=4)]
        [bool]$PasswordNeverExpires,

        [Parameter(Mandatory=$false,
                   ValueFromPipelineByPropertyName=$true,
                   Position=5)]
        [bool]$UserMayNotChangePassword 

    )

    Begin
    {
    }
    Process
    {
    $cred=New-Object -TypeName System.management.automation.pscredential -ArgumentList "null",$Password[0]
    $Plaintextpassword=$cred.GetNetworkCredential().password
    $computer = [ADSI]"WinNT://$($ComputerName[0]),computer"
    $user = $computer.Create("User", "$($Name[0])")
    $user.setpassword("$PlainTextPassword")
    $user.put("Description",$($Description[0])) 
    $user.set("PasswordNeverExpires",$($PasswordNeverExpires))  
    $user.set("UserMayNotChangePassword",$($UserMayNotChangePassword))  
    $user.SetInfo()    
    }
    End
    {
    }
}

Can anyone please check your localaccount.psm1 and suggest me where I went wrong. Thanks in advance.

CodePudding user response:

You need to alter certain bits in the UserFlags property of the user:

if ($UserMayNotChangePassword) {
    # ADS_UF_PASSWD_CANT_CHANGE --> user cannot change password
    $user.UserFlags.value = $user.UserFlags.value -bor 0x40
    $user.SetInfo()
}
if ($PasswordNeverExpires) {
    # ADS_UF_DONT_EXPIRE_PASSWD --> password never expires
    $user.UserFlags.value = $user.UserFlags.value -bor 0x10000
    $user.SetInfo()
}

alternative for the above

$flags = 0
if ($UserMayNotChangePassword) {
    # ADS_UF_PASSWD_CANT_CHANGE --> user cannot change password
    $flags  = 0x40
}
if ($PasswordNeverExpires) {
    # ADS_UF_DONT_EXPIRE_PASSWD --> password never expires
    $flags  = 0x10000
}
# if one or both properties are set
if ($flags) {
    $user.UserFlags.value = $user.UserFlags.value -bor $flags
    $user.SetInfo()
}

These are the values for the ADS_USER_FLAG_ENUM

ADS_UF_SCRIPT                                 = 0x1
ADS_UF_ACCOUNTDISABLE                         = 0x2
ADS_UF_HOMEDIR_REQUIRED                       = 0x8
ADS_UF_LOCKOUT                                = 0x10
ADS_UF_PASSWD_NOTREQD                         = 0x20
ADS_UF_PASSWD_CANT_CHANGE                     = 0x40
ADS_UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED        = 0x80
ADS_UF_TEMP_DUPLICATE_ACCOUNT                 = 0x100
ADS_UF_NORMAL_ACCOUNT                         = 0x200
ADS_UF_INTERDOMAIN_TRUST_ACCOUNT              = 0x800
ADS_UF_WORKSTATION_TRUST_ACCOUNT              = 0x1000
ADS_UF_SERVER_TRUST_ACCOUNT                   = 0x2000
ADS_UF_DONT_EXPIRE_PASSWD                     = 0x10000
ADS_UF_MNS_LOGON_ACCOUNT                      = 0x20000
ADS_UF_SMARTCARD_REQUIRED                     = 0x40000
ADS_UF_TRUSTED_FOR_DELEGATION                 = 0x80000
ADS_UF_NOT_DELEGATED                          = 0x100000
ADS_UF_USE_DES_KEY_ONLY                       = 0x200000
ADS_UF_DONT_REQUIRE_PREAUTH                   = 0x400000
ADS_UF_PASSWORD_EXPIRED                       = 0x800000
ADS_UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION = 0x1000000

BTW. I would make both parameters [switch] instead of [bool] like this:

[switch]$PasswordNeverExpires,
[switch]$UserMayNotChangePassword

so you can either leave them out or add to the New-LocalUser function call

  • Related