Zum Hauptinhalt springen

Gültigkeitsbereiche (Scopes) von Funktionen

Auch Funktionen haben, genau wie Variablen, einen Gültigkeitsbereich. Technisch gesehen sind Funk-tionen eigentlich nichts weiter als in Variablen gespeicherte Skriptblöcke, die automatisch gestartet wer-den, wenn man Ihren Namen eingibt. Hierzu ein kleines Beispiel:

$ScriptBlock = { 20 * 20 }
$ScriptBlock
> 20 * 20

Im obigen Skript wird ein Skriptblock mit dem Code 20 * 20 in einer Variablen gespeichert. Wenn Sie die Variable ausführen, wird aber nicht der Wert berechnet, sondern nur der Inhalt des Skriptblocks zurückgegeben. Das liegt, wie schon oben erwähnt, daran, dass ein Skriptblock einen Starter benötigt. Sobald Sie einen Ausführungsoperator vor die Variable schreiben, startet Powershell den Skriptblock und gibt das Ergebnis der Berechnung zurück:

$ScriptBlock = { 20 * 20 } 
& $ScriptBlock
> 400

Ein Skriptblock kann also auch aus einer Variablen heraus gestartet werden. Eine Funktion ist faktisch nichts anderes als eine Variable, die einen Skriptblock enthält, der automatisch ausgeführt wird, wenn man sie aufruft.

Weitere Methoden und abschließende Gedanken

Neben den hier vorgestellen Methoden gibt es außerdem natürlich die Möglichkeit, externe Kennwort-Dienste zu verwenden, wie z.B. den Azure Key Vault. Hierfür stellt Microsoft im Azure-Modul eine Reihe von Cmdlets zur Verfügung, die den Zugriff auf Secrets (Kennwörter, private Schlüssel undd Zer-

tifikate) in Azure sehr einfach machen. Ich will auf diese Methode aus zwei Gründen aber nicht im De-tail eingehen - zum einen hat Microsoft das Selber ganz wunderbar beschrieben, zum anderen gibt es hier das Henne-Ei-Problem - der Zugriff auf den Key-Vault benötigt nämlich eine Initiale Authentifizie-rung, die wiederum erfordert, dass man das Kennwort des Azure-Accounts irgendwo gespeichert hat. Und hierfür benötigt man dann eine der oben beschriebenen Methoden. Das grundsätzliche Problem ist also, dass man initial immer einen Weg braucht, um den Start-Schlüssel, mit dem alle folgenden Infor-mationen gesichert sind, abzulegen. Und egal, welche von den oben beschriebenen Methoden Ihnen am Besten zusagt, am Ende landen Sie immer wieder bei der Microsoft Data Protection API. Einzig mit KeePass haben Sie die Möglichkeit, einen zweiten Faktor in die Authentifizierung einzubringen, so dass Sie sich nicht zu 100% auf die DPAPI verlassen müssen. Denn die DPAPI ist eine Abstraktionsschicht, die die Benutzung von kryptografischen Verfahren für Benutzer und (!) Programmierer einfacher ma-chen soll. Aber diese Abstraktion bringt auch Sicherheitsprobleme mit sich, denn sobald man Zugriff auf das Benutzerkonto bekommt, kann man sich auch den Master-Key aneignen. Wenn man Zugriff auf das AD bekommt, kann man sich sogar den Universalschlüssel aneignen, mit dem die Master-Keys aller Benutzer zu entschlüsseln sind. Sollte man deshalb die DPAPI meiden? Wohl kaum, denn wenn der Master-Key in unbefugte Hände gelangt, ist technisch gesehen eh alles hinüber, da alle anderen Sicher-heitsverfahren wie z.B. Public/Private-Key-Verschlüsselung sich ebenfalls auf die DPAPI verlassen. Im Prinzip ist es also egal, welche der obigen Methoden Sie verwenden. Müssen Sie nur ein einziges Cre-dential schützen, ist es also durchaus sinnvoll, das Objekt einfach als CliXml-Datei zu speichern. Müs-sen Sie viele Schlüssel verwenden, nutzen Sie den Windows Key Vault, denn der Zugriff braucht keine zusätzlichen Module oder Abhängigkeiten und ist mit dem .NET-Framework mit wenigen Zeilen Code implementiert. Wenn Sie mehr Sicherheit und Komfort wollen und Ihnen die Abhängigkeiten egal sind, verwenden Sie PoshKeePath. Den Credential Vault würde ich nicht mehr verwenden, da er ein zusätzli-ches Modul oder gute C#-Kenntnisse voraussetzt und keine weiteren Vorteile mit sich bringt.

Index


-Contains 32

-in 32

-is 60

-match 107

-replace 115, 117

-split 116

–notmatch 107

.NET-Framework 88

$Confirmpreference 69

$Error 81, 83

$matches 107

$Maximumerrorcount 81

$Profile 97

$PSCmdlet 54

$WhatIfPreference 69

Mit Powershell Kennwörter in Password Safe speichern

Mit Powershell Kennwörter in Password Safe speichern

Die letzte gute Variante, mit der Kennwörter gespeichert werden können, ist das Open-Soure-Tool Kee-pass.

Keepass ist ein kostenfreier Open-Source Password-Safe mit vielen Funktionen. Keepass verwaltet An-meldeinformationen ähnlich wie das Credential Vault in Dateien oder Datenbanken. Die Datenbanken sind mit AES 256 oder ChaCha20 verschlüsselt. Bei beiden Verfahren handelt es sich um derzeit fak-tisch nicht knackbare symmetrische Algorithmen. Die Datenbanken können auf verschiedene Arten ent-schlüsselt werden, wie z.B. mit Kennwort, mit Fido-Keys, mit Schlüsseldateien oder dem angemeldeten Windows Benutzer. Die einzige Variante, die im Zusammenhang mit Powershell Sinn macht, ist natür-lich die Verschlüsselung über die Benutzeranmeldung (DPAPI). Zusätzlich können Sie die Datenbank mit einer Schlüsseldatei absichern, wodurch Sie faktisch eine Multifaktor-Authentifizierung erreichen.


Um Kennwörter von Powershell aus in Keepass speichern zu können, benö�gen Sie nur das PoshKeePass-Modul aus der Powershell-Gallery. Das Modul bringt alle notwendigen Keepass-Dateien in Form einer .dll mit. Um auf Nummer sicher zu gehen, können Sie die .dlls aber auch durch von Ihnen geprü�e Keepass-Dateien ersetzen. Anschließend können Sie mit dem CmdLet New-KeePassDatabase eine neue Datenbank anlegen.

Install-Module -Name PoshKeePass -Force

# Anlegen einer Datenbank, die über den Windows-Login gesichert ist

New-KeePassDatabase -DatabasePath C:\creds\posh.kdbx -UseNetworkAccount

Wenn Sie eine Datenbank mit Schlüsseldatei erzeugen möchten, müssen Sie die GUI von KeePass be-mühen. Starten Sie dafür KeePass und öffnen die neu erstellte Datenbank über "FIle > Open". Alternativ können Sie über "File > New" die Datenbank auch direkt hier erstellen. Anschließend wählen Sie "File

> Chang Masterkey" und aktivieren die Checkbox "Show Expert Options". Entfernen Sie den Haken bei "Master Password", setzen Sie den Haken bei "Windows User Account" und "Key file / provider" wäh-len Sie den Button "Create".


image

Abbildung 30 - Konfigurieren Sie eine neue Datenbank

Als nächstes geben Sie den Pfad für die Schlüsseldatei an. Die Schlüsseldatei enthält ein zufällig gene-riertes Kennwort. Um echten "Zufall" zu generieren, müssen Sie Text eingeben und die Maus über ein "White Noise"-Bild bewegen.


image

Abbildung 31 - Generieren Sie Entropie für einen echten Zufallswert

Anschließend beenden Sie den Dialog mit OK und beenden den Dialog zum Ändern der Verschlüsse-lung ebenfalls mit OK. Keepass fragt Sie nun, ob Sie die Datenbank sichern wollen. Bestätigen Sie das ebenfalls.Sie können jetzt den Sicherheitsschlüssel drucken, mit dem Sie die Datenbank wiederherstel-len können, sollten die Schlüsseldatei verloren gehen. Anschließend können Sie Keepass beenden.

Nachdem Sie eine Datenbank erstellt haben, können Sie ein Datenbankprofil erzeugen. Das Profil wird im Modul-Ordner als "KeePassConfiguration.xml" angelegt und automatisch beim Laden des Moduls eingelesen. Mit Hilfe einer Konfiguration brauchen Sie beim Erstellen oder Einlesen eines Eintrags nicht jedes mal alle Daten angeben, sondern können einfach auf die Konfiguration verweisen.

Keepass erlaubt es außerdem, Kennwörter zu gruppieren. Mit dem Cmdlet New-KeePassGroup legen Sie Gruppen an. Gruppen verhalten sich wie Ordner und können auch Untergruppen enthalten. Die erste Ebene heißt wie der Name, den Sie Ihrer Datenbank vergeben haben - in unserem Beispiel Posh.


# Anlegen einer Konfiguration

New-KeePassDatabaseConfiguration -DatabaseProfileName Demo `

-DatabasePath C:\creds\posh.kdbx -UseNetworkAccount -Default

# Wenn Sie eine Schlüsseldatei verwendet haben, geben Sie den Pfad mit "KeyPath" an New-KeePassDatabaseConfiguration -DatabaseProfileName Demo -PassThru`

-DatabasePath C:\creds\posh.kdbx -KeyPath C:\creds\posh.key -UseNetworkAccount # Anschließend können Sie auf die Konfiguration verweisen

New-KeePassGroup -DatabaseProfileName Demo -KeePassGroupName Azure `

-KeePassGroupParentPath Posh

# Sie können auch Icons hinterlegen, was für eine rein von Powershell genutzte

# DB aber wenig Sinn macht. Notizen können aber helfen, den Überblick zu behalten New-KeePassGroup -KeePassGroupName O365 -DatabaseProfileName Demo `

-KeePassGroupParentPath Posh -IconName World -Notes "Office 365 Accounts"

Neue Einträge erzeugen Sie mit New-KeePassEntry. Achten Sie darauf, dass das KeePass-Modul als Kennwörter wie üblich nur Secure Strings übernimmt. Wenn Sie eine Gruppe angeben, verwenden Sie den / (Slash), nicht Backslash wie im Dateisystem. PoshKeePass quittiert das sonst mit einer Fehlermel-dung. Zum Abrufen verwenden Sie das Cmdlet Get-KeePassEntry.


$Pw = ConvertTo-SecureString -String "Passw0rd" -AsPlainText -Force

New-KeePassEntry -KeePassEntryGroupPath posh/azure -Title "Global Admin" `

-UserName Admin -KeePassPassword $Pw -Notes "Mein erstes Password" `

-URL portal.azure.de -IconName World -DatabaseProfileName Demo


# Um alle Einträge einer Gruppe abzurufen, geben Sie beim Abruf nur den Gruppennamen an

Get-KeePassEntry -KeePassEntryGroupPath posh/Azure -DatabaseProfileName Demo


# Um einen spezifischen Eintrag zu bekommen, filtern Sie auf den Titel, den Username # oder beides. Sie können die Gruppe auch auslassen.

Get-KeePassEntry -DatabaseProfileName DemoKeyFile -Title "Admin" -UserName Admin


# Sie können sich das Kennwort auch direkt als Klartext ausgeben lassen.

Get-KeePassEntry -KeePassEntryGroupPath posh/Azure -DatabaseProfileName DemoKeyFile`

-Title "Admin" -UserName Admin -AsPlainText


# Wenn Sie ein PSCredential-Objekt brauchen, kann PoshKeePass Ihnen das direkt erzeugen

$cred = Get-KeePassEntry -KeePassEntryGroupPath posh/Azure -Title "Global Admin" `

-DatabaseProfileName DemoKeyFile -UserName Admin -AsPlainText

$cred.Credential


# Zum Löschen verwenden Sie Remove-KeePassentry mit dem -cofirm:false

Get-KeePassEntry -KeePassEntryGroupPath posh/Azure -DatabaseProfileName DemoKeyFile`

-Title "Global Admin" -UserName Admin | Remove-KeePassEntry -Confirm:$false


Credential Vault

Das Credential Vault funktioniert ähnlich wie der Credential Locker, speichert aber alle Anmeldeinfor-mationen in einer Datei, anstatt für jede Anmeldeinformation eine eigene Datei abzulegen. Außerdem kann das Credential Vault Anwendungsspezifisch speichern und ist relativ einfach per .NET aufzurufen, so dass ein Extra-Modul nicht notwendig ist. Man spart sich also im Zweifel eine Extra-Abhängigkeit im Skript. Da es sich um eine Windows-Runtime-Klasse handelt, müssen Sie sie vorher laden.

Legen Sie Initial eine neue Instanz des Typs Windows.Security.Credentials.PasswordVault an. Das Ob-jekt stellt Ihnen anschließend Methoden zur Verfügung, um das Vault zu bearbeiten. Die relevanten Me-thoden sind Retrieve(), RetrieveAll(), FindAllByResource(), FindAllByUserName(), Add() und Remo-ve().


# Laden der Windows Runtime Klasse [Windows.Security.Credentials.PasswordVault,Windows.Security.Credentials, ContentType=WindowsRuntime]

$Vault = New-Object Windows.Security.Credentials.PasswordVault


# Alle Anmeldeinformationen abrufen

$Vault.RetrieveAll()


# Das Vault verwaltet keine Powershell- sondern Password-Credentials. Es muß also # immer erst ein Password-Credential erzeugt werden, dass dann dem Vault

# hinzugefügt werden kann. Der Konstruktor hat 3 Parameter: Resource (Anwendung), # Username und password. Das Passwort wird dabei als Klartext übergeben.

# Anschließend kann das Password-Credential der add()-Methode als Argument # übergeben werden.

$Cred = Get-Credential

$Cred = new-object -Type Windows.Security.Credentials.PasswordCredential `

-ArgumentList 'Powershell','Holger','Passw0rd'

$Vault.Add($Cred)


# Neben Retrieve kann man auch nach einzelnen Anmeldeinformationen suchen:

$Vault.FindAllByUserName('Holger')

$Vault.FindAllByResource('Powershell')

Grundsätzlich ist der Umgang mit dem Credential Vault meiner Meinung nach vorzuziehen, da er ein-fach ist und kein zusätzliches Modul benötigt. Voraussetzung ist mindestens Windows 8 / Server 2012. Egal ob Sie Credential Vault oder Credential Locker verwenden - in jedem Fall arbeitet auch hier im Hintergrund wieder die Microsoft DPAPI. Auch das Credential Vault kann man übrigens mit Vaultcmd. exe auch direkt über die Kommandozeile steuern.


Credential Locker

Wenn Sie Kennwörter im Credential Locker ablegen wollen, verwenden Sie am einfachsten das Powers-hell-Modul CredentialManager aus der Powershell-Gallery, da der Zugriff auch über das .NET-Frame-work nicht trivial ist. Das Modul macht den Zugriff einfach, denn es hat nur 4 Cmdlets und bildet die Funktionalität von cmdkey.exe in Powershell ab.


Cmdlet

Funktion

Get-StrongPassword

Gibt ein zufällig generiertes Kennwort zurück

New-StoredCredential

Speichert Anmeldeinformationen im Credential Manager

Get-StoredCredential

Ruft Anmeldeinformationen aus dem Credential-Manager ab

Remove-StoredCredential

Entfernt Anmeldeinformationen aus dem Credential Manager

Get-StrongPassword hat zwei Parameter, -Length und -NumberOfSpeicalCharacter, über die Eigen-schaften des Kennworts generien kann. Es liefert einen String zurück. New-StoredCredential speichert Credentials in Credential-Manager. Es ist relativ komplex und hat eine Reihe von nichtssagenden Para-metern, deren Namen sich aus den Parametern von cmdkey.exe ergeben.

• Target: Der Computer, für den die Anmeldeinforma�onen gelten. Wird eine Verbindung mit dem Target hergestellt, werden automa�sch die hinterlegten Anmeldeinforma�onen verwendet.

• Username: Der Benutzername, der gespeichert werden soll

• Password: Das Kennwort, das gespeichert werden soll, im Klartext

• SecurePassword: Das Kennwort, das gespeichert werden soll, als Secure String (alterna�v zum Klartext-Kennwort)

• Creden�als: Sta� Benutzername und Kennwort kann auch ein PSCreden�al-Objekt übergeben werden, wie es z.B. Get-Creden�al erzeugt

• Type: Die Art des Kennworts - z.B. DomainPassword oder Generic. Unterstützt werden Generic, DomainPassord und DomainCer�fcate. Alle anderen angebotenen Typen werden von Windows nicht mehr unterstützt

• Persist: Legt fest, ob die Anmeldedaten nur während der aktuellen Anmeldung (Session), dauertha� auf dem gleichen Rechner für alle Sitzungen des Benutzers (LocalMachine) oder auch auf anderen Rechnern der Domäne (Enterprise) sichtbar sein sollen. Wird Enterprise ausgewählt, muß der Benutzer über ein servergespeichertes Profil verfügen, da der Parameter letztlich nur festlegt, ob die Anmeldeinforma�onen unter

$home\AppData\Local\Microso�\Creden�als (LocalMachine) oder unter

$home\AppData\Roaming\Microso�\Creden�als (Enterprise) gespeichert werden.

Hier ein paar Beispiele, wie man New-StoredCredential verwenden kann:


Get-StrongPassword -Length 12 -NumberOfSpecialCharacters 3


# Ein Generisches Credential

$Cred = Get-Credential

New-StoredCredential -Credentials $Cred -Comment User -Persist LocalMachine


# Anmeldeinformationen für Server1.netz-weise.de als Domäneninformationen

# hinterlegen. Wird eine Verbindung zum Zielsystem per NTLM, Kerberos oder als # aushandelbares Auth. hergestellt, werden automatisch die hinterlegten

# Anmeldeinformationen verwendet.

# -Persist Enterprise speichert die Daten im Raomind-Teil es Profils.

New-StoredCredential -Target Server1.netz-weise.de -UserName netz-weise\hans `

-Password $Password -Type DomainPassword -Persist Enterprise

Wenn Sie Anmeldeinformationen zum späteren Abrufen aus einem Powershell-Skript speichern wollen, verwenden Sie am Besten generische Anmeldeinformationen. Da die Anmeldeinformationen auch nicht zum automatischen Verbinden genutzt werden sollen, brauchen Sie auch kein Target angeben. Zum Ab-rufen nutzen Sie Get-StoredCredential. Achten Sie darauf, dass Get-StoredCredential nur nach dem Tar-get filtern kann. Um einen spezifischen Account zu finden, müssen Sie die Ausgabe mit Where-Object filtern. Als Ergebnis erhalten Sie ein Credential-Objekt zurück. Das Löschen mit Remove-Credential ist leicht Buggy und funktioniert nur, wenn für das Credential ein Target angegeben wurde. Da Remove-Credential auch nicht Pipelinefähig ist, müssen Sie zudem Foreach-Object benutzen.


New-StoredCredential -UserName Netz-weise\PoshGeneric -Password "Passw0rd" `

-Comment "Powershell Generic" -Persist LocalMachine # Abfragen des Credentials mit Get-StoredCredential

$Cred = Get-StoredCredential -Type Generic |

Where-Object -FilterScript { $_.username -eq "netz-weise\PoshGeneric" }


# Und löschen - durch die Brust ins Auge Get-StoredCredential -Type Generic |

Where-Object -FilterScript { $_.username -eq "netz-weise\PoshGeneric" } | Foreach-Object -Process { Remove-StoredCredential -Target $_.Target }

Der Vorteil des Credential Locker liegt darin, dass Sie unterschiedliche Anmeldeinformationen an einer Stelle hinterlegen können. Wenn Sie ein Target angeben, kann die Verbindung außerdem automatisch ohne vorherigen Abruf des Credentials stattfinden. Außerdem können die Credential über mehrere Rechner synchronisiert werden, wenn Sie servergespeicherte Profile verwenden.