Es gibt Szenarien, in denen es sich nicht vermeiden lässt, dass Anmeldeinformationen in einem PowerShell-Skript gespeichert werden müssen. Ein Beispiel wäre ein Skript, das in einem geplanten Task gestartet wird, um Aufräumarbeiten auf einer Datenbank auszuführen, die nur die SQL-Anmeldung mit Benutzername und Kennwort erlaubt.

$username = ‚abtisDatabaseUser‘
$password = ‚Pa$$w0rd‘
$SQLServer = ‘test-db.abtis.local’
$DatabaseName = ‘Test’
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString =
„Server=$SQLServer; Database=$DatabaseName; User ID=$username; Password=$password

In diesem Beispiel ist das Kennwort im Klartext abgelegt, was natürlich ein Sicherheitsrisiko darstellt. Eine gängige Praxis ist es daher, das Kennwort verschlüsselt als „SecureString“ abzulegen. Mit folgenden Befehlen wird der SecureString erstellt und als String (nicht als SecureString-Objekt) ausgegeben:

‚Pa$$w0rd‘ |
    ConvertTo-SecureString -AsPlainText -Force |
    ConvertFrom-SecureString

Das Ergebnis ist eine lange alphanumerische Zeichenkette, die dem verschlüsselten Kennwort entspricht. Um das Passwort zur Laufzeit wieder zu entschlüsseln wird ein PSCredential-Objekt verwendet.

$username = ‚abtisDatabaseUser‘
$secureStringPassword =
    ‚01000000d08c9ddf0115d1118c7a00c04fc297eb01000000ca‘ +
    ‚aba5aa3754e74598ab9a274984d103000000000200000000000‘ +
    ‚3660000c0000000100000009337bd14c10258ec83d9163dc3ac‘ +
    ‚0b2c0000000004800000a000000010000000d4f8630944e85d7‘ +
    ‚323244dae55ebfe2218000000101eed6381bf51a61239fff0b8‘ +
    ‚98550fe71ea83b5b71eab214000000edd347ddc97b99e40f1f1‘ +
    ‚dfcbc27309ab07db224‘ | ConvertTo-SecureString
$credentials =
    New-Object System.Management.Automation.PSCredential -ArgumentList $username, $secureStringPassword
$password = $credentials.GetNetworkCredential().Password

$SQLServer = ‘test-db.abtis.local’
$DatabaseName = ‘Test’ 

$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString =
    „Server=$SQLServer; Database=$DatabaseName; User ID=$username; Password=$password

Wichtig ist an dieser Stelle, dass das Skript von genau demselben Benutzeraccount ausgeführt wird, der auch den SecureString erstellt hat, da der Verschlüsselungsschlüssel an diesen Benutzeraccount gebunden ist. Falls versucht wird, das Kennwort in einem anderen Benutzerkontext zu entschlüsseln, kommt es zu Folgender Fehlermeldung:

ConvertTo-SecureString : Schlüssel ist im angegebenen Status nicht gültig.

Durch diese Maßnahme erscheint das Passwort im Skript nicht mehr im Klartext. Da das Skript allerdings regelmäßig als geplanter Task von einem Dienst ausgeführt wird, der das Passwort entschlüsseln kann, ist es weiterhin noch nicht ausreichend geschützt. Ein potentieller Angreifer könnte, falls er Schreibrechte auf das Skript besitzt, die folgende Zeile hinzufügen, um das entschlüsselte Passwort in eine Datei zu speichern:

$credentials =
    New-Object System.Management.Automation.PSCredential -ArgumentList $username, $secureStringPassword
$password = $credentials.GetNetworkCredential().Password
$password | Out-File .\password.txt # Speichert das entschlüsselte Passwort.

Sobald der geplante Task das nächste Mal ausgeführt wird, wird eine Datei erstellt, die das Passwort im Klartext enthält. Um das zu verhindern gibt es folgende Möglichkeiten um das Skript vor Veränderungen zu schützen:

 

Redakt.: Manuel Batsching