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.
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
orSecureKey
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)
}