1

I'm looking to write a script that will change the administrator password on a remote server using PowerShell. The following command will do this

$Admin=[adsi]("WinNT://" + MyServer + "/Administrator, user")
$Admin.SetPassword("NewPassword")

But I would like to be able to hide the "NewPassword" in the script to make it more secure.

So is there a way to save the "NewPassword" to a secure .txt file then be able to use it like this?

$Admin.SetPassword("$secureFile")

The script will be run as a scheduled task.

Enrico Campidoglio
  • 56,676
  • 12
  • 126
  • 154
user1890242
  • 69
  • 1
  • 10
  • 19

1 Answers1

1

Yes, you can use the ConvertTo-SecureString and ConvertFrom-SecureString cmdlets to encrypt the password before saving it to a file on disk.

However, keep in mind that you'll need an encryption key in order to encrypt/decrypt the password using the cmdlets. From the documentation:

If an encryption key is specified by using the Key or SecureKey parameters, the Advanced Encryption Standard (AES) encryption algorithm is used. The specified key must have a length of 128, 192, or 256 bits because those are the key lengths supported by the AES encryption algorithm.

If you don't specify a key, the Windows Data Protection API (DPAPI) will be used for the encryption. This means that the key will be tied to the user account who invoked the cmdlets. Now, if you're running the script as a scheduled job this solution will work just fine.

Here's a couple of scripts that will save and read an encrypted password to an XML file on disk using a generated key:

function Get-SecurePassword {
<#
.Synopsis
    Gets a password stored securely in an XML file.
.Parameter Path
    The path to the XML file to import the password from.
#>
[CmdletBinding()]
param(
    [Parameter(Position=1)]
    [string]$Path = "Password.xml"
)
    if (Test-Path $Path) {
        $cache = Import-Clixml $Path
        $key = [System.Convert]::FromBase64String($cache.Secret)
        $password = $cache.EncryptedPassword | ConvertTo-SecureString -Key $key
        $password
    }
}

function Set-SecurePassword {
<#
.Synopsis
    Stores a password securely in an XML file.
.Parameter Path
    The path to the XML file to export the password to.
#>
[CmdletBinding()]
param(
    [Parameter(Position=1)]
    [string]$Password,
    [Parameter(Position=2)]
    [string]$Path = "Password.xml"
)
    $key = New-StrongPasswordBytes -Length 32
    $textualKey = [System.Convert]::ToBase64String($key)
    $securePassword = $Password | ConvertFrom-SecureString -Key $key
    $cache = New-Object PSObject -Property @{ "EncryptedPassword" = $securePassword; "Secret" = $textualKey }
    $cache.PSObject.TypeNames.Insert(0, "SecurePassword")
    $cache | Export-Clixml $Path
}

function New-StrongPasswordBytes ($length) {
    Add-Type -Assembly System.Web
    $password = [System.Web.Security.Membership]::GeneratePassword($length, $length / 2)
    [System.Text.Encoding]::UTF8.GetBytes($password)
}
Enrico Campidoglio
  • 56,676
  • 12
  • 126
  • 154
  • I think it is important to note that the password to be secured here is obfuscated, but still accessible to anyone that can access the .xml file. Good enough solution for the OP, but not particularly secure. – Prof Von Lemongargle Feb 27 '17 at 21:50