Archive for the ‘Windows Server 2016’ Category

Einfacher SNMP Walker in Powershell

15 März 2017

Ein Uraltprotokoll das Simple Network Management Protokoll kurz SNMP gibt es heute immer noch. Teilweise hilft es sogar ganz schnell Informationen zu erhalten, die sonst nur mühsam aus anderen Geräten, z. B. Druckern zu erhalten sind.

Auch im Server 2016 und Windows 10 gibt es standardmäßig eine COM-Bibliothek welche die Kommunikation mit SNMP-Geräten ermöglicht. Die Bibliothek bringt eine Funktion mit Namen GetTree mit. Mittels dieser Funktion kann man auf einen Schlag alle relevanten Informationen erhalten. Dies hilft oft schon einen ersten Eindruck von einem Gerät zu erhalten, man muss lediglich die IP-Adresse kennen. Wichtig zu wissen, die OIDs müssen mit einem führenden Punkt angegeben werden:

$IP = "192.168.1.87"
$SNMP = New-Object -ComObject olePrn.OleSNMP
$SNMP.Open($IP, "public")
$SNMP.GetTree(".1.3.6.1")
$SNMP.Close()

Die Zahl 1.3.6.1 ist quasi eine Art Adresse. Bei einem aktuellen HP-Drucker funktioniert diese 1.3.6.1 die Adresse 1.3.6 allerdings nicht. Interessiert man sich speziell für Managementdaten dann wird man unter 1.3.6.1.2 fündig. Hier eine schöne Auflistung mit RFC-Verweisen, was wo gefunden werden kann: http://www.multinet.de/fileadmin/mib2/. Drucker werden speziell über die OID 1.3.6.1.2.1.43 abgefragt. Auf der Internetseite http://www.alvestrand.no/objectid/ ist die Hierarchie schön erklärt. Darüber kann man dann den Sinn der Zahlen verstehen.

Was kann man mit diesen OIDs und SNMP anstellen? Z. B. kann man einen Reboot eines Druckers im Netz auslösen: https://newyear2006.wordpress.com/2016/07/10/hp-netzwerkdrucker-per-remote-und-reboot-txt-neu-starten-nix-klappt-aber-snmp-bringt-die-lsung/. Man findet z. B. für die OID 1.3.6.1.2.1.43.5.1.1.3 folgenden Eintrag:

{iso(1) identified-organization(3) dod(6) internet(1) mgmt(2) mib-2(1) printmib(43) prtGeneral(5) prtGeneralTable(1) prtGeneralEntry(1) prtGeneralReset(3)}

prtGeneralReset OBJECT-TYPE
-- This value is a type 3 enumeration
SYNTAX INTEGER {
notResetting(3),
powerCycleReset(4), -- Cold Start
resetToNVRAM(5), -- Warm Start
resetToFactoryDefaults(6) -- Reset contents of
-- NVRAM to factory defaults
}
MAX-ACCESS read-write
STATUS current
DESCRIPTION
"Setting this value to `powerCycleReset, `resetToNVRAM, or `resetToFactoryDefaults will result in the resetting of the printer. When read, this object will always have the value `notResetting(3), and a SET of the value `notResetting shall have no effect on the printer. Some of the defined values are optional. However, every implementation must support at least the values `notResetting and resetToNVRAM."

Quelle: http://oid-info.com/get/1.3.6.1.2.1.43.5.1.1.3

Die tatsächliche Quelle in diesem Fall ist aber eine RFC, die RFC 1759, https://tools.ietf.org/html/rfc1759.html. Dadurch, dass es eine RFC ist, wird es natürlich klar, dass es bei dem Script für den Druckreboot nicht um eine HP spezifische OID handelt sondern um eine allgemein gültige OID, welche auch von anderen Druckerherstellern verwendet werden kann. Damit funktioniert der Neustart auch bei anderen Netzwerkdruckern.

Noch ein Hinweise zum Artikel mit dem Druckerreset. Die Angabe des Parameters 4 ist nun auch klar, denn die steht für powerCycleReset, siehe oben die Parameter.

Um einfache Infos zu einem Gerät zu erhalten fragt mein einfach den sysDescr ab. Der sysDescr stellt eine Gerätebeschreibung dar. http://www.alvestrand.no/objectid/1.3.6.1.2.1.1.1.html. Der Aufruf sieht dann so aus:

$snmp.get(".1.3.6.1.2.1.1.1.0")
HP ETHERNET MULTI-ENVIRONMENT

oder noch besser, man fragt mittels Tree nach:

$snmp.GetTree(".1.3.6.1.2.1.1.1")
system.sysDescr.0
HP ETHERNET MULTI-ENVIRONMENT

Dabei ist offensichtlich, dass sich HP nicht an die Vorgabe hält und Versionsinformationen unterdrückt. Das Beispiel zeigt aber auch, dass man einen einzelnen Wert mittels Get() und .0 erhalten kann und bei GetTree() automatisch alles dazugehörige erhält, sogar den Typ.

Mit dieser Information können wir nun auch folgendes schreiben:

$snmp.get("system.sysDescr.0")
HP ETHERNET MULTI-ENVIRONMENT

D. h. man kann nun sprechendere Namen verwenden. Für unser Druckerreset wäre dies:

$snmp.gettree(".1.3.6.1.2.1.43.5.1.1.3")
printmib.prtGeneral.prtGeneralTable.prtGeneralEntry.prtGeneralReset.1
3
$snmp.get("printmib.prtGeneral.prtGeneralTable.prtGeneralEntry.prtGeneralReset.1")
3

Beides mal wird die 3 für notResetting geliefert.

Noch ein Punkt der wichtig ist, um die Rückgaben von GetTree() besser zu verstehen. Es werden immer zwei Arrays zurückgegeben, d. h. zuerst ein Array mit den Namen der OIDs und danach ein Array mit den eigentlichen Werten zu den OIDs. Dies wird deutlich wenn man die verfügbaren Sprachen des Druckers abfragt:

$snmp.gettree("printmib.prtLocalization.prtLocalizationTable.prtLocalizationEntry.
prtLocalizationLanguage")
printmib.prtLocalization.prtLocalizationTable.prtLocalizationEntry.
prtLocalizationLanguage.1.1
printmib.prtLocalization.prtLocalizationTable.prtLocalizationEntry.
prtLocalizationLanguage.1.2
printmib.prtLocalization.prtLocalizationTable.prtLocalizationEntry.
prtLocalizationLanguage.1.3
printmib.prtLocalization.prtLocalizationTable.prtLocalizationEntry.
prtLocalizationLanguage.1.4
printmib.prtLocalization.prtLocalizationTable.prtLocalizationEntry.
prtLocalizationLanguage.1.5
printmib.prtLocalization.prtLocalizationTable.prtLocalizationEntry.
prtLocalizationLanguage.1.6
printmib.prtLocalization.prtLocalizationTable.prtLocalizationEntry.
prtLocalizationLanguage.1.7
printmib.prtLocalization.prtLocalizationTable.prtLocalizationEntry.
prtLocalizationLanguage.1.8
en
es
de
fr
ar
it
pt
nl

In Wahrheit ist es jedoch ein verschachteltes bzw. zweidimensionales Array:

($snmp.gettree(".1.3.6.1.2.1.43.7.1.1.2"))[0]
Der Index [0] ist für einen Zugriff auf ein 2-dimensionales Array unzulässig.
In Zeile:1 Zeichen:1
+ ($snmp.gettree(".1.3.6.1.2.1.43.7.1.1.2"))[0]
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : NeedMultidimensionalIndex

($snmp.gettree(".1.3.6.1.2.1.43.7.1.1.2"))[0,0]
printmib.prtLocalization.prtLocalizationTable.prtLocalizationEntry.
prtLocalizationLanguage.1.1
($snmp.gettree(".1.3.6.1.2.1.43.7.1.1.2"))[1,0]
en

Man erhält zuerst die Namen und in der zweiten Dimension die Werte. Also [0,*] enthält alle Namen und [1,*] enthält alle Werte.

Achso, wie bin ich jetzt von “printmib.prtLocalization.prtLocalizationTable.prtLocalizationEntry.
prtLocalizationLanguage” auf 1.3.6.1.2.1.43.7.1.1.2 gekommen? Auch dazu gibt es eine Funktion:

$snmp.OIDFromString("printmib.prtLocalization.prtLocalizationTable.prtLocalizationEntry.
prtLocalizationLanguage") -join "."
1.3.6.1.2.1.43.7.1.1.2

Jetzt hab ich soviel von den ganzen Zusammenhängen geschwafelt, warum nun nicht am Schluss noch etwas sinnvolles zusammenbauen, z. B. eine Tabelle mit allen sinnvollen Werten?

$e=$SNMP.GetTree(".1.3.6.1")
$d=@()
# umsortieren der Arraystruktur
for($i=0;$i-lt $e.length/2;$i++){$d+=@($e[0,$i], $e[1,$i]) }
$d | out-gridView

Oder noch besser alles mehr powershelllike mit Objekten:

$e=$SNMP.GetTree(".1.3.6.1")
$d=@()
# umsortieren der Arraystruktur
for($i=0;$i-lt $e.length/2;$i++){$d+=[pscustomobject]@{ID=$e[0,$i];Value=$e[1,$i];OID=($snmp.OIDFromString(($e[0,$i])) -join ".")} }
$d | out-gridView

Damit steht dem Erkunden der SNMP-Welt nichts mehr im Wege!

Treiber von Windows 10 im Windows Server 2016 installieren wenn es keine offiziellen Treiber gibt, am Beispiel einer Intel-Netzwerkkarte

7 März 2017

Eigentlich sind sich Windows 10 und Windows Server 2016 recht nahe, je nach Versionsstand von Windows 10. Dennoch gibt es manchmal bei der verwendeten Hardware Einschränkungen in Bezug auf Treiber. In einem aktuellen Fall war in einem Rechner eine Intel I219-V Netzwerkkarte verbaut. Dieser Karte genügt natürlich heutigen Managementansprüchen in Servern nicht unbedingt und deshalb wurde in Server 2016 die Treiberunterstützung für diese Karte unterlassen. Was an dieser Karte aber komisch ist, ist dass es eine Zertifizierung im Windows Server Katalog dafür gibt: https://www.windowsservercatalog.com/item.aspx?idItem=985d89e0-d6d1-b9e0-654c-0209df71a8c7&bCatID=1468.

Was kann man machen um die Karte trotzdem nutzen zu können? Früher ging man her und änderte die zugehörige Treiber-INF-Datei und aktivierte die Windows 10 Treiber für Server 2016. Diese Methode wurde seit Windows Vista Zeiten immer schwieriger. Man benötigt nun passende Zertifikate, damit Änderungen an INF-Dateien autorisiert sind. Man kann aber in Server 2016 noch die bewährte Methode gehen, die Überprüfung der Treibersignatur auszuschalten, dann installiert man einmal die Treiber, ladet und segnet sie ab. Danach aktiviert man wieder die Prüfung der Treibersignaturen. Nun kann man die Geräte mit Windows 10 Treibern unter Windows Server 2016 nutzen.

Für obiges Beispiel beschreibt dieser Blogartikel den Vorgang sehr schön: http://blog.citrix24.com/install-windows-server-2016-core-intel-nuc/.

Hier mache ich aber eine komplette Beschreibung wegen ein paar Besonderheiten und weil oft Blogs im Internet auch verschwinden.

Ermittlung der HardwareID
Fangen wir an die betreffenden Geräte ausfindig zu machen. Normalerweise würden erkannte Netzwerkadapter mittels Get-NetAdapter auftauchen. Aber die Intel I219-V ist nicht dabei. Nun kann man wie im Blogartikel beschrieben mittels

GetWMIObject win32_PNPEntity |select name,deviceid |where {$_.Name match "Ethernet"}

die HardwareID ermitteln, welche

name     : Intel(R) Ethernet Connection I219-V
deviceid : PCI\VEN_8086&DEV_1570&SUBSYS_20638086&REV_21\3&11583659&0&FE

ergibt. Von dieser Info ist die VEN_8086&DEV_1570 von Bedeutung. Im Blogartikel wird noch eine zweite Variante genannt, die bezieht sich auf die WLAN-Karte, welche nicht unter Ethernet zu finden ist, sondern unter Network. Wenn man allerdings unter einem deutschsprachigen Windows diesen Befehl ausführt

GetWMIObject win32_PNPEntity |select name,deviceid |where {$_.Name match "Network"}

dann erscheint nicht die gesuchte Info, sondern

name                                   deviceid
—-                                   ——–
Microsoft Kernel Debug Network Adapter ROOT\KDNIC\0000

weil es Network nicht gibt. Man muss statt dessen nach

GetWMIObject win32_PNPEntity |select name,deviceid |where {$_.Name match "Netzwerkcontroller"}

suchen, um z. B. dieses Ergebnis zu bekommen:

name     : Netzwerkcontroller
deviceid : PCI\VEN_8086&DEV_24F3&SUBSYS_90108086&REV_3A
\4&A711841&0&00E0

Blöd und umständlich so was. Aber wir sind ja auf Server 2016, da gibt es neuere Möglichkeiten Hardwaredinge abzufragen:

Get-PnpDevice -Class Net| select status, friendlyname, instanceid|fl *

status       : OK
FriendlyName : Intel(R) Ethernet Connection I219-V
InstanceId   : PCI\VEN_8086&DEV_1570&SUBSYS_20638086&REV_21\3&11583659&0&FE

status       : Error
FriendlyName : Netzwerkcontroller
InstanceId   : PCI\VEN_8086&DEV_24F3&SUBSYS_90108086&REV_3A
\4&A711841&0&00E0

Prima. Hier sehen wir auch gleich, dass es beim Wirelesscontroller ebenso Probleme gibt, weil dort der Status Error steht. Dies war beim I219-V am Anfang natürlich auch, allerdings sind hier im Beispiel bereits die LAN-Treiber geladen.

Wir müssen uns also nur merken, dass wir anstatt der WMI-Abfrage von Win32_PNPEntity auch direkt Get-PnPDevice –Class Net verwenden können.

Treiber herunterladen und entpacken
Neben der HardwareID benötigen wir auch die passenden Treiber von Windows 10. In diesem Fall waren diese unter https://downloadcenter.intel.com/de/download/ unter dem Stichwort ProWin und ProsetWireless zu finden. Damit man aber mit den Dateien etwas anfangen kann, müssen diese aber entpackt werden. Leider wird es immer mehr zur Unsitte nicht mehr hinzuzuschreiben, wie man Treiber nur entpacken aber nicht installieren kann. Im Zweifel verwendet man 7zip um die Treiber aus den .EXE-Dateien zu extrahieren.

INF-Datei modifizieren
So nun muss man zu den IDs den passenden Treiber finden. Dazu ruft man

Get-ChildItem –Recurse | Select-String –Pattern "VEN_8086&DEV_1570" | group Path | select name

Name
—-
D:\IntelTreiber\PRO1000\Winx64\NDIS62\e1d62x64.inf
D:\IntelTreiber\PRO1000\Winx64\NDIS63\e1d63x64.inf
D:\IntelTreiber\PRO1000\Winx64\NDIS64\e1d64x64.inf
D:\IntelTreiber\PRO1000\Winx64\NDIS65\e1d65x64.inf

auf. Dabei sollte man bereits im Pfad stehen, wo man die Treiber entpackt liegen hat.

Eine Frage ergibt sich, welche Datei man nun bearbeitet? Im konkreten Fall die e1d65x64.inf. Mit den kryptischen Versionen 62, 63, 64 und 65 ist die NDIS-Version gemeint. Windows Server 2016 beherrscht zwar bereits NDIS 6.60 aber ist abwärtskompatibel, deshalb die 65 für Version 6.50. Hier findet man ein paar Infos zu den verschiedenen NDIS-Versionen bei Windowsversionen: https://en.wikipedia.org/wiki/Network_Driver_Interface_Specification.

Man ladet nun die INF-Datei einfach in Notepad, im obigen Beispiel so:

Notepad D:\IntelTreiber\PRO1000\Winx64\NDIS65\e1d65x64.inf

Nun müssen wir uns die Sektionen [Intel.NTamd64.10.0.1] und [Intel.NTamd64.10.0] genauer ansehen. Kurz die 10.0.1 steht für Windows Clientversionen, und 10.0 für Server.

Die Sektionen haben bei INF-Dateien eine besondere Bedeutung. Das lustige ist, dass in der betreffenden INF-Datei nicht nur Windows 10 sondern auch Server 2016 Informationen stehen, ja sogar explizit für die I219-V Netzwerkkarte. Allerdings wurde im für Server entscheidenden Abschnitt die I219-V ausgelassen!

Mehr Infos zu den Herstellerangaben bei INF-Dateien findet man hier, da wird auch der genaue Aufbau der Sektionsnamen beschrieben: https://msdn.microsoft.com/de-de/windows/hardware/drivers/install/inf-manufacturer-section.

Man fügt also unter [Intel.NTamd64.10.0] diesen Eintrag hinzu

%E1570NC.DeviceDesc%            = E1570.10.0.1,       PCI\VEN_8086&DEV_1570
%E1570NC.DeviceDesc%            = E1570.10.0.1,       PCI\VEN_8086&DEV_1570&SUBSYS_00008086
%E1570NC.DeviceDesc%            = E1570.10.0.1,       PCI\VEN_8086&DEV_1570&SUBSYS_00011179

dabei müsste auch

%E1570NC.DeviceDesc%            = E1570,       PCI\VEN_8086&DEV_1570
%E1570NC.DeviceDesc%            = E1570,       PCI\VEN_8086&DEV_1570&SUBSYS_00008086
%E1570NC.DeviceDesc%            = E1570,       PCI\VEN_8086&DEV_1570&SUBSYS_00011179

funktionieren und stellt sogar die sicherere Variante dar.

Treibersignaturprüfung ausschalten
Jetzt kommt der eigentlich wichtigste Punkt. Ohne diesen bekommt man die Sache nicht zum Laufen.

bcdedit /set LOADOPTIONS DISABLE_INTEGRITY_CHECKS
bcdedit /set TESTSIGNING ON
bcdedit /set NOINTEGRITYCHECKS ON

Für diese Änderung muss allerdings der Rechner neu gestartet werden, also

Restart-Computer

Treiber installieren
Nun kommt der spannende Moment, wenn man die Treiber lädt, ob es klappt.

pnputil.exe -i -a D:\IntelTreiber\PRO1000\Winx64\NDIS65\e1d65x64.inf

Wenn dann so was ausgegeben wird, hat alles geklappt:

Microsoft-PnP-Hilfsprogramm

Verarbeitungsinf.:            e1d65x64.inf
Der Treiber konnte auf einem Gerät dieses Systems installiert werden.
Das Treiberpaket wurde erfolgreich hinzugefügt.
Veröffentlichter Name:            oem2.inf

Versuche gesamt:              1
Anzahl erfolgreicher Importe: 1

Abschlussarbeit
Natürlich muss man nun die Treibersignaturprüfung wieder aktivieren.

bcdedit /set LOADOPTIONS ENABLE_INTEGRITY_CHECKS
bcdedit /set TESTSIGNING OFF
bcdedit /set NOINTEGRITYCHECKS OFF

 

Vorsicht mit Get-NetFirewallRule bzw. WMI MSFT_NetFirewallRule-Klasse bei Abfrage der Enabled-Eigenschaft – gilt allgemein bei $True und $False in Powershell

10 Juli 2016

Ein Script welches Windows Firewall Regel-Eigenschaften abfragte funktionierte nicht wie erwartet. Es wurde immer die Enabled Eigenschaft abgefragt aber es kam nicht das erwartete Ergebnis, wurde die Abfrage aber negiert, kam das erwartete Ergebnis heraus! Am Ende stellte es sich heraus, dass die Enabled-Eigenschaften kein klassisches Bool sondern einen String zurückgibt, hier die Story:

Fragen wir zunächst die aktuelle Anzahl von Regeln ab, hier bei einem aktuellen Windows 10:

$r=Get-NetFirewallRule
$r.length
413

Es gibt also 413 Regeln. Nun sollen alle Regeln ermitteln werden, die aktiviert sind:

($r | where enabled -eq $true).length
184

Jetzt sollen alle Regeln ermittelt werden, die nicht aktiviert sind:

($r | where enabled -eq $false).length
0

Die 0 ist jetzt nicht das erwartete Ergebnis, wenn man davon ausgeht, dass es 413 Regeln gibt, davon sind 184 aktiv, dann sollten mehr als 0 inaktiv sein.

Wo liegt das Problem? Das Problem ist, dass bei $True oder $False in Powershell immer True oder False am Bildschirm ausgegeben wird. Man interpretiert einen solchen Wert schnell als Boolean. Aber in diesem Fall hat man es nicht mit einem Boolean zu tun:

$r[0].enabled.pstypenames
Microsoft.PowerShell.Cmdletization.GeneratedTypes.NetSecurity.Enabled
System.Enum
System.ValueType
System.Object

Es ist also ein Aufzählungstyp!

($r | where enabled -eq "True").length
184
($r | where enabled -eq "False").length
229

So macht die Sache mehr Sinn!

Oder man macht die Abfrage über den passenden Typ:

($r| where enabled -eq ([Microsoft.PowerShell.Cmdletization.GeneratedTypes.NetSecurity.Enabled]:
:True)).length
184
($r| where enabled -eq ([Microsoft.PowerShell.Cmdletization.GeneratedTypes.NetSecurity.Enabled]:
:False)).length
229

Übrigens: $true –eq "True" ergibt immer True, auch wenn man $true –eq "irgendwas" setzt! Und $False –eq "False" ergibt immer False, egal mit was verglichen wird, außer $false!

Unterschiede zwischen Windows Funktionen bzw. Features bei der Installation

25 Januar 2016

Microsoft hat es über die letzten Jahre mal wieder geschafft ordentlich Verwirrung zu stiften. Wenn man Windows Funktionen wie z. B. das .NET-Framework installiert, so gibt es zig verschiedene Varianten wie man dies erreichen kann.

In diesem Zusammenhang findet man:

Enable-WindowsOptionalFeature
Install-WindowsFeature
Add-WindowsFeature
dism.exe
pkgmgr.exe

Ein schöne Übersicht welche Variante auf welcher Platform, sogar bis 2016 und Nano-Server verfügbar ist, findet man hier: http://peter.hahndorf.eu/blog/WindowsFeatureViaCmd

Nicht nur, dass es unterschiedliche Aufrufe zur Installation gibt, nein je nach Variante haben die Pakete auch unterschiedliche Namen!

Um nun z. B. das .Net 3.5 Framework zu installieren, verwendet man unter Windows Server 2012:

Install-WindowsFeature –Name NET-Framework-Core

und unter Windows 10:

Enable-WindowsOptionalFeature –Featurename NetFx3

Weitere Beispiele hier: http://blog.ittoby.com/2012/11/installing-net-35-on-windows8server.html

Neue Parameter für New-SelfSignedCertificate

21 August 2015

Per Zufall bin ich heute über eine interessante Sache gestoßen. Bereits mit Windows 8 wurden die PKI-Powershell Cmdlets eingeführt. Mit enthalten ist New-SelfSignedCertificate. Das Problem dabei war, dass das Anwendungsgebiet des Cmdlets wegen fehlender Paramater ziemlich limitiert war.

Als ich heute unter Windows 10 New-SelfSignedCertficate verwendete und mittels TAB-Taste die Parametervervollständigung nutzte, wunderte ich mich nicht schlecht, als auf einmal eine Fülle von unbekannten Parametern auftauchte. Darunter waren so Dinge Extension, KeyUsage, KeyProtection.

Durch die Fülle der Parameter war ich etwas überfordert und mich interessierte vor allem eine komplette Auflistung der Parameter. Wie in Powershell üblich verwendet man dazu Get-Help:

PS > get-help New-SelfSignedCertificate

NAME
    New-SelfSignedCertificate

ÜBERSICHT
    Creates a new self-signed certificate for testing purposes.

SYNTAX
    New-SelfSignedCertificate [-CertStoreLocation <String>] [-CloneCert <Certificate>] [-DnsName <String>] [-Confirm]
    [-WhatIf] [<CommonParameters>]

BESCHREIBUNG
    The New-SelfSignedCertificate cmdlet creates a self-signed certificate for testing purposes. Using the CloneCert

Mmmhh, das war irgendwie nicht das was ich erwartet hatte. OK, vielleicht hilft ein Update der Hilfe, also Update-Help durchgeführt. Leider war das Ergebnis unverändert. Nun noch der Versucht online etwas mehr Infos zu bekommen, mittels

Get-Help New-SelfSignedCertificate –Online

Aber wieder nix. Ganz im Gegenteil, man landet momentan noch auf der Hilfeseite von Windows Server 2012 R2 und Windows 8.1 Hilfe. Mal wieder ein ganz mieses Qualitätsmanagement von Microsoft. Auf der anderen Seite kann man sagen, das ist so gewollt, weil vielleicht doch noch Beta.

Da Powershell wegen seiner flexiblen Innereien so genial ist, gibt es vielleicht noch eine andere Möglichkeit herauszufinden, was Sache ist. Wenn schon Get-Help die falsche Syntax hat, aber die TAB-Vervollständigung die ganzen Parameter kennt, dann kann man diese Parameter sicher auch abfragen. Dem ist tatsächlich so:

PS > $P= get-command New-SelfSignedCertificate
PS > $p.Parameters

Key                         Value
—                         —–
SecurityDescriptor          System.Management.Automation.ParameterMetadata
TextExtension               System.Management.Automation.ParameterMetadata
Extension                   System.Management.Automation.ParameterMetadata
HardwareKeyUsage            System.Management.Automation.ParameterMetadata
KeyUsageProperty            System.Management.Automation.ParameterMetadata
KeyUsage                    System.Management.Automation.ParameterMetadata
KeyProtection               System.Management.Automation.ParameterMetadata
KeyExportPolicy             System.Management.Automation.ParameterMetadata
KeyLength                   System.Management.Automation.ParameterMetadata

Um die Sache etwas übersichtlicher zu machen, verwendet man besser:

PS > $p.Parameters.keys | sort
AlternateSignatureAlgorithm
CertStoreLocation
CloneCert
Confirm
Container
CurveExport
Debug
DnsName
ErrorAction
ErrorVariable
ExistingKey
Extension
FriendlyName
HardwareKeyUsage
HashAlgorithm
InformationAction
InformationVariable
KeyAlgorithm
KeyDescription
KeyExportPolicy
KeyFriendlyName
KeyLength
KeyLocation
KeyProtection
KeySpec
KeyUsage
KeyUsageProperty
NotAfter
NotBefore
OutBuffer
OutVariable
Pin
PipelineVariable
Provider
Reader
SecurityDescriptor
SerialNumber
Signer
SignerPin
SignerReader
SmimeCapabilities
Subject
SuppressOid
TestRoot
TextExtension
Type
Verbose
WarningAction
WarningVariable
WhatIf

Alle fett dargestellten Parameter sind neu hinzugekommene. Wie man sieht, eine ganze Menge. Nun weiß man was es gibt aber welche Parameter kann man konkret füttern? Man kann hergehen und alles ausprobieren. Denn es gibt aktuell keinen einzigen Google Suchtreffer mit z. B. New-SelfsignedCertificate mit KeyUsage: https://www.google.com/search?q=new-selfsigncertificate+keyusage&oq=new-selfsigncertificate+keyusage&aqs=chrome..69i57.7167j0j7&sourceid=chrome&es_sm=93&ie=UTF-8#q=%22new-selfsigncertificate%22+%22keyusage%22
Man kann aber auch nachdenken und entdeckt:

Es kam diese Woche die Server 2016 Technical Preview 3 heraus. Was liegt also näher dort mal die Lage zu checken. Gesagt, getan. Tatsächlich sind hier bei Aufruf von Get-Help die Parameter alle verfügbar:

SYNTAX
New-SelfSignedCertificate [-SecurityDescriptor <FileSecurity>]
[-TextExtension <string[]>] [-Extension <X509Extension[]>] [-HardwareKeyUsage <HardwareKeyUsage[]> {None | SignatureKey | EncryptionKey | GenericKey | StorageKey | IdentityKey}] [-KeyUsageProperty <KeyUsageProperty[]> {None | Decrypt | Sign | KeyAgreement | All}] [-KeyUsage <KeyUsage[]> {None | EncipherOnly | CRLSign | CertSign | KeyAgreement | DataEncipherment | KeyEncipherment | NonRepudiation | DigitalSignature | DecipherOnly}] [-KeyProtection <KeyProtection[]> {None | Protect | ProtectHigh | ProtectFingerPrint}] [-KeyExportPolicy <KeyExportPolicy[]> {NonExportable | ExportableEncrypted | Exportable}] [-KeyLength <int>] [-KeyAlgorithm <string>] [-SmimeCapabilities] [-ExistingKey] [-KeyLocation <string>] [-SignerReader <string>) [-Reader <string>] [-Si gnerPin <securestring>] [-Pin <securestring>] [-KeyDescription <string>] [-KeyFriendlyName <string>] [-Container <string>] [-Provider <string>] [-CurveExport <CurveParametersExportType> {None | CurveParameters | CurveName}] [-KeySpec <KeySpec> {None | KeyExchange | Signature}] [-Type <CertificateType> {Custom | CodeSigningCert | DocumentEncryptionCert | SSLServerAuthentication | DocumentEncryptionCertLegacyCsp}] [-FriendlyName <string>] [-NotAfter <datetime>] [-NotBefore <datetime>] [-SerialNumber <string>] [-Subject <string>] [-DnsName <string[]>] [-Suppressoid <string[]> [-HashAlgorithm <string>] [-AlternateSignatureAlgorithm] [-TestRoot] [-Signer <Certificate>] [-CloneCert <Certificate>] [-CertStoreLocation <string>] [-whatlf] [-Confirm] [<CommonParameters>]

Ja das ist doch mal was.

Es geht noch besser, alle Parameteroptionen die beim Server aufgeführt werden, sind auf Windows 10 auch verfügbar! Ja dann kann man ja was daraus machen.

Eine weitere Hilfe stellt die Implementierung von Vadim Podans dar, welcher bereits früher für eine umfassende PKI-Unterstützung in Powershell gesorgt hat. Er hat in der Powershell Script Gallery bereits ein New-SelfSignedCertificate Skript veröffentlicht: https://gallery.technet.microsoft.com/scriptcenter/Self-signed-certificate-5920a7c6.

So das war es zunächst, sinnvolle Anwendungen kommen bei Gelegenheit…