none
Local Administrator Password Reset RRS feed

  • Question

  • Hey Scripting guy!!,

    My customer has a requirement to change the local administrator (built-in) password for all machines on the enterprise every 15 days or so. The password should be randomly generated and also saved to a SQL database.  

    I currently do have a script to achieve this (refer snippet below). However, i am not sure how i can securely write this to a table.

    --------------------------------------------------------------------------------------------------------------------------------------------

    $RandomPswd = Fn_RandomPassword #Function Call to generate random pswd
     If($Debug)
     {

      Write-Host $RandomPswd
     }

     $LocalAdmin =[ADSI]$LocalAdmin = "WinNT://$($env:COMPUTERNAME)/SYSADMIN,User"
     $LocalAdminName = $LocalAdmin.Name

    #Create Connection object to SQL server
     $Connection = New-Object System.Data.SQLClient.SQLConnection("Data Source='<>'; Initial Catalog='ABCD'; Integrated Security=SSPI")
     $Command = New-Object System.Data.SQLClient.SQLCommand
     $Connection.Open()
     $Command.Connection = $Connection
     $Query = @"
    Exec proc_password_Reset '$LocalAdminName','$RandomPswd','$env:COMPUTERNAME','$SerialNumber','$LocalTime','$env:USERNAME'
    "@
     $Command.CommandText = $Query
     $UploadResult = $Command.ExecuteNonQuery()

    #If upload is successfull, $uploadresult will be set to 1. Only on that condition should the password be reset.
     If($UploadResult -eq 1)
     {

      $LocalAdmin.SetPassword($RandomPswd)

     }
     $Connection.Close()
    }

    --------------------------------------------------------------------------------------------------------------------------------------------

     On the SQL server i have a SP which accepts the input and  inserts it into a table. The script is delivered using SCCM software distribution and executes using system creds. I have given domain computers 'execute' permissions on stored proc.

    Is there a better way i can achieve this, rather than using SQLclient on the endpoints?

    Cheers!!

    Thursday, February 5, 2015 11:31 AM

Answers

  • PowerShell has some encryption tools I use to encrypt passwords for storage in text. It allows data to be encrypted/stored/decrypted. In this case, only the user profile that encrypted the data can decrypt it.

    Encrypt:

    $strSvcPwd="????????"
    #$SecurePassword = Read-Host -Prompt "Enter password" -AsSecureString 
    $SecurePassword = $strSvcPwd | ConvertTo-SecureString -AsPlainText -Force
    $SecurePassword | ConvertFrom-SecureString
    Out-File -FilePath EncrypedPassword.txt -inputObject ($SecurePassword | ConvertFrom-SecureString) -Force

    Decrypt:

    #First, get $strSecurePassword from output file EncrypedPassword.txt

    $SecurePassword = $strSecurePassword | ConvertTo-SecureString
    $strTaskUserName = whoami
    $Credentials = New-Object System.Management.Automation.PSCredential -ArgumentList $strTaskUserName, $SecurePassword
    $strSvcPwd = $Credentials.GetNetworkCredential().Password 

    • Marked as answer by Varun C N Tuesday, February 10, 2015 4:41 AM
    Thursday, February 5, 2015 7:41 PM

All replies

  • I would think that this would not be secure if the client is running the script, because it has to send the password over the network in clear text in order to save it in a SQL database.

    -- Bill Stewart [Bill_Stewart]

    Thursday, February 5, 2015 4:17 PM
    Moderator
  • YOu cannot save a password in a database unless the database is encrypted.  If you are running the script on the database server the nework will be secure however, the connection to the database will not unless you request encryption.

    Talks to your DBA about how to secure a database.

    I usually just use an extremely difficult password and save it in an envelope stored in the company safe or secure location then set all workstations to the same password.  It is seldom needed except when we need to repair the workstation.

    There are third party tools that can do what you ask.  It takes more than a few lines of script to do it securely.


    ¯\_(ツ)_/¯

    Thursday, February 5, 2015 7:15 PM
  • PowerShell has some encryption tools I use to encrypt passwords for storage in text. It allows data to be encrypted/stored/decrypted. In this case, only the user profile that encrypted the data can decrypt it.

    Encrypt:

    $strSvcPwd="????????"
    #$SecurePassword = Read-Host -Prompt "Enter password" -AsSecureString 
    $SecurePassword = $strSvcPwd | ConvertTo-SecureString -AsPlainText -Force
    $SecurePassword | ConvertFrom-SecureString
    Out-File -FilePath EncrypedPassword.txt -inputObject ($SecurePassword | ConvertFrom-SecureString) -Force

    Decrypt:

    #First, get $strSecurePassword from output file EncrypedPassword.txt

    $SecurePassword = $strSecurePassword | ConvertTo-SecureString
    $strTaskUserName = whoami
    $Credentials = New-Object System.Management.Automation.PSCredential -ArgumentList $strTaskUserName, $SecurePassword
    $strSvcPwd = $Credentials.GetNetworkCredential().Password 

    • Marked as answer by Varun C N Tuesday, February 10, 2015 4:41 AM
    Thursday, February 5, 2015 7:41 PM
  • This is all well-known, and something I wrote about not too long ago:

    Windows IT Pro: Resetting the Local Administrator Password on Computers

    The trouble is transmitting and storing an admin password from the client to a server over the network. To be secure, it would need to be encrypted when sent over the network and in the database.

    As jrv pointed out, this is not trivial and needs to be done carefully to be secure. If you have need of this capability, I would suggest that it would be simpler and ultimately less expensive to buy a third-party software that does this.


    -- Bill Stewart [Bill_Stewart]

    Thursday, February 5, 2015 9:23 PM
    Moderator
  • @Jerry - I had in fact thought about using SecureStrings and having one password for all machines on the network (~7000). But the customer wanted a dynamic random password. I had to write the function that i use in my script. They want to fly with this :-)

    ------------------------------------------------------------------------------------------------------------

    Function Fn_RandomPassword
     {
      $Pas1 = $Pas2 = $Pas3 = $Password = $pas4= $passwordtemp = $NULL
      $random=new-object System.Random

      ####Generate a new 8 character password, the range is ASCII characters from 33 to 127###

      (1..2|foreach {$Pas1=$Pas1+[char]$random.next(48,57)})
      (1..2|foreach {$Pas2=$Pas2+[char]$random.next(65,90)})
      (1..2|foreach {$Pas3=$Pas3+[char]$random.next(97,122)})
      (1..2|foreach {$Pas4=$Pas4+[char]$random.next(40,47)})

      $passwordtemp = $Pas1+$pas2+$pas3+$pas4
      $Password = [string]::join("",($passwordtemp.ToCharArray()|sort {$Random.Next()}))
      return $Password
      If($Debug)
      {
       Write-host $Password

      }
      
     }

    ------------------------------------------------------------------------------------------------------------

    So the only trouble for me is encryption on the wire and at rest.

    As JRV suggested, i ll talk to my DBA about the encryption at rest part..

    @Bill, that's a nice blog.. got quite a few inputs i can use.. And yes, i ll explore third party tools as well

    Cheers!!

    Friday, February 6, 2015 4:40 AM
  • I don't think you need encrypted storage or transport if you have encrypted at the data element level. A SecureString allows you to encrypt the text before you send it anywhere. Create a SecureString and save it in a text field. Then retrieve it and decrypt when needed. The caveat being only the user profile that encrypted it can decrypt it.
    Friday, February 6, 2015 8:02 PM