Warum USB 3.0 bzw. USB 3.1 nicht so schnell ist wie es sein könnte – oder die Geschichte um UASP USB Attached SCSI Protocol

28 April 2017

Ein Kunde fragte warum seine USB 3.0 Festplatte nicht schneller wäre. Eine einfache Frage aber um diese richtig beantworten zu können sind verschiedene Aspekte und Begriffe zu klären. Dabei ist wichtig zu wissen, dass bei der Anbindung eines externen Speichers per USB verschiedene Protokolle zum Einsatz kommen können. Es gibt einmal die Anbindung über das BOT-Protokoll (Bulk-Only Transport) und einmal über das UAS-Protokoll (USB Attached SCSI).

UASP ist deshalb besonders interessant weil es Command Queuing, Asynchrone Verarbeitung und erweiterte Aufgaben und Verwaltungsmöglichkeiten mitbringt. Der Protokolloverhead im Vergleich zur Datenübertragung mittels BOT sinkt signifikant. So sind bei einem USB 3.0 Anschluss mittels BOT-Protokoll 250MB/Sekunde möglich. Mittels UASP erreicht man mit der gleichen Hardware fast 400MB/Sekunde dabei sinkt gleichzeitig noch die Prozessorbelastung. Damit aber alles reibungslos funktioniert müssen Hardware und Treiber optimal aufeinander abgestimmt sein und sich im richtigen Modus befinden. Bei USB 3.0 oder 3.1 ist vor allem auf die Länge und Qualität der Kabel zu achten, sonst wird es nix mit der Highspeed-Übertragung der Daten. Da viele herkömmliche Festplatten für diese hohe Übertragungsraten eh zu langsam sind, macht eigentlich nur die Verwendung von SSDs sinn. Allerdings können herkömmlich Festplatten einen erheblichen Geschwindigkeitszugewinn verzeichnen, wenn mehrere Prozesse gleichzeitig auf die Festplatte zugreifen, dann hilft das Command Queuing und die asynchrone Verarbeitung.

Es gab schon früh Bestrebungen UASP unter Windows zu nutzen. Es war sogar bereits für Windows XP und Server 2003 vorgesehen: https://msdn.microsoft.com/en-us/library/windows/hardware/dn642103%28v=vs.85%29.aspx. Jedoch war jeder Hersteller gezwungen eigene Treiber zu entwickeln. Erst später mit Einführung von Windows 8 wurde ein generischer Treiber UASPStor.SYS von Microsoft direkt ausgeliefert: https://msdn.microsoft.com/en-us/library/windows/hardware/ff538820%28v=vs.85%29.aspx.

Die UAS-Spezifikation ist hier zu finden: Die aktuelle Fassung ist von 2016 und läuft unter INCITS 471-2010[R2015]: https://standards.incits.org/apps/group_public/project/details.php?project_id=30. Eine ältere, aber frei einsehbare Version gibt es hier: http://www.usb.org/developers/docs/devclass_docs/uasp_1_0.zip.

In der Microsoft USB FAQ finden sich auch Hinweise: https://msdn.microsoft.com/en-us/library/windows/hardware/dn423379%28v=vs.85%29.aspx#loadeddriver

Hardware
Es gibt nur wenig Geräte, die extra mit UASP-Unterstützung werben. Dies liegt sicher daran, dass bei den meisten externen Festplatten die Festplatten einfach zu langsam sind. Wer jedoch SSDs in externen Laufwerken einsetzt, der wird um UASP-Unterstützung nicht herum kommen.

Ein Hersteller der die Bedeutung von UASP erkannt hat ist Startech, dort finden sich alle möglichen USB-Kabel und externe Gehäuse wo explizit auf UASP hingewiesen wird. Der Hersteller preist die Vorteile in einem eigenen Blog-Beitrag an: https://blog.startech.com/post/all-you-need-to-know-about-uasp/

Wie kann man die Unterstützung von UASP prüfen?
So siehts im Gerätemanager aus: http://winaero.com/blog/check-if-your-usb-3-0-device-supports-usb-attached-scsi-uas-protocol/. Aber spannend wird es wie immer erst in der Commandline. Wenn man ein UASP-Gerät einsteckt, so erkennt Windows automatisch ob es den UASP-Treiber und den Dienst UASPSTOR starten muss. Klappt beides, so kann man mittels Powershell den aktuellen Status ermitteln:

Get-PnpDevice |where name -match mass

Status     Class           FriendlyName
——     —–           ————
OK         USB             USB-Massenspeichergerät
OK         SCSIAdapter     Per USB angeschlossenes SCSI (UAS)-Massenspeichergerät

Hier müsste das Gerät als “USB Attached SCSI (UAS) Mass Storage Device” bzw. “Per USB angeschlossenes SCSI (UAS)-Massenspeichergerät” auftauchen.

Zum Prüfen, ob der UASP-Dienst läuft und der Treiber geladen ist:

get-service uaspstor

Status   Name               DisplayName
——   —-               ———–
Stopped  uaspstor           USB Attached SCSI (UAS) Driver

Wenn also der Dienst nicht läuft oder keine UAS bei den Massenspeichern auftaucht, dann hat man keine UAS-fähige Hardware.

Linux
Wie kann man unter Linux feststellen, ob sein Gerät als UASP-Gerät erkannt wurde? Man ruft dmesg auf und findet dort einen Eintrag wie

[15655.952172] scsi host 14: uas

[15667.952172] sd 14:0:0:0: [sdk] Attached SCSI disk

Mögliche Probleme mit UAS
Nicht direkt ein Problem von UAS, sondern eher eine Definitionslücke bei Microsoft. Beim normalen USB-Treiber kann man einen Schreibschutz aktivieren, dieser wird beim UAS-Treiber noch nicht unterstützt.

http://forensenellanebbia.blogspot.de/2015/08/usb-write-blocking-with-registry-beware.html, Lösung: http://forensenellanebbia.blogspot.de/2015/08/usb-write-blocking-with-registry-beware_13.html aber Wegfall der Geschwindigkeit!

Der schnelle UAS-Übertragungsmodus steht nur an XHCI-USB-Controllern zur Verfügung, siehe https://msdn.microsoft.com/en-us/library/windows/hardware/dn423379%28v=vs.85%29.aspx#loadeddriver.

Hier noch weitere Infos zum Thema UASP, USB 3.0 und USB 3.1: https://www.elektronik-kompendium.de/sites/com/1310061.htm.

Was noch aufgefallen ist, etwas für die Forensiker
Eine über UASP angeschlossene Festplatte taucht, wenn diese entfernt wurde, später immer noch bei den Massenspeichern auf, allerdings mit dem Status Unknown. Schließt man eine andere Festplatte mit demselben Controller am gleichen Port an, so erhält diese einen neuen “Mass Storage”-Treibereintrag. So dass darüber später jederzeit nachvollziehbar wird, wann welche Festplatte per UAS angeschlossen war.

Wie kann man diese Zuordnung im Nachhinein feststellen?

Dazu benötigt man die InstanceID und muss die Seriennummer der Festplatte kennen.

$uas=Get-PnpDevice -class scsiadapter |where name -match uas
($uas).DeviceID
USB\VID_174C&PID_55AA\MSFT30____________W400BBX4

Die Seriennummer ist nämlich in der InstanceID enthalten und zwar sind es immer die letzten 20 Zeichen nach MSFT30. Allerdings in umgekehrter Reihenfolge, d. h. obige ID gehört zu der Festplatte mit der Seriennummer 4XBB004W.

Damit ist die Zuordnung zur Platte eindeutig gegeben. Nun noch die Frage, wann wurde zuerst am System benutzt?

$uas|Get-PnpDeviceProperty -KeyName DEVPKEY_Device_FirstInstallDAte

InstanceId KeyName                                   Type       Data
———- ——-                                   —-       —-
USB\VID… DEVPKEY_Device_FirstInstallDAte           FileTime   28.04.2017 13:00:03

Ebenso kann man mit DEVPKEY_Device_LastRemovalDate feststellen, wann sie das letzte Mal am System angemeldet war.

Advertisements

Endlich gibt es eine neue Dokuseite für Windows 10 und Windows Server 2016 für Administratoren

26 April 2017

Microsoft Technet ist die Informationsquelle für Windows belange. Allerdings leidet Technet seit Jahren an alten Technologien, so sind die meisten URLs nicht sprechend. Microsoft veröffentlicht für verschiedene Technologien nun seit einiger Zeit Dokumentationen unter doc.microsoft.com. Nun haben Windows 10 und Windows Server 2016 endlich die Ehre bekommen. Wenn man tiefer klickt, landet man zwar schnell wieder auf den alten Technet-Seiten aber der Anfang ist endlich gemacht.

Englisch:
https://docs.microsoft.com/en-us/windows/windows-10/
https://docs.microsoft.com/en-us/windows-server/windows-server-2016

Deutsch:
https://docs.microsoft.com/de-de/windows/windows-10/
https://docs.microsoft.com/de-de/windows-server/windows-server-2016

Das beste daran ist, dass die Dokus nun über Github einsehbar und vor allem auch editierbar sind: https://github.com/MicrosoftDocs/windowsserverdocs und https://github.com/Microsoft/windows-itpro-docs. Ebenso kann man Fehler direkt ansprechen und diskutieren: https://github.com/Microsoft/windows-itpro-docs/issues.

SQL Server Version aus MDF-Datei auslesen

22 April 2017

Man kann mit ganz einfachen Mitteln aus einer SQL-Server MDF-Datei auslesen, mit welcher SQL-Serverversion die Datei erstellt bzw. zuletzt bearbeitet wurde.

Hier wird ein kleiner Aufruf in Powershell beschrieben: https://jingyangli.wordpress.com/2017/04/12/check-internal-version-of-a-mdf-file/. Die tiefergehende Erläuterung findet sich hier: http://rusanu.com/2011/04/04/how-to-determine-the-database-version-of-an-mdf-file/.

Function Get-SQLServerInternalDBVersionFromFile {
  [CmdletBinding()]
  Param(
    [String]$MDFFile
  )

  $VersionBytes =  Get-Content -Encoding Byte $MDFFile | Select-Object –Skip 0x12064 -First 2
  $Version = $VersionBytes[1] * 256 + $VersionBytes[0]
  $Version
}

Hier gibt es eine Auflistung aller bisher bekannten Versionen: http://sqlserverbuilds.blogspot.de/2014/01/sql-server-internal-database-versions.html.

Hier die Tabelle nochmal:

SQLServer Version

Internal Database Version Database Compatibility Level

SQL Server 2016

852 130
SQL Server 2014 782 120
SQL Server 2012 706 110
SQL Server 2012 CTP1 684 110
SQL Server 2008 R2 660/661 100
SQL Server 2008 655 100

SQL Server 2005 SP2+
with VarDecimal enabled

612 90
SQL Server 2005 611 90
SQL Server 2000 539 80
SQL Server 7.0 515 70
SQL Server 6.5 408 65
SQL Server 6.0 unbekannt 60

Übermittlungsoptimierung Neuigkeiten in Windows 10 v1703

5 April 2017

Ich hatte mich hier schon mal mit der Übermittlungsoptimierung auseinandergesetzt, als ein WLAN verstopft wurde. https://newyear2006.wordpress.com/2016/05/28/bermittlungsoptimierung-frisst-die-gesamte-bandbreite/. Microsoft hat mit Windows 10 angefangen Updates nicht mehr per BITS auszuliefern sondern eben über die Übermittlungsoptimierung. Nur waren seither die Möglichkeiten darüber Informationen zu erhalten sehr begrenzt.

Mit dem Creators Update allerdings, hat ein neues Modul mit Namen DeliveryOptimization Einzug gehalten.

PS > get-command -Module DeliveryOptimization

CommandType     Name                                               Version    Source
———–     —-                                               ——-    ——
Cmdlet          Get-DeliveryOptimizationPerfSnap                   1.0.0.0    DeliveryOptimization
Cmdlet          Get-DeliveryOptimizationStatus                     1.0.0.0    DeliveryOptimization

Man kann zwar keine Einstellungen ändern, allerdings bekommt man nun endlich einige Infos zu dem was im Hintergrund stattfindet.

PS > Get-DeliveryOptimizationStatus
No active Delivery Optimization download or upload jobs
PS > Get-DeliveryOptimizationPerfSnap
There are no Delivery Optimization downloads to show PerfSnap data

Nachdem man bei den Updateeinstellungen dann die Verbreitung über das LAN oder übers Internet aktiviert hat, bekommt man entsprechende Daten, hier zu den einzelnen Dateien:

PS > Get-DeliveryOptimizationStatus

FileId                  : a4d873c066a67a58ce46f0bb69bc6e6d2eaddda8
FileSize                : 182553
TotalBytesDownloaded    : 182553
PercentPeerCaching      : 0
BytesFromPeers          : 0
BytesFromHttp           : 182553
Status                  : Caching
Priority                : Foreground
BytesFromLanPeers       : 0
BytesFromGroupPeers     : 0
BytesFromInternetPeers  : 0
BytesToLanPeers         : 0
BytesToGroupPeers       : 0
BytesToInternetPeers    : 0
HttpConnectionCount     : 4
LanConnectionCount      : 0
GroupConnectionCount    : 0
InternetConnectionCount : 0
DownloadMode            : 99
SourceURL               : http://download.windowsupdate.com/c/msdownload/update/software
/crup/2017/04/windows10.0-kb
6251-x64-express_a4d873c066a67a58ce46f0bb69bc6e6d2eaddda8.cab

Dabei sind vor allem die gesammelten Performance Daten interessant:

PS > Get-DeliveryOptimizationPerfSnap
FilesDownloaded                 : 5
FilesUploaded                   : 0
TotalBytesDownloaded            : 565.427
TotalBytesUploaded              : 0
AverageDownloadSize             : 113.085
AverageUploadSize               : 0

Diese gibt es auch in erweiterter Fassung bei Verwendung von –Verbose:

PS > Get-DeliveryOptimizationPerfSnap -Verbose
FilesDownloaded                 : 4
FilesUploaded                   : 0
TotalBytesDownloaded            : 398.452
TotalBytesUploaded              : 0
AverageDownloadSize             : 99.613
AverageUploadSize               : 0
DownloadMode                    : 3
Files                           : 7
CacheSizeBytes                  : 0
TotalDiskBytes                  : 135.770.664.960
AvailableDiskBytes              : 120.237.105.152
NumberOfPeers                   : 0
CdnConnections                  : 10
LanConnections                  : 0
GroupConnections                : 0
InternetConnections             : 0
DownlinkBps                     : 2.339.984
UplinkBps                       : 127.664
ForegroundDownloadRatePct       : 90
BackgroundDownloadRatePct       : 45
UploadRatePct                   : 100
UploadCount                     : 0

Hier wurde das Modul das erste Mal erwähnt: https://2pintsoftware.com/delivery-optimization-powershell-cmdlets/. Hier findet man auch weitere wissenswerte Infos zur Übermittlungsoptimierung. Der Downloadmode wird hier beschrieben: https://2pintsoftware.com/delivery-optimization-dl-mode/.

Neue Provisioning Cmdlets in Windows 10 v1703 Creators Update

4 April 2017

Beim durchschauen der neuen Windows 10 Version bin ich auf ein neues Powershell Modul gestoßen. Es nennt sich schlicht und ergreifend Provisioning ist aber bereits in Version 3 verfügbar.

Cool ein neues Modul und dann gleich Version 3! Bei der Recherche mittels Google war nichts in der Richtung zu finden, auch die Hilfe des Moduls zeigte nur ins Nirvana. Also eine echte Neuentdeckung Smiley.

So schaut man sich die Modul Infos an:

PS C:\WINDOWS\system32> get-module provisioning|fl *

LogPipelineExecutionDetails : False
Name                        : Provisioning
Path                        : C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules\Provisioning\provisioning.psm1
ImplementingAssembly        :
Definition                  : #
                              # Script Module file for provcmdlets module.
                              #
                              # Copyright (c) Microsoft Corporation
                              #
                              #
                              # Cmdlet aliases
                              #
                              Set-Alias Add-ProvisioningPackage Install-ProvisioningPackage
                              Set-Alias Remove-ProvisioningPackage Uninstall-ProvisioningPackage
                              Set-Alias Add-TrustedProvisioningCertificate Install-TrustedProvisioningCertificate
                              Set-Alias Remove-TrustedProvisioningCertificate Uninstall-TrustedProvisioningCertifi
                              Export-ModuleMember -Alias * -Function * -Cmdlet *
Description                 :
Guid                        : 1323f046-a4bd-47df-a8bc-8253eabc49b2
HelpInfoUri                 : http://go.microsoft.com/fwlink/?LinkId=525624
ModuleBase                  : C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules\Provisioning
PrivateData                 :
Tags                        : {}
ProjectUri                  :
IconUri                     :
LicenseUri                  :
ReleaseNotes                :
RepositorySourceLocation    :
Version                     : 3.0
ModuleType                  : Script
Author                      : Microsoft Corporation
AccessMode                  : ReadWrite
ClrVersion                  : 4.0
CompanyName                 : Microsoft Corporation
Copyright                   : © Microsoft Corporation. All rights reserved.
DotNetFrameworkVersion      :
ExportedFunctions           : {}
Prefix                      :
ExportedCmdlets             : {[Export-ProvisioningPackage, Export-ProvisioningPackage], [Export-Trace, Export-Tra
                              [Get-ProvisioningPackage, Get-ProvisioningPackage], [Get-TrustedProvisioningCertific
                              Get-TrustedProvisioningCertificate]…}
ExportedCommands            : {[Export-ProvisioningPackage, Export-ProvisioningPackage], [Export-Trace, Export-Tra
                              [Get-ProvisioningPackage, Get-ProvisioningPackage], [Get-TrustedProvisioningCertific
                              Get-TrustedProvisioningCertificate]…}
FileList                    : {}
CompatiblePSEditions        : {}
ModuleList                  : {}
NestedModules               : {provcmdlets}
PowerShellHostName          :
PowerShellHostVersion       :
PowerShellVersion           : 4.0
ProcessorArchitecture       : None
Scripts                     : {}
RequiredAssemblies          : {}
RequiredModules             : {}
RootModule                  : provisioning.psm1
ExportedVariables           : {}
ExportedAliases             : {[Add-ProvisioningPackage, Add-ProvisioningPackage],
                              [Add-TrustedProvisioningCertificate, Add-TrustedProvisioningCertificate],
                              [Remove-ProvisioningPackage, Remove-ProvisioningPackage],
                              [Remove-TrustedProvisioningCertificate, Remove-TrustedProvisioningCertificate]}
ExportedWorkflows           : {}
ExportedDscResources        : {}
SessionState                : System.Management.Automation.SessionState
OnRemove                    :
ExportedFormatFiles         : {}
ExportedTypeFiles           : {}

Bei den NestedModules fällt provcmdlets auf. Sucht man damit in Google findet man gerade mal 10 Einträge und alles erst seit Ende 2016. Also alles noch ganz heiß!

provcmdlets findet man im Verzeichnis C:\Windows\System32\WindowsPowerShell\v1.0\Modules\Provisioning:

PS C:\WINDOWS\system32> dir C:\Windows\System32\WindowsPowerShell\v1.0\Modules\Provisioning

    Verzeichnis: C:\Windows\System32\WindowsPowerShell\v1.0\Modules\Provisioning

Mode                LastWriteTime         Length Name
—-                ————-         —— —-
-a—-       18.03.2017     21:57           6570 provautologger_add.reg
-a—-       18.03.2017     21:57            152 provautologger_del.reg
-a—-       18.03.2017     21:57          20992 provcmdlets.dll
-a—-       18.03.2017     21:57          90112 provcommon.dll
-a—-       18.03.2017     21:57           2238 provisioning.psd1
-a—-       18.03.2017     21:57            482 provisioning.psm1
-a—-       18.03.2017     21:57         745984 provpackageapi.dll
-a—-       18.03.2017     21:57           8378 provtrace.wprp
-a—-       18.03.2017     21:57          13312 wiminterop.dll

D. h. es gibt verschiedene DLL-Dateien und sogar Registry-Dateien die involviert sind. Bekommt man irgendwelche Infos von den DLL-Dateien?

PS C:\Windows\System32\WindowsPowerShell\v1.0\Modules\Provisioning> (dir).versioninfo| select comments, filedescription

Comments FileDescription
——– —————

 

 

         "ProvPackageAPI.DYNLINK"

Gähnende Leere. Schade.

Was ist nun an Cmdlets enthalten?

PS C:\WINDOWS\system32> get-command -Module
Provisioning

CommandType     Name                                               Version    Source
———–     —-                                               ——-    ——
Alias           Add-ProvisioningPackage                            3.0        Provisioning
Alias           Add-TrustedProvisioningCertificate                 3.0        Provisioning
Alias           Remove-ProvisioningPackage                         3.0        Provisioning
Alias           Remove-TrustedProvisioningCertificate              3.0        Provisioning
Cmdlet          Export-ProvisioningPackage                         3.0        Provisioning
Cmdlet          Export-Trace                                       3.0        Provisioning
Cmdlet          Get-ProvisioningPackage                            3.0        Provisioning
Cmdlet          Get-TrustedProvisioningCertificate                 3.0        Provisioning
Cmdlet          Install-ProvisioningPackage                        3.0        Provisioning
Cmdlet          Install-TrustedProvisioningCertificate             3.0        Provisioning
Cmdlet          Uninstall-ProvisioningPackage                      3.0        Provisioning
Cmdlet          Uninstall-TrustedProvisioningCertificate           3.0        Provisioning

Dabei verweisen die Add-Aliase auf die Install-Cmdlets und die Remove-Aliase auf die UnInstall-Cmdlets. Netto bleiben also folgende Cmdlets übrig:

Export-ProvisioningPackage
Export-Trace
Get-ProvisioningPackage
Get-TrustedProvisioningCertificate
Install-ProvisioningPackage
Install-TrustedProvisioningCertificate
Uninstall-ProvisioningPackage
Uninstall-TrustedProvisioningCertificate

Wenn man sich die Auflistung so anschaut, dann würde man meinen mit Get-ProvisioningPackage könnte man etwas anfangen. Dem ist leider nicht so. Auch Get-ProvisioningPackage –AllInstalledPackages brachte nichts zurück.

Also mal die Parameter so anschauen:

PS C:\> (get-command Get-ProvisioningPackage).Definition

Get-ProvisioningPackage [-PackageId] <string> [-LogsDirectoryPath <string>] [-WprpFile <string>]
[-ConnectedDevice] [<CommonParameters>]

Get-ProvisioningPackage [-PackagePath] <string> [-LogsDirectoryPath <string>] [-WprpFile
<string>] [-ConnectedDevice] [<CommonParameters>]

Get-ProvisioningPackage [-AllInstalledPackages] [-LogsDirectoryPath <string>] [-WprpFile
<string>] [-ConnectedDevice] [<CommonParameters>]

Jetzt hatte ich da so eine Idee, welche auch Version 3 erklärt. Denn es gibt in DISM sogenannte Provisioning Package Command Line Optionen https://msdn.microsoft.com/de-de/windows/hardware/commercialize/manufacture/desktop/dism-provisioning-package-command-line-options, welche seither noch keine Powershell Entsprechung gefunden haben. Wahrscheinlich sind die Provisioning Cmdlets darauf abgestellt?

Also die These mal schnell überprüft. Provisioning Packages haben ihre eigenen Dateiendungen nämlich .ppkg. Es finden sich auf Windows 10 Systemen im Verzeichnis C:\windows\Provisioning\Packages entsprechende Dateien:

PS C:\windows\Provisioning\Packages> dir

    Verzeichnis: C:\windows\Provisioning\Packages

Mode                LastWriteTime         Length Name
—-                ————-         —— —-
-a—-       18.03.2017     21:57           6139 Power.EnergyEstimationEngine.Control.ppkg
-a—-       18.03.2017     21:57           5654 Power.EnergyEstimationEngine.CPU.ppkg
-a—-       18.03.2017     21:57           5701 Power.EnergyEstimationEngine.Display.ppkg
-a—-       18.03.2017     21:57           5677 Power.EnergyEstimationEngine.MBB.ppkg
-a—-       18.03.2017     21:57           5622 Power.EnergyEstimationEngine.StandbyActivation.ppkg
-a—-       18.03.2017     21:57           6498 Power.EnergyEstimationEngine.Storage.ppkg
-a—-       18.03.2017     21:57           5637 Power.EnergyEstimationEngine.Telemetry.ppkg
-a—-       18.03.2017     21:57           5644 Power.EnergyEstimationEngine.Wifi.ppkg
-a—-       18.03.2017     21:57           6512 Power.Settings.Battery.ppkg
-a—-       18.03.2017     21:57           5718 Power.Settings.Button.ppkg
-a—-       18.03.2017     21:57           5612 Power.Settings.Disk.ppkg
-a—-       18.03.2017     21:57           5598 Power.Settings.Display.ppkg
-a—-       18.03.2017     21:57           5411 Power.Settings.EnergySaver.ppkg
-a—-       18.03.2017     21:57           5551 Power.Settings.IdleResiliency.ppkg
-a—-       18.03.2017     21:57           5631 Power.Settings.PCIExpress.ppkg
-a—-       18.03.2017     21:57          11478 Power.Settings.Processor.ppkg
-a—-       18.03.2017     21:57           6623 Power.Settings.Sleep.ppkg

Was passiert nun wenn man Get-ProvisioningPackage mit so einer Datei aufruft?

PS C:\windows\Provisioning\Packages> Get-ProvisioningPackage -PackagePath .\Power.Settings.Processor.ppkg

IsInstalled     : False
PackageID       : fc01e91f-914c-45af-9d7c-0b2e5fbedf62
PackageName     : Power.Settings.Processor
PackagePath     : C:\windows\Provisioning\Packages\Power.Settings.Processor.ppkg
Description     :
Rank            : 0
Altitude        : 0
Version         : 7.0
OwnerType       : Microsoft
Notes           :
LastInstallTime :
Result          :

Ja das sieht ja nun schon wesentlich besser aus. Also handelt es sich tatsächlich um Cmdlets um ppkg-Dateien verwalten zu können. These also bestätigt.

Und wo braucht man nun ppkg-Dateien konkret? Zur Einrichtung von Rechnern oder Handies, dazu musste man seither bei den Einstellungen auf Konten, dort auf Arbeits- und Schulkonto gehen und da dann auf Bereitstellungspaket hinzufügen oder entfernen. Dies geht nun wesentlich einfacher!

Hier eine Beschreibung zum Thema: https://technet.microsoft.com/en-us/itpro/windows/deploy/provisioning-how-it-works.

Man könnte nun noch viel mehr probieren aber die Richtung ist schon mal klar.

QoS in IP-Netzwerken testen

1 April 2017

QoS also Quality of Service soll dabei helfen Datenpakete zu priorisieren damit z. B. ein VoIP-Telefonat reibungslos läuft. Nur leider hat die Sache wie immer einen Haken.

Man muss im Zusammenhang mit QoS in IP-Netzten aktuell RSVP (IntServ) und ToS (DiffServ) unterscheiden. https://de.wikipedia.org/wiki/Quality_of_Service#Realisierung_in_IP-Netzen. Wann immer man über RSVP liest kann man es eigentlich gleich abhaken, denn es hat sich nicht durchgesetzt und wurde einer breiten Basis mit der Aufgabe von Windows XP beraubt. Dieser Artikel geht zum Beispiel auf den Ping.EXE –v Parameter ein und welche Änderungen bei Windows Vista bzw. Windows 7 gekommen sind: http://htluo.blogspot.de/2016/05/qos-test-tool-on-windows-7-or-above.html. Ich möchte noch auf diesen Artikel verweisen wo beim Server 2012 von RSVP in Verbindung mit QWave die Rede ist: https://technet.microsoft.com/de-de/library/hh831592(v=ws.11).aspx. Aber ich gehe davon aus, dass dies ein Versehen ist oder MS?

Windows, auch ein aktuelles Windows 10 ist also ein Totalreinfall in Sachen QoS-Tests. Zum Glück gibt es Linux, dort kann man fast mit Bordmitteln einen Endpunkt auf QoS Unterstützung testen.

Man benötigt also ein Ubuntu oder Debian System, dort hat der Ping-Befehl den Parameter –Q. Mit diesem kann man die TOS-Angabe übergeben. Ein Mapping zwischen DSCP und TOS-Werten ist hier zu finden: https://www.tucny.com/Home/dscp-tos. Hier wird auch gleich noch auf ein paar Besonderheiten eingegangen. Die gängigsten Werte sind 104 (DSCP 26) für SIP und 184 (DSCP 46) für RTP.

Nun zur praktischen Anwendung. So prüft man z. B. sipgate, genauso gut könnte man auch eine Fritzbox mittels fritz.box testen:

ping proxy.live.sipgate.de –Q 184

Man bekommt ganz normal Ping-Pakete zurück. Wie kann man nun aber nachvollziehen, ob die Gegenseite tatsächlich QoS unterstützt?

Man macht in einem zweiten Terminalfenster eine Abfrage mittels TCPDump. Gegebenenfalls muss man TCPDump noch mittels apt-get installieren.

tcpdump –i eth0 –v ip[1]==184 and icmp[0]==0

Wenn nun Antwortpakete von der Gegenseite kommen, werden diese hier angezeigt. Sobald hier etwas angezeigt wird, passt es. Wird nichts angezeigt hat man ein Problem.

Bei Problemen sollte man zuerst schauen, ob die ICMP-Requests auch rausgehen:

tcpdump –i eth0 –v ip[1]==184 and icmp[0]==8

Es sollte tos mit 0x8b was 184 Dezimal entspricht angezeigt werden.

Wenn man mehr Infos haben möchte, kann man noch TShark oder Wireshark bemühen. Wie man damit umgeht zeigt dieser Artikel sehr schön: http://conceptsfortheroad.com/2016/01/01/using-linux-to-verify-dscp/.

VSSAdmin Writers in Powershell überführen

31 März 2017

Für die Analyse von Fehlern bei Backups ist es oft hilfreich vssadmin zu bemühen. Aus diesem Grund hier eine allgemeine Funktion um die verfügbaren Volumenschattenkopie-Verfasser ermitteln zu können.

Normalerweise ruft man vssadmin list writer auf und erhält dann

vssadmin list writers
vssadmin 1.1 – Verwaltungsbefehlszeilenprogramm des Volumeschattenkopie-Dienstes
(C) Copyright 2001-2013 Microsoft Corp.

Verfassername: "Task Scheduler Writer"
   Verfasserkennung: {d61d61c8-d73a-4eee-8cdd-f6f9786b7124}
   Verfasserinstanzkennung: {1bddd48e-5052-49db-9b07-b96f96727e6b}
   Status: [1] Stabil
   Letzter Fehler: Kein Fehler

Verfassername: "VSS Metadata Store Writer"
   Verfasserkennung: {75dfb225-e2e4-4d39-9ac9-ffaff65ddf06}
   Verfasserinstanzkennung: {088e7a7d-09a8-4cc6-a609-ad90e75ddc93}
   Status: [1] Stabil
   Letzter Fehler: Kein Fehler

Es geht aber schöner, wenn man diese Funktion benutzt:

Function Get-VSSWriter {

# deutsch/englisch unterscheidet sich
If ((Get-UICulture).Name -like "de-*") {
$pat = "Verfassername:\s"
$quot = ‚"‘
} else {
$pat = "Writer\sname:\s"
$quot = "’"
}
 
vssadmin list writers |
Select-String -Pattern $pat -Context 0,4 |
ForEach-Object {
     [pscustomobject]@{
         Id = (($_.Context.PostContext -split "\r\n")[0] -split ‚:‘)[1].Trim()
         Name = ($_.Line -split ‚:\s‘,2)[1] -replace $quot,“
  Status = (($_.Context.PostContext -split "\r\n")[2] -split ‚:‘)[1].Trim()
  LastError = (($_.Context.PostContext -split "\r\n")[3] -split ‚:‘)[1].Trim()
     }
}

}

Geklaut von https://p0w3rsh3ll.wordpress.com/2016/07/14/backuprestore-a-local-windows-internal-database/ und etwas verschönert.

Beim Aufruf mittels Get-VSSWriter erhält man z. B. diese Ausgabe:

Id                                     Name                            Status     LastError
–                                     —-                            ——     ———
{d61d61c8-d73a-4eee-8cdd-f6f9786b7124} Task Scheduler Writer           [1] Stabil Kein Fehler
{75dfb225-e2e4-4d39-9ac9-ffaff65ddf06} VSS Metadata Store Writer       [1] Stabil Kein Fehler
{0bada1de-01a9-4625-8278-69e735f39dd2} Performance Counters Writer     [1] Stabil Kein Fehler
{e8132975-6f93-4464-a53e-1050253ae220} System Writer                   [1] Stabil Kein Fehler
{a65faa63-5ea8-4ebc-9dbd-a0c4db26912a} SqlServerWriter                 [1] Stabil Kein Fehler
{cd3f2362-8bef-46c7-9181-d62844cdc0b2} MSSearch Service Writer         [1] Stabil Kein Fehler
{4dc3bdd4-ab48-4d07-adb0-3bee2926fd7f} Shadow Copy Optimization Writer [1] Stabil Kein Fehler
{be000cbe-11fe-4426-9c58-531aa6355fc4} ASR Writer                      [1] Stabil Kein Fehler
{542da469-d3e1-473c-9f4f-7847f01fc64f} COM+ REGDB Writer               [1] Stabil Kein Fehler
{afbab4a2-367d-4d15-a586-71dbb18f8485} Registry Writer                 [1] Stabil Kein Fehler
{7e47b561-971a-46e6-96b9-696eeaa53b2a} MSMQ Writer (MSMQ)              [1] Stabil Kein Fehler
{2a40fd15-dfca-4aa8-a654-1f8c654603f6} IIS Config Writer               [1] Stabil Kein Fehler
{4969d978-be47-48b0-b100-f328f07ac1e0} BITS Writer                     [1] Stabil Kein Fehler
{a6ad56c2-b509-4e6c-bb19-49d8f43532f0} WMI Writer                      [1] Stabil Kein Fehler

Arp für IPv6 bzw. wie kann ich zu einer IPv6-Adresse die zugehörige IPv4-Adresse unter Windows ermitteln?

20 März 2017

Wenn man unter aktuellen Windowsversionen z. B. Get-SmbOpenFile verwendet, um z. B. sehen zu können, welcher Benutzer auf welchem Rechner gerade welche Dateien geöffnet hat, so bekommt man dort einen ClientComputername angegeben. Leider wird dieser ClientComputername oft als IPv6-Adresse und nicht als IPv4-Adresse angegeben. Im Grunde ist es ja korrekt alles über IPv6 zu machen aber wir Menschen tun uns halt schwer mit den IPv6-Adressen.

Wie kann man nun aber zu einer IPv6-Adresse die zugehörige IPv4-Adresse im lokalen Netz ermitteln? Ein Aufruf von ARP.EXE zeigt gähnende Leere, denn es zeigt nur IPv4-Adressen an. Einen Parameter –6 oder ARP6.EXE gibt es nicht.

Nun könnte man NETSH.EXE das alte Universaltool rauskramen und mittels

netsh int ipv6 show neigh

die MAC-Adressen zu den MAC-Adressen von der ARP.EXE-Ausgabe in Beziehung setzen. Aber das artet schnell in Arbeit aus.

Hier hilft wie immer Powershell, denn dort gibt es das Get-NetNeighbor-Cmdlet und damit kommt man bei richtiger Anwendung ganz schnell zum Ziel:

PS> Get-NetNeighbor| Group-Object linklayeraddress | where count -eq 2 | select -ExpandProperty group

ifIndex IPAddress                 LinkLayerAddress 
——- ———                 —————- 
3       fe80::41dc:1d58:7d3b:c57b EC-A8-6B-D1-F5-46
3       192.168.100.72            EC-A8-6B-D1-F5-46
3       fe80::1e74:dff:feac:c8d0  1C-74-0D-AC-C8-D0
3       192.168.100.1             1C-74-0D-AC-C8-D0

Hier sieht man schön, dass die passenden IP-Adressen immer durch die MAC-Adresse beieinander gruppiert sind und so schön von der einen auf die andere geschlossen werden kann.

Da wir uns schon wieder bei Powershell befinden, ist es sicher sinnvoll daraus gleich eine Funktion zu machen, welche in Skripten verwendet werden kann.

Function Convert-IPAddress {
[CmdletBinding()]
Param(
  [IPAddress]$IPAdresse
)

$n=Get-NetNeighbor

# Alle IP-Adressen mit MAC-Adressen ermitteln:
$nip = $n|where linklayeraddress -ne ""| sort linklayeraddress

# MAC-Adresse zur gesuchten IP-Adresse ermitteln: 
$nMAC = $nip | where ipaddress -eq $IPAdresse.IPAddressToString
# alle IP-Adressen zur ermittelten MAC holen:
$rip = $nip | where linklayeraddress -eq $nmac.LinkLayerAddress

$rip = $rip| where ipaddress -ne $IPAdresse.IPAddressToString

If ([System.Net.Sockets.AddressFamily]::InterNetworkV6 -eq $IPAdresse.AddressFamily) {
  # von IPv6 nach IPv4, also nur IPv4 zurückgeben
  ($rip | where {([IPAddress]$_.IPAddress).AddressFamily -eq [System.Net.Sockets.AddressFamily]::InterNetwork}).IPAddress
} else {
  If ([System.Net.Sockets.AddressFamily]::InterNetwork -eq $IPAdresse.AddressFamily) {
   # von IPv4 nach IPv6, also nur IPv6 zurückgeben
   ($rip | where {([IPAddress]$_.IPAddress).AddressFamily -eq [System.Net.Sockets.AddressFamily]::InterNetworkV6}).IPAddress
  } 
}
}

Damit kann man nun ganz einfach die IP-Adresse konvertieren:

PS> Convert-IPAddress fe80::1e74:dff:feac:c8d0
192.168.100.1
PS> Convert-IPAddress 192.168.100.1
fe80::1e74:dff:feac:c8d0

Gibt man eine Adresse an, zu der es keine Entsprechung gibt, bekommt man einfach $Null zurück.

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!

“Wie soll diese Website geöffnet werden?”-Dialog wegbekommen

10 März 2017

In bestimmten Situationen, vor allem nach einer Installation oder Deinstallation eines Programms, kann es bei einem neu eingerichteten Windows 10 dazu kommen, dass ein Dialog geöffnet wird mit dem Text:

Wie soll diese Website geöffnet werden?

App verwenden
—–
Standardbrowser verwenden

[  ]  Immer diese App zum Öffnen von <Website> verwenden

OK

Da die Installationen oder Deinstallationen meistens mit Adminrechten durchgeführt werden, kann es zu einer Situation kommen, wenn man die Meldung nicht beachtet und der eigentliche administrative Vorgang bereits abgeschlossen ist, dass die Meldung weiterhin am Bildschirm stehen bleibt und nicht mehr wegzubekommen ist. Das hat mit den fehlenden Rechten des Standardbenutzers nach der Installation zu tun.

Was also tun?

Entweder Rechnerneustart oder im Taskmanager die Datei OpenWith.EXE beenden.