Archive for the ‘Powershell 5.0’ Category

Wichtige Unterschiede zwischen Powershell 5.1 und Powershell Core 6.x bei Invoke-WebRequest und Invoke-RestMethod

3 Februar 2018

Wenn man Invoke-WebRequest oder Invoke-RestMethod unter Powershell Core 6.x benutzt, sollte man im Zweifel nachfolgendes wissen. Die Namen sind die gleichen aber im Hintergrund haben sich einige Dinge geändert.

Ein sehr ausführlicher Artikel beschreibt die Unterschiede der Web-Cmdlets hier: https://get-powershellblog.blogspot.de/2017/11/powershell-core-web-cmdlets-in-depth.html.

So werden z. B. Header Variablen in Powershell Core strenger überprüft, siehe https://get-powershellblog.blogspot.com/2017/11/powershell-core-web-cmdlets-in-depth.html#L08. Um bestehende Scripte möglichst einfach weiterverwenden zu können, könnte man diese Umgebungsvariable setzen:

$PSDefaultParameterValues[‚Invoke-RestMethod:SkipHeaderValidation‘] = $true
$PSDefaultParameterValues[‚Invoke-WebRequest:SkipHeaderValidation‘] = $true

Damit kann man die strikte Header Prüfung abschalten.

Man muss sich auch bewusst sein, dass nun die Rückgabetypen andere sind als bisher. Man sollte also obigen Artikel unter https://get-powershellblog.blogspot.de/2017/11/powershell-core-web-cmdlets-in-depth.html#L09 genauer studieren. Vor allem kann dadurch teilweise die Logik eines Scripts einen ganz anderen Pfad bekommen!!

Nicht weniger wichtig ist das geänderte Verhalten bei Fehlern und Statuscodes: https://get-powershellblog.blogspot.com/2017/11/powershell-core-web-cmdlets-in-depth.html#L13.

Der zweite Artikel in der Blogserie beschreibt welche Features in Powershell Core 6.x im Vergleich zu Windows Powershell 5.1 nicht mehr vorhanden sind. https://get-powershellblog.blogspot.de/2017/12/powershell-core-web-cmdlets-in-depth.html.

Der wichtigste Punkt dabei ist, dass Invoke-WebRequest und Invoke-RestMethod nun keine file:// bzw. ftp://-Protokollle mehr unterstützen!! Nur noch http:// bzw. https:// werden unterstützt. Der zweite wichtige Punkt ist, dass ParsedHTML nicht mehr unterstützt wird, dieser Punkt ist logisch, weil auf den anderen Platformen kein Internet Explorer mit seinem DOM zur Verfügung steht. Dritter Punkt ist die komplette Abwesenheit von New-WebServiceProxy zur Abfrage von SOAP-Endpunkten.

Ein größeres Thema könnten Zertifikate werden, denn aufgrund der Crossplattform-Unterstützung kommen unterschiedliche Bibliotheken zum Einsatz, wo nicht alle Informationen in .Net Core durchgereicht werden und somit Powershell Core nicht zur Verfügung stehen!

OK den Wegfall von SSL 3.0 sollte zu verschmerzen sein, was allerdings blöd ist, ist der Wegfall der Unterstützung von ServicePointManager https://get-powershellblog.blogspot.com/2017/12/powershell-core-web-cmdlets-in-depth.html#L12. Diese Methode hatte früher hier z. B. Anwendung gefunden: https://newyear2006.wordpress.com/2014/07/26/bei-powershell-ssltls-zertifikate-prfung-einfach-ignorieren/. Eine mögliche Lösung ist allerdings Artikel 3 der Serie bei Parameter –SkipCertificateCheck beschrieben.

Der dritte Teil der Blogserie beschreibt Erweiterungen bzw. neue Features die bei Powershell Core in Invoke-WebRequest und Invoke-RestMethod Einzug gehalten haben https://get-powershellblog.blogspot.de/2017/12/powershell-core-web-cmdlets-in-depth_24.html.

Insgesamt haben die beiden Cmdlets 12 neue Parameter erhalten. Die wahrscheinlich wichtigsten sind die Unterstützung für OAuth Authentifizierung und Link-Parameter um REST-Aufrufen über mehrere Ergebnisseiten folgen zu können.

Darüberhinaus wird es mit Powershell Core 6.1.x noch weitere tolle neue Features geben, vor allem bezogen auf Formulare, siehe hier: https://get-powershellblog.blogspot.de/2018/01/powershell-core-61-web-cmdlets-roadmap.html.

Werbeanzeigen

Windowsupdate.LOG unter Windows 10 lesen

6 Dezember 2015

MS hat mal wieder ein Zwangsverbesserung angestoßen und damit vieles wieder komplizierter gemacht. Konnte man früher einfach die Windowsupdate.LOG-Datei aus C:\Windows im Notepad einsehen, so findet man nun den Hinweis:

Windows Update logs are now generated using ETW (Event Tracing for Windows).
Please run the Get-WindowsUpdateLog PowerShell command to convert ETW traces into a readable WindowsUpdate.log.

For more information, please visit http://go.microsoft.com/fwlink/?LinkId=518345

Ich kann mir den Grund schon denken, warum die Umstellung gemacht wurde, nämlich wegen Performance und der Dateifragmentierung vorzubeugen. Vor allem auf Windows IoT Geräten ist immer zu wenig Platz, also warum dann nicht ein bewährtes Format verenden, welches eh Log-Dateien im Zaum hält.

Als bekennender Powersheller hab ich auch kein Problem mit Commandlets, aber wenn dann weite Teile der daraus erzeugten Log-Datei dann so aussieht?

1601.01.01 01:00:00.0000000 1040  13164                 Unknown( 10): GUID=fceb5510-7e12-22d8-8d1b-e6a079483552 (No Format Information found).
1601.01.01 01:00:00.0000000 1040  13164                 Unknown( 26): GUID=464bbb57-7e12-b0a1-8d1b-e6a079483552 (No Format Information found).
1601.01.01 01:00:00.0000000 1040  13164                 Unknown( 10): GUID=fceb5510-d1b3-b0a1-23ef-338952442d14 (No Format Information found).

Wo ist hier der Informationsgehalt?

Wenn es nur Teile betrifft, kann man sich mittels dieses Aufrufs eine einfachere Update.Log erstellen:

Get-Content "$env:USERPROFILE\Desktop\Windowsupdate.log"|Select-String -Pattern "1601.01.01 01:00:00.0000000*" -NotMatch |Set-Content "$env:USERPROFILE\Desktop\Windowsupdate_Clean.log"

Damit erhält man die unsinnigen Fragmente ausgefiltert und die relevanten Daten in Windowsupdate_Clean.log gespeichert. Hier bei den Kommentaren lassen sich einige zum Thema aus: https://technet.microsoft.com/en-us/library/mt238376.aspx.

Leider hat auch Windows 10 V1511 das Problem mit den falschen bzw. unnötigen LOG-Einträgen.

Wer jetzt denkt, er wäre clever und könnte direkt die Inhalte aus den EWT-Dateien auslesen, denn schließlich gibt es ja noch die Funktion Get-WinEvent, welche EWT-Dateien lesen kann, wird ernüchtert feststellen, dass dem nicht so ist. Der Inhalt der mittels EWT erfassten Daten wird in Dateien mit der Endung .ETL gespeichert.

Beim Aufruf von z. B.

Get-WinEvent -Path C:\Windows\logs\WindowsUpdate\WindowsUpdate.20151206.160438.596.1.etl -Oldest

bekommt man genauso das belanglose Geschwafel wie in der erzeugten Windowsupdate.LOG-Datei. Ist das womöglich ein genereller Bug?

Ein weiterer Artikel zum Format und was man damit machen kann und wo auch auf den Symbolserver eingeht: http://blogs.technet.com/b/charlesa_us/archive/2015/08/06/windows-10-windowsupdate-log-and-how-to-view-it-with-powershell-or-tracefmt-exe.aspx.

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…

Umgang mit verschiedenen Versionen von Powershellmodulen und Ermittlung von Unterschieden

30 Juli 2015

Microsoft hat mit Veröffentlichung von Windows 10 auch neue Cmdlets für Powershell eingeführt. Bei Windows 10 Pro und vergleichbaren Versionen, wo der Client Hyper-V enthalten ist, gibt es viele neue Cmdlets für die Verwaltung von virtuellen Maschinen. Interessant dabei ist, dass es eine neue Version des Hyper-V-Moduls gibt. Bis Windows 8.1 und Server 2012 R2 kam die Version 1.1 zum Einsatz und mit Windows 10 gibt es das Hyper-V-Modul in Version 2.0.0.0.

Aus Kompatibilitätsgründen macht es Sinn ein Modul mit einer spezifischen Version zu laden. Vor allem, wenn man z. B. vergleichen möchte, was sich in der neuen Version des Moduls verändert hat.

Welche Version aktuell geladen ist, bekommt man mit Get-Module heraus:

PS> get-module hyper-v

ModuleType Version    Name                                ExportedCommands
———- ——-    —-                                —————-
Binary     1.1        hyper-v                             {Add-VMDvdDrive,…

Mittels Remove-Module kann man das Modul entladen und mit Hilfe von Get-Module –Listavailable erhält man alle verfügbaren Versionen:

PS> Remove-Module hyper-v
PS> Get-Module -ListAvailable Hyper-V

    Verzeichnis: C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules

ModuleType Version    Name                                ExportedCommands
———- ——-    —-                                —————-
Binary     2.0.0.0    Hyper-V                             {Add-VMDvdDrive, Add-VMFibreChannelHba, Add-VMGroupMember, Add-VMHardDiskDrive…}
Binary     1.1        Hyper-V                             {Add-VMDvdDrive, Add-VMFibreChannelHba, Add-VMHardDiskDrive, Add-VMMigrationNetwork…}

Mittels Import-Module kann man nun ein Modul laden:

PS> Import-Module Hyper-V
PS> Get-Module Hyper-V

ModuleType Version    Name                                ExportedCommands
———- ——-    —-                                —————-
Binary     2.0.0.0    Hyper-V                             {Add-VMDvdDrive, Add-VMFibreChannelHba, Add-VMGroupMember, Add-VMHardDiskDrive…}

Man bekommt automatisch die neueste Version. Mit dem Parameter –RequiredVersion kann man nun eine spezifische Version laden:

Import-Module Hyper-V -RequiredVersion 1.1

Nun kann man mittels dieser Möglichkeit beide Versionen laden, die Cmdlets einer Variablen zuweisen und diese Vergleichen lassen:

PS> Import-Module Hyper-V -RequiredVersion 1.1
PS> $cV1 = Get-Command -Module Hyper-V
PS> Remove-Module Hyper-V
PS> Import-Module Hyper-V -RequiredVersion 2.0.0.0
PS> $cV2 = Get-Command -Module Hyper-V
PS> compare $cv1 $cv2

InputObject                              SideIndicator
———–                              ————-
Add-VMGroupMember                        =>
Add-VMNetworkAdapterRoutingDomainMapping =>
Add-VMSwitchTeamMember                   =>
Add-VMTPM                                =>
Disable-VMConsoleSupport                 =>
Enable-VMConsoleSupport                  =>
Get-VHDSet                               =>
Get-VHDSnapshot                          =>
Get-VMGroup                              =>
Get-VMHostCluster                        =>
Get-VMNetworkAdapterIsolation            =>
Get-VMSwitchTeam                         =>
Get-VMTPM                                =>
Get-VMVideo                              =>
New-VMGroup                              =>
Optimize-VHDSet                          =>
Remove-VHDSnapshot                       =>
Remove-VMGroup                           =>
Remove-VMGroupMember                     =>
Remove-VMSwitchTeamMember                =>
Rename-VMGroup                           =>
Set-VMHostCluster                        =>
Set-VMNetworkAdapterIsolation            =>
Set-VMNetworkAdapterRoutingDomainMapping =>
Set-VMSwitchTeam                         =>
Set-VMTPM                                =>
Set-VMVideo                              =>
Start-VMTrace                            =>
Stop-VMTrace                             =>
Update-VMVersion                         =>
Add-VmNetworkAdapterRoutingDomainMapping <=
Get-VmNetworkAdapterIsolation            <=
Set-VmNetworkAdapterIsolation            <=
Set-VmNetworkAdapterRoutingDomainMapping <=

Dabei fällt auf, dass keine Cmdlets entfernt wurden, auch wenn es auf den ersten Blick so aussieht. Es wurde lediglich die Schreibweise bei den letzten vier Cmdlets von …-Vm… in …-VM… geändert.

Halten wir also fest, dies sind die neuen Cmdlets in Hyper-V 2.0.0.0:

Add-VMGroupMember
Add-VMNetworkAdapterRoutingDomainMapping
Add-VMSwitchTeamMember
Add-VMTPM
Disable-VMConsoleSupport
Enable-VMConsoleSupport
Get-VHDSet
Get-VHDSnapshot
Get-VMGroup
Get-VMHostCluster
Get-VMNetworkAdapterIsolation
Get-VMSwitchTeam
Get-VMTPM
Get-VMVideo
New-VMGroup
Optimize-VHDSet
Remove-VHDSnapshot
Remove-VMGroup
Remove-VMGroupMember
Remove-VMSwitchTeamMember
Rename-VMGroup
Set-VMHostCluster
Set-VMNetworkAdapterIsolation
Set-VMNetworkAdapterRoutingDomainMapping
Set-VMSwitchTeam
Set-VMTPM
Set-VMVideo
Start-VMTrace
Stop-VMTrace
Update-VMVersion

Temporäre Dateien in Powershell erzeugen

30 April 2015

Lange hat es gedauert aber jetzt ist sie da. Microsoft hat in der April 2015 Preview für Powershell 5.0 eine Funktion für temporäre Dateien implementiert. New-TemporaryFile erzeugt eine temporäre Datei und gibt dessen Dateinamen in Form eines FileInfo-Objekt zurück.

Leider gibt es New-TemporaryFile nicht bei alten Versionen. Aber es gibt ja Polyfills. Hintergründe wie man Polyfills in Powershell erzeugen kann, kann man hier nachlesen: https://newyear2006.wordpress.com/2014/11/17/fehlende-cmdlets-in-powershell-durch-polyfills-nachbilden/.

Auf dieser Basis kann man mittels dieses Scripts die fehlende Funktion nachrüsten:

if (-not (Get-Command New-TemporaryFile -ErrorAction SilentlyContinue)) {
  &{ Function global:New-TemporaryFile ($Parameter) {
            [System.IO.FileInfo][System.IO.Path]::GetTempFileName()
        }
    }
}

Somit kann man bei älteren Powershell-Skripte bereits Funktionen nutzen, welche noch nicht verfügbar sind.