Behandelte Themen unter "Handling von Zertifikaten"
Einleitung Zertifikatsverwaltung
2.1Zertifikatsverwaltung mit dem .Net Namespace "System.Security.Cryptography.X509Certificates"
2.1.1X509Certificate2-Klasse
2.1.1.1Ein X509Certificate2-Object erstellen
Beispiel 1a: Auslesen der Zertifikate im lokalen Store mittels dem Zertifikatsprovider
Beispiel 1b: Auslesen der Zertifikate im lokalen Store mittels der .Net-Klasse X509Store
Beispiel 2a: Ein Zertifikatsobjekt aus einer lokalen pfx-Zertifikatsdatei erstellen (Import-Methode)
Beispiel 2b: Ein Zertifikatsobjekt aus einer lokalen pfx-Zertifikatsdatei erstellen (cmdlet: get-pfxcertificate)
2.1.1.2Anwendungen von X509Certificate2
Beispiel 1: Anwenden von Eigenschaften und Methoden auf ein Zertifikatsobjekt
Beispiel 2: Zertifikat aus *.cer Datei importieren und Eigenschaften auslesen
2.2.2X509Store-Klasse
Beispiel 1: Mehrere Klassen des System.Security.Cryptography.X509Certificates-Namespaces im Einsatz
2.2.3Sonstige .Net Klassen
Beispiel 1a: Exportieren eines Zertifikats in eine pfx-Datei (Klasse X509ContentType)
Beispiel 1b: Exportieren aller Zertifikats aus dem Currentuser\my-Store in pfx-Dateien (Klasse X509ContentType)
2.3Zertifikatsverwaltung mit dem Zertifikatsprovider
2.4Zertifikatsverwaltung mit dem Quest QAD-SnapIn
Beispiel 1: Auflisten von Zertifikaten mit QAD (Storelocation: LocalMachine, Store: My)
Beispiel 2: Anzeigen aller Zertifikate im LocalMachineStore
Beispiel 3a Anlage eines zusätzlichen Zertifikatsstores für den "aktuellen Benutzer" mit QAD
Beispiel 3b: Löschen eines zusätzlichen Zertifikatsstores für den "aktuellen Benutzer" mit QAD
Beispiel 4: Exportieren aller Zertifikats aus dem Currentuser\my-Store in pfx-Dateien
Beispiel 5: Ein Zertifikatsobjekt mit einem Quest-cmdlet erstellen
******************************************************************************************************
1 Einleitung
Eine gute Einführung in die Arbeitsweise von Zertifikaten findet man hier:
Unter diesem Kapitel möchte ich erarbeiten, wie man Informationen aus Zertifikaten lesen kann, Zertifikate monitort oder diese im- und exportiert. Dazu gehören detaillierte Fragen wie
- haben meine Rechner die richtigen Zertifikate im richtigen Zertifikatsstore
- sind diese Zertifikate gültig
- wann laufen die Zertifikate ab
- sind Zertifikate gesperrt
- ist die Zertifikatskette überall vorhanden
- welche Fileformate soll man für welchen Einsatzzweck wählen
Viele dieser Aufgaben erledigen sich im Zusammenspiel mit einer in ein ActiveDirectory integrierten Zertifizierungsstelle und der Verwendung von GroupPolicies quasi von alleine. Möchte man aber die Verantwortung einer Zertifizierungsstelle nicht im eigenen Hause tragen, oder kommt über Wirtschaftlichkeitsberechnungen zu dem Schluss sich seine Zertifikate lieber von einer externen CA zu besorgen, so können Powershell und .Net wertvolle Werkzeuge für die Administration und das Monitoring der Zertifikate sein.
Eine Alternative zur manchmal etwas aufwändigen .Net-Schreibweise für dieses Aufgabenspektrum ist der Einsatz der
Dabei handelt es sich um ein kostenloses SnapIn, das unter anderem für den Bereich "X.509 Certificate Management" eine Reihe interessanter cmdlets mitbringt. Einige der Beispiele in diesem Kapitel setzen die Installation dieses SnapIns voraus. Module und SnapIns allgemein habe ich in
Alle cmdlets des SnapIns hat Quest im Adminguide "ActiveRoles_MgmtShellForAD_14_AdminGuide_English.pdf" dokumentiert, der unter dem obigen Questlink downloadbar ist.
Für die "PKI cmdlets" gibt es nocheinmal ein Extra Paper, für das sich der Download durchaus lohnt.
Der Guide umfasst etwa 50 Seiten und gibt in der ersten Hälfte eine meiner Meinung nach sehr gute Einführung über Zertifikate und behandelt im zweiten Teil die PKI-cmdlets.
2 Zertifikatsverwaltung
2.1 Zertifikatsverwaltung mit dem .Net Namespace "System.Security.Cryptography.X509Certificates"
Unter diesem Namespace sind alle Klassen enthalten, die für die .Net -Programmierung mit Zertifikaten benötigt werden
2.1.1 X509Certificate2-Klasse
MSDN:
Möchte man mit bestimmten X509-Zertifikaten arbeiten, so benötigt man aus dem "System.Security.Cryptography.X509Certificates Namespace" entweder die Klasse "X509Certificate" oder "X509Certificate2". Beide Klassen stellen X509-Zertifikat dar und beinhalten Methoden und Eigenschaften für den Umgang mit Zertifikaten.
Die
"The primary difference between the X509Certificate and the X509Certificate2 class is that the private key must reside in the certificate store for the X509Certificate class."
In diesem Kapitel 2.1.1 und seinen Unterkapiteln kümmere ich mich nur um die Klasse X509Certificate2!
2.1.1.1 Ein X509Certificate2-Object erstellen
Powershell bringt auch in der Version 2 nur wenige cmdlets mit, mit denen ein gewohnt einfacher und komfortabler Umgang mit Zertifikaten möglich wäre. Um Objekte der Klasse "X509Certificate2" zu erzeugen, stehen damit folgende Werkzeuge zur Verfügung:
a) Zertifikatsprovider
b) .Net Klassen
c) Powershell cmdlet "Get-PfxCertificate"
Anbei einige Beispiele, die verdeutlichen sollen, wie mit den eben genannten Werkzeugen Zertifikatsobjekte erzeugt werden können.
Beispiel 1: Auslesen der Zertifikate im lokalen Store mittels dem Zertifikatsprovider
$Cert=@()
$Cert=(GCI cert:/localmachine/my | Select -First 1)
$Cert.gettype() | Format-Table Name,BaseType -auto
#Ausgabe
Name BaseType
---- --------
X509Certificate2 System.Security.Cryptography.X509Certificates.X509Certificate
Anmerkung 1: Die Syntax des Zertifikatsprovider ist sicherlich die einfachste. Sein Nachteil liegt in der Beschränkung auf die Stores der lokalen Maschine. Möchte man auf die Stores von anderen Maschinen zugreifen, ist der direkte, aber etwas aufwändigere Aufruf der .Net-Klasse der richtige Ansatz (siehe Beispiel 1b).
Anmerkung 2: Die erste Codezeile
"$Cert=@()"
deklariert $Cert als Array. Sobald $Cert mehr als einen Wert enthält, ist dieser Befehl nicht notwendig. Bei nur einem Wert würde dieser Wert aber nicht ausgegeben werden.
Beispiel 2: Auslesen der Zertifikate im lokalen Store mittels der .Net-Klasse X509Store
Der Vorteil des folgenden Beispiels gegenüber dem vorigen Beispiel 1a) liegt hier in der Remotefähigkeit.
$Cert=@()
$store = New-Object System.Security.Cryptography.X509Certificates.X509Store("\\Dom1Dc01\My","LocalMachine")
$store.Open("ReadOnly")
$Cert=($store.certificates | Select -First 1)
$Cert.gettype() | Format-Table Name,BaseType -auto
#Ausgabe
Name BaseType
---- --------
X509Certificate2 System.Security.Cryptography.X509Certificates.X509Certificate
Beispiel 3: Ein Zertifikatsobjekt aus einer lokalen pfx-Zertifikatsdatei erstellen (Import-Methode)
$Cert=@()
$cert = new-object System.Security.Cryptography.X509Certificates.X509Certificate2
$pfxPass = "PW123"
$certpath="c:\temp\TestCert1.pfx"
$cert.import($certPath,$pfxPass,"Exportable,PersistKeySet")
$cert.gettype() | Format-Table Name, BaseType -auto
#Ausgabe
Name BaseType
---- --------
X509Certificate2 System.Security.Cryptography.X509Certificates.X509Certificate
Anmerkungen zu Beispiel 1c:
- Im Beispiel 1 des
Beispiel 4: Ein Zertifikatsobjekt aus einer lokalen pfx-Zertifikatsdatei erstellen (cmdlet: get-pfxcertificate)
siehe
$Cert=@()
$cert=get-pfxcertificate -filepath 'C:\mycerts\test2.pfx'
$cert.gettype() | Format-Table Name, BaseType -auto
#Ausgabe
Name BaseType
---- --------
X509Certificate2 System.Security.Cryptography.X509Certificates.X509Certificate
Zusammenfassung Beispiele 1 bis 4:
Wie man an der identischen Ausgabe des Typs der Beispiele sieht, enthält die Variable $Cert tatsächlich jeweils ein X509-Zertifikat. Jetzt kann das Zertifikatsobjekt mit einer ganzen Reihen von Eigenschaften und Methoden der X509Certificate2-Klasse behandelt werden.
Das nachfolgende
Ein weiteres ausgearbeitetes Beispiel:
2.1.1.2 Anwendungen von X509Certificate2
Beispiel 1: GetIssuername(), NotAfter, Verify()
$Cert=@()
$Cert=(GCI cert:/localmachine/my | Select -First 1) #vgl. alternativ die Beispiel 1b) und 1c)
$Cert.getissuername() #Methode
$Cert.NotAfter #Eigenschaft
$Cert.Verify() #Methode
#Ausgabe
CN=TestCA1
Samstag, 25. Februar 2113 14:01:04
False
In diesem Beispiel werden die Methoden
- getissuername() - liefert den Namen der Zertifizierungsstelle ab, die das X.509-Zertifikat (v.3) ausgestellt hat
- Verify() - Führt mithilfe von Basisvalidierungsrichtlinien eine Validierung von X.509-Ketten aus
und die Eigenschaft
- Notafter - Ruft das Datum in Ortszeit ab, ab dem ein Zertifikat nicht mehr gültig ist
für das erste Zertifikat im My-Store des Systemaccounts aufgerufen.
Beispiel 2: Zertifikat aus *.cer Datei importieren und Eigenschaften auslesen
In der MSDN befindet sich ein Visualbasic-Programmcode, den ich hier nach Powershell konvertieren möchte. Dieser Code zeigt meiner Meinung nach schön die Möglichkeiten der X509Certificate2 Klasse auf
Der orginal VB-Code befindet sich am Ende des Artikels unter MSDN:
function readFile{
# Einlesen eines Zertifikatfiles in ein Bytearray
param($filename)
$FileStream = New-Object System.IO.FileStream ($filename,[System.IO.FileMode]::Open,[System.IO.FileAccess]::read)
[int]$size = [math]::truncate($filestream.Length)
[byte[]] $data = new-object byte[] $size
$filestream.Read($data, 0, $size) | out-null
return $data
}
function showCertInfo{
param($filename)
$X509 = new-object System.Security.Cryptography.X509Certificates.X509Certificate2
[byte[]] $rawdata=readfile -filename $filename
'Create X509Certificate2 object from .cer file.
$X509.import($rawdata)
#http://msdn.microsoft.com/en-us/library/ms148437.aspx
#X509Certificate2.Import Method (Byte())
"Subject: {1}{0}" -f [Environment]::NewLine,$x509.Subject
"Issuer: {1}{0}" -f [Environment]::NewLine, $x509.Issuer
"Version: {1}{0}" -f [Environment]::NewLine, $x509.Version
"Valid Date: {1}{0}" -f [Environment]::NewLine, $x509.NotBefore
"Expiry Date: {1}{0}" -f [Environment]::NewLine, $x509.NotAfter
"Thumbprint: {1}{0}" -f [Environment]::NewLine, $x509.Thumbprint
"Serial Number: {1}{0}" -f [Environment]::NewLine, $x509.SerialNumber
"Friendly Name: {1}{0}" -f [Environment]::NewLine, $($($x509.PublicKey).Oid).FriendlyName
"Public Key Format: {1}{0}" -f [Environment]::NewLine, $($($x509.PublicKey).EncodedKeyValue).Format($True)
"Raw Data Length: {1}{0}" -f [Environment]::NewLine, $RawData.Length
#"Certificate to string: {1}{0}" -f [Environment]::NewLine, $x509.ToString($True)
#"Certificate to XML String: {1}{0}" -f [Environment]::NewLine, $($($x509.PublicKey).Key).ToXmlString($False)
'Add the certificate to a X509Store.
$store = New-Object System.Security.Cryptography.X509Certificates.X509Store
$store.Open("MaxAllowed")
$store.Add($X509)
$store.close()
}
#Aufruf des Skripts
showCertInfo -filename "c:\mycerts\test.cer"
#Ausgabe
Subject: CN=Karl Napf, CN=Users, DC=Dom1, DC=intern
Issuer: CN=Dom1-CA01, DC=Dom1, DC=intern
Version: 3
Valid Date: 13.05.2011 14:57:07
Expiry Date: 12.05.2012 14:57:07
Thumbprint: CFAC05F46158ABB0BC29D5EC30E10C06B9655B3F
Serial Number: 74E4644900000000005D
Friendly Name: RSA
Public Key Format: 30 82 01 0a 02 82 01 01 00 a8 dc b2 40 ed 27 4f 7d 19 bb 8e af 81 db bd 89 d4 e7 62 50 62 06 aa ec b9 7b 0a b3 73 71 58 1a 96 a3 e1 5e d8 11 f4 e5 c5 9e
80 24 93 4f 57 65 5a 3c 26 9a ce 80 06 9c 4d a0 59 6c 7c 80 5a d3 c7 e7 09 06 df 17 6b 1f b6 94 cf 9b 8a 28 5b 65 b8 28 31 62 54 4e 38 be c5 cc 14 f6 ca 1f e0 2e 4b 66 ac
24 d6 fe 03 75 0c 4c 68 6e c8 d2 7e e5 b8 f8 77 1c 67 18 98 55 a7 49 fa 51 fc e2 a1 ea 5b b6 73 d3 fe 00 91 88 df 81 66 f7 12 e6 9e 70 fa fe a3 79 31 ff ff 87 42 eb 34 9b
af 1b 0e 5e 17 45 5c 5b 1e 40 28 09 da 53 6d 83 09 95 1a 72 6e 91 c8 97 8a a5 91 f5 81 5b ea 58 8a 37 e3 ce a7 77 2f d9 70 86 22 70 cb c0 16 d9 69 6f a6 5e 16 f0 b9 5e c7
b9 6c 1b 06 08 42 e5 9b ad 60 b4 f9 99 59 4b 7b 38 14 70 61 4c ea 33 de c0 fc f1 3a cf c5 1f 6c 08 85 c9 15 0a 03 fe f4 93 f6 59 02 03 01 00 01
Raw Data Length: 2094
Steht kein Cer-Zertifikatsfile zur Verfügung, kann man sich einfach in der MMC -> Zertifikate (certmgr.msc) aus dem Container "Vertrauenswürdige Stammzertifizierungsstellen" ein paar Zertifikate mit "Alle Aufgaben -> Exportieren" exportieren. Dabei ist es egal, ob man als Format DER oder BASE-64 wählt.
Das Beispiel liest in der Function "readfile" eine Zertifikatsdatei im cer-Format in ein Bytearray ein. In der Function "showCertInfo" wird ein das Objekt $x509 aus der Klasse "X509Certificate2" erzeugt und mit der import-Methode mit den Daten aus dem Bytearray befüllt.
Anschliessend werden einige Eigenschaften des Objekts $X509 ausgelesen und ausgegeben.
weitere Links:
Zum Thema "ByteArray" siehe "
Zum Thema "Formatierung" siehe "
2.2.2 X509Store-Klasse
Beispiel 1: Mehrere Klassen des System.Security.Cryptography.X509Certificates-Namespaces im Einsatz
Unter den eben genannten MSDN-Link findet man wieder ein ausführliches Beispiel in VisualBasic zu den Klassen
- X509Store
- X509Certificate2
- X509Certificate2Collection
Dieses MSDN- Beispiel möchte ich ebenfalls nach Powershell konvertieren.
#Step 1
#Create new X509 store called teststore from the local certificate store.
$storename = "teststore"
$storelocation = "Currentuser"
$store = New-Object System.Security.Cryptography.X509Certificates.X509Store($storename,$storelocation)
$store.Open("ReadWrite")
#Step 2
#Create certificates from certificate files.
$certificate1 = new-object System.Security.Cryptography.X509Certificates.X509Certificate2("c:\mycerts\zert1.cer")
$certificate2 = new-object System.Security.Cryptography.X509Certificates.X509Certificate2("c:\mycerts\zert2.cer")
$certificate5 = new-object System.Security.Cryptography.X509Certificates.X509Certificate2("c:\mycerts\zert5.cer")
#Step 3
#Create a collection and add two of the certificates.
$collection = New-object System.Security.Cryptography.X509Certificates.X509Certificate2Collection
$collection.Add($certificate2)
$collection.Add($certificate5)
#Step 4
#Add certificates to the store.
$store.Add($certificate1)
$store.AddRange($collection)
$storecollection = new-object System.Security.Cryptography.X509Certificates.X509Certificate2Collection
$storecollection=$store.certificates
"Store name: {0}" -f $store.Name
"Store location: {0}" -f $store.Location
$x509 =new-object System.Security.Cryptography.X509Certificates.X509Certificate2
foreach($x509 in $storecollection){
$x509.subject
#$storecollection | %{$_.subject #Alternativ
}
#Step 5
#Remove a certificate
$store.Remove($certificate1)
$storecollection2 = new-object System.Security.Cryptography.X509Certificates.X509Certificate2Collection
$storecollection2=$store.certificates
"{1}Store name: {0}" -f $store.Name, [Environment]::NewLine
$x509a =new-object System.Security.Cryptography.X509Certificates.X509Certificate2
foreach($x509a in $storecollection2){
$x509a.subject
#$storecollection | %{$_.subject #alternativ zu foreach
}
#Step 6
#Remove a range of certificates.
$store.RemoveRange($collection)
$storecollection3 = new-object System.Security.Cryptography.X509Certificates.X509Certificate2Collection
$storecollection3=$store.certificates
"{1}Store name: {0}" -f $store.Name, [Environment]::NewLine
If ($storecollection3.Count -eq 0) {
"Store contains no certificates."
}Else{
$x509b =new-object System.Security.Cryptography.X509Certificates.X509Certificate2
foreach($x509b in $storecollection3){
$x509b.subject
#$storecollection3 | %{$_.subject #alternativ zu foreach
} #foreach
} #Endif
#Step 7
#Close the store.
$store.Close()
Stehen keine Cer-Zertifikatsfiles zur Verfügung, kann man sich einfach in der MMC -> Zertifikate (certmgr.msc) aus dem Container "Vertrauenswürdige Stammzertifizierungsstellen" ein paar Zertifikate mit "Alle Aufgaben -> Exportieren" exportieren. Dabei ist es egal, ob man als Format DER oder BASE-64 wählt.
Anmerkungen zum Code:
Step 1)
- Im Kapitel Allgemeines ->
- lautet $storelocation nicht "currentuser", sondern "localmachine", so kann mit $storename = "\\dom1dc01\teststore" auch ein Store auf einer Remotemaschine angelegt werden.
- Die Klasse X509Store ist überladen mit mehreren Konstruktoren. Das Beispiel nutzt den Konstruktor mit dem Parametern Storelocation und des Storenamens.
- Die möglichen Flags der Openmethode findet man unter MSDN:
Step 2)
Hier werden aus *.cer Files Objekte der Klasse X509Certificate2 erstellt. *.cer zeichnen sich dadurch aus, daß Sie keinen privaten Schlüssel besitzen.
Für X509Certificate2-Objekte mit privatem Schlüssel und Passwort muß die Import-Methode zusätzlich benützt werden. Der Import eines Zertifikats aus einer *.pfx Datei (= Zertifikate mit privatem Schlüssel) ist in Beispiel 3 unter
Step 3)
MSDN:
Die Klasse X509Certificate2Collection erstellt ein Array, dessen Elemente einzelne Zertifikate der Klasse X509Certificate2 sind. Mit der
#Codeergänzung
$collection.count
$Collection[1].gettype() | Format-Table Name,BaseType -auto
#Ausgabe
2
Name BaseType
---- --------
X509Certificate2 System.Security.Cryptography.X509Certificates.X509Certificate
Step 4)
- dem in Step 1) erzeugten Objekt $store der Klasse X509Store einige Zertifikatsobjekte hinzugefügt, einmal als einzelnes Zertifikat ($certificate1) und einmal als Range ($Collection bzw. $certificate2 und $certificate5).
- die
Step 5)
- Aus dem Objekt $StoreCollection2 wird ein einzelnes Zertifikat entfernt.
Step 6)
Aus dem Objekt $StoreCollection§ wird ein ein Zertifikatrange ($collection) entfernt.
2.2.3 Sonstige .Net Klassen
Beispiel 1a: Exportieren eines Zertifikats in eine pfx-Datei (Klasse X509ContentType)
Im Beispiel 1c des
$Cert=@()
$cert = (dir cert:\currentuser\my)[0]
$type = [System.Security.Cryptography.X509Certificates.X509ContentType]::pfx
$pass = ConvertTo-SecureString "Hurra" -AsPlainText -Force
$bytes = $cert.export($type, $pass)
[System.IO.File]::WriteAllBytes("c:\mycerts\file.pfx", $bytes)
#aus
#TechNet Blogs > My Nuggets > exporting certificate from user store to PFX using powershell
Diesen Code habe ich in der Technet
Der Import eines Zertifikats aus einer *.pfx Datei ist in Beispiel 3 unter
Beispiel 1b: Exportieren aller Zertifikats aus dem Currentuser\my-Store in pfx-Dateien (Klasse X509ContentType)
$Certs=@()
$certs = (dir cert:\currentuser\my)
$type = [System.Security.Cryptography.X509Certificates.X509ContentType]::pfx
$pass = ConvertTo-SecureString "Hurra" -AsPlainText -Force
$certs | % {
$bytes = $_.export($type, $pass)
if ($_.hasprivatekey){ #nur Zertifikate mit PrivatKey exportieren
[System.IO.File]::WriteAllBytes("c:\mycerts\$($_.subject).pfx", $bytes)
}else{
"{0} hat keinen Privatekey und kann daher nicht in eine pfx-Datei exportiert werden" -f $_.subject
}
}
Der Code exportiert alle Zertifikate mit privatem Schlüssel in das Verzeichnis c:\mycerts. Leider lässt sich nicht steuern, ob alle Zertifikate der Zertifikatskette ebenfalls exportiert werden sollen. Anwendungen, die diese Kette benötigen, kommen mit den so erzeugten PFX-Files leider nicht zurecht.
Mehr Details zum PKCS#12 Standard gibt es unter:
Dieselbe Lösung erreicht man auch über das Quest Active Roles cmdlets "Export-QADCertificate", wie in Beispiel 4 unter
2.3 Zertifikatsverwaltung mit dem Zertifikatsprovider
Wie schon weiter oben beschrieben, bietet der Certificate Provider eine einfache Syntax an, um Objekte der Klasse X509Certificate2 zu erstellen. Das erstellte Objekt ist dasselbe, wie mit der ".Net-Klasse X509Certificate2" und "new-object".
2.4 Zertifikatsverwaltung mit dem Quest QAD-SnapIn
Installation siehe:
Alle QAD-cmdlets mit Beispielen: Powergui - QAD cmdlets reference
Beispiel 1: Auflisten von Zertifikaten mit QAD (Storelocation: LocalMachine, Store: My)
Get-QADLocalCertificateStore My LocalMachine | Get-QADCertificate | Format-Table -autosize
#Ausgabe
IssuedBy IssuedTo ValidFrom ValidTo
-------- -------- --------- -------
Dom1-CA01 DOM1CLI01.Dom1.intern 02.05.2011 05.05.2011
Dom1-CA01 DOM1CLI01.Dom1.intern 26.04.2011 29.04.2011
Dom1-CA01 26.04.2011 25.04.2012
Dom1-CA01 DOM1CLI01.Dom1.intern 26.04.2011 25.04.2012
Dom1-CA01 DOM1CLI01.Dom1.intern 02.05.2011 01.05.2012
Dom1-CA01 DOM1CLI01.Dom1.intern 26.04.2011 25.04.2012
Dom1-CA01 DOM1CLI01.Dom1.intern 02.05.2011 30.05.2011
Dom1-CA01 DOM1CLI01.Dom1.intern 26.04.2011 24.05.2011
Dom1-CA01 DOM1CLI01.Dom1.intern 02.05.2011 01.05.2012
Beispiel 2: Anzeigen aller Zertifikate im LocalMachineStore
Das Skript kennezeichnet alle Zertifikate, bei denen das heutige Datum nicht im Gültigkeitszeitraum des Zertifikats liegt
function getcerts{
param($store,$storelocation)
$certs=Get-QADLocalCertificateStore $store $storelocation | Get-QADCertificate
$certs | foreach {
try{
$ISOlderThanValidfrom=$(get-date)-$($_.validfrom)
$ISOlderThanValidto=$(get-date)-$($_.validto)
$a= "{0,-60} {1:d} {2:d} {3:0} {4:0}" -f $_.issuedto,$_.validfrom,$_.validto,$Store,$storelocation
if ($ISOlderThanValidfrom -lt 0) {
write-host "$a Dieses Zertifikatsbeginn ist noch nicht gültig" -backgroundcolor yellow
}elseif($ISOlderThanValidto -gt 0){
write-host "$a Dieses Zertifikat ist abgelaufen" -backgroundcolor yellow
}else{
write-host $a
} #if
}#try
catch{
}
} #foreach
} #Function
$storelocation="localmachine"
$stores=Get-QADLocalCertificateStore -StoreLocation $storelocation
$stores | foreach {
getcerts $_.name $storelocation
}
Die Funktion getcerts liest alle Zertifikate des übergebenen Stores aus und prüft seine Gültigkeit bezüglich des Gültigkeitzeitraums. Einen anderen Ansatz mit .Net findet man in diesem sehr lesenswerten Artikel der Scripting Guys
Technet - ScriptingGuy:
Beispiel 3a Anlage eines zusätzlichen Zertifikatsstores für den "aktuellen Benutzer" mit QAD
#erfordert die Installation und Registrierung des Quest-SnapIns
$storename = "TestUserStore04"
$storelocation = "Currentuser"
New-QADLocalCertificateStore -storename $storename -storelocation $storelocation
Im Vergleich zu Beispiel 1a, welches dasselbe Ergebnis liefert, ist dieser Weg sicherlich deutlich einfacher zu Skripten
Beispiel 3b: Löschen eines zusätzlichen Zertifikatsstores für den "aktuellen Benutzer" mit QAD
$storename = "TestUserStore03"
$storelocation = "Currentuser"
Remove-QADLocalCertificateStore -storename $storename -storelocation $storelocation
#identisch zu
Get-QADLocalCertificateStore -storename $storename -storelocation $storelocation | Remove-QADLocalCertificateStore
Einen vergleichbaren Code in native .Net habe ich nicht gefunden.
Beispiel 4: Exportieren aller Zertifikats aus dem Currentuser\my-Store in pfx-Dateien
$pw="hello"
Get-QADLocalCertificateStore My|
Get-QADCertificate | %{
Export-QADCertificate $_ -Mode chain -Format Pfx -Password (ConvertTo-SecureString $pw -asplaintext -force) -File c:\MyCerts\$($_.issuedto).pfx} | out-null
Dieselbe Aufgabe lässt sich auch über reines .Net erledigen, wie in Beispiel 1b unter
Die Verwendung des cmdlets "ConvertTo-SecureString" habe ich im Kapitel
Weitere Beispiele für das cmdlet Export-QADCertificate:
Beispiel 5: Ein Zertifikatsobjekt mit einem Quest-cmdlet erstellen
Das Beispiel zeigt den Unterschied bei der Verwendung der QAD-cmdlets und der .Net-Programmierung. Eine Kombination von Objekten, Methoden oder Eigenschaften zwischen beiden Techniken wird also nicht so ohne weiteres funktionieren. (siehe auch Erklärung am Ende des Skripts)
$Cert=@()
$cert=Get-QADLocalCertificateStore My LocalMachine | Get-QADCertificate | select -first 1 | Format-Table -autosize
$cert
$cert.gettype() | Format-Table Name, BaseType -auto
$cert | gm
#Ausgabe
IssuedBy IssuedTo ValidFrom ValidTo
-------- -------- --------- -------
Dom1-CA01 DOM1CLI01.Dom1.intern 02.05.2011 05.05.2011
Name BaseType
---- --------
Object[] System.Array
TypeName: Microsoft.PowerShell.Commands.Internal.Format.FormatStartData
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
...
Auch bei diesem Beispiel enthält die Variable $Cert ein Zertifikatsobject, allerdings keines der Klasse X509Certificate2, sondern der Klasse FormatStartData. Will man das Ergebnis weiterbearbeiten, muss man sich bei Quest und nicht in der MSDN informieren. (siehe: Quest ActiveRoles Management Shell for Active Directory).