Archive for the ‘USB’ Category

Feststellen welches Programm das Entfernen eines USB-Gerätes unter Windows verhindert

30 August 2017

Wenn man unter Windows USB Geräte abmeldet bzw. auswirft, kann es passieren, dass man mit dieser schönen Meldung beglückt wird:

—————————
Fehler beim Abdocken von "USB-Massenspeichergerät"
—————————
Das Gerät "USB-Massenspeichergerät" kann aufgrund eines unbekannten Fehlers nicht beendet werden. Entfernen Sie das Gerät nicht, solange es noch verwendet wird. Schließen Sie alle Programme, von denen das Gerät verwendet wird, und entfernen Sie es anschließend.
—————————
OK  
—————————

Unter Windows 7 sieht die Meldung etwas anders aus, ist aber genauso sinnlos:

—————————
Fehler beim Abdocken von "USB-Massenspeichergerät"
—————————
Dieses Gerät wird gerade verwendet. Schließen Sie alle Programme oder Fenster, die möglicherweise das Gerät verwenden, und wiederholen Sie den Vorgang.
—————————
OK  
—————————

Tja, “Unbekannte Fehler” sind des Benutzers liebste Fehler! Selbst heute in Zeiten von Windows 10 hat es Microsoft noch nicht geschafft diese Meldung mit mehr sinnvollen Informationen zu versehen und kommt immer noch so kryptisch wie zu Windows XP-Zeiten daher.

Aber dank Powershell kann der gequälte Anwender sich etwas mehr Informationen beschaffen. Zumindest bei Windows 7 bis Windows 10.

Get-WinEvent -ProviderName Microsoft-Windows-Kernel-PnP -MaxEvents 5 | where {$_.TimeCreated.Date -eq (Get-Date).Date -and $_.id -eq 225} | ft TimeCreated, Message –Wrap

Denn es werden in der Ereignisanzeige in Windows tiefergehende Informationen zum Vorgang gespeichert und damit kann man in der Regel den Grund für obige Fehlermeldung herausfinden. Man muss nur beim Microsoft-Windows-Kernel-PNP Provider nach der EventID 225 suchen.

In diesem Fall bekommt man z. B.:

TimeCreated         Message
———–         ——-
30.08.2017 17:33:47 Die Anwendung \Device\HarddiskVolume4\Windows\System32\cmd.exe mit der Prozess-ID                     21832 hat das Entfernen oder Auswerfen für das Gerät                     USB\VID_1E68&PID_0035\BB00000XXXXXXX beendet.

angezeigt. D. h. cmd.exe, also die Eingabeaufforderung, mit der ProzessID 21832 hatte Zugriff auf den USB-Stick und verhinderte dadurch das Auswerfen.

Advertisements

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.

USB-Bootstick von einer Windows-ISO erstellen, MasterbootRecord (MBR)-Variante

6 März 2017

In Bezug zu diesem Artikel https://newyear2006.wordpress.com/2009/09/19/windows-vista-windows-7-usb-boot-stick-erstellen/, hier ein Update um die einzelnen Dinge per Powershell hinzubekommen. Dadurch wird es möglich eine beliebige aktuelle Microsoft ISO-Datei (von Vista bis Server 2016) zu verwenden und deren Inhalt auf einem bootbaren USB-Stick zu erhalten. Damit die unten stehenden Powershellbefehle verfügbar sind, braucht man mindestens Windows 8.1, getestet habe ich es mit Windows 10.

Diese Methode könnte man auch mit leichter Variation verwenden, um eine bootbare VHD oder VHDX für einen Hyper-V zu bekommen. Aber dies vielleicht ein anderes Mal.

Ein weiterer Vorteil bei diesem Weg kann man auch Modifikationen der zu installierenden Dateien vornehmen. So kann man z. B. die EI.CFG bearbeiten, bevor man die eigentliche Installation beginnt. https://newyear2006.wordpress.com/2009/12/13/windows-7-versionsauswahl-bei-installation/. Oder man könnte die Eingabe des Produktschlüssels umgehen: https://newyear2006.wordpress.com/2012/08/30/windows-8-eingabe-des-produktschlssels-bei-der-installation-umgehen/. Noch eine Variante: https://newyear2006.wordpress.com/2013/09/13/windows-8-1-mit-product-key-von-windows-8-installieren/.

Damit die folgenden Befehle auch funktionieren, braucht man eine Powershell-Eingabeaufforderung mit Administratorrechten.

Auswahl des USB-Sticks
Da wir hier gezielt die Daten auf einen USB-Stick schreiben wollen und bei den Aktionen auch mal schnell die falsche Platte gelöscht werden kann, lassen wir uns nur Geräte die als Wechseldatenträger (Removable Storage) auftauchen anzeigen.

$diskObj = Get-Volume | Where DriveType –eq Removable | Get-Partition | Get-Disk | Out-GridView –Title "USB-Stick auswählen" –PassThru

Um auf vom Volume zur Disk zu kommen, muss man den Umweg über die Partition machen. Am Ende sorgt Out-GridView, dass nur ein Stick ausgewählt werden kann.

Wer hier nichts angezeigt bekommt, der hat womöglich einen Stick der als interne Festplatte erkannt wird. Vor allem USB-Sticks die “Windows to Go” geeignet sind, werden so also nicht erkannt. Wer möchte, kann dazu diese Variante wählen:

$diskObj = Get-Disk | Out-GridView –Title "USB-Stick auswählen" –PassThru

Wer auf einem Hyper-V oder Nano-Server arbeitet, der hat Out-GridView nicht zur Verfügung, der kann auch diese Variante verwenden:

Get-Disk | select Number, FriendlyName, @{Name="Total Size"; Expression={"{0:N2} GB" –f ($_.Size/1GB)}}

Es werden alle Laufwerke aufgelistet und man wählt eines aus:

$diskObj = Get-Disk –Number X

Egal welche Methode man gewählt hat, man sollte nun in $diskObj ein Objekt vom Typ MSFT_Disk haben.

USB-Stick löschen und formatieren
Nun geht es ans eingemachte. Für alle, die nicht wissen, was sie tun, hier kann man schnell seine Platte löschen, wenn man oben nicht das richtige Laufwerk ausgewählt hat!

$diskNr = $diskObj.Number

Get-Disk –Number $diskNr | Clear-Disk –RemoveData

muss mit Ja bestätigt werden.

$part=New-Partition –DiskNumber $diskNr –UseMaximumSize –IsActive

$part | Format-Volume –FileSystem NTFS –NewFileSystemLabel "BootDisk"

hier darf kein –Full angegeben werden, dann ist es automatisch eine Quick-Formatierung.

Add-PartitionAccessPath –Disknumber $diskNr –PartitionNumber $part.PartitionNumber –AssignDriveletter

Laufwerksbuchstaben holen:

$drive = (Get-Partition –DiskNumber $diskNr –PartitionNumber $part.PartitionNumber).DriveLetter

ISO-Datei auswählen
So, nun muss das ISO-Image geladen werden, hier wieder komfortabel per Auswahl die ISO-Datei ausgewählt:

$isoFile = Get-Item .\myIsoPath\*.ISO | Out-GridView –Title "ISO auswählen" –PassThru

Möchte man eine ISO-Datei direkt angeben oder liegt die ISO-Datei im aktuellen Pfad, dann kann auch der direkte Weg benutzt werden:

$isoFile = Get-Item (Resolve-Path .\myIsoFile.ISO)

Nun muss die ISO-Datei eingehängt werden und der zugeordnete Laufwerksbuchstabe ermittelt werden. Allerdings gibt es hier mal wieder ein kleines Problem! Die ISO-Datei darf nicht mittels UNC-Pfad angegeben werden bzw. darf nicht auf einem Remotelaufwerk liegen, sonst wird sie nicht richtig eingehängt, bzw. es wird kein Laufwerksbuchstabe zugeordnet. Nachdem ich ewig lang gezweifelt habe, habe ich jemand anderes gefunden, der genau das gleiche Problem entdeckt hat: https://github.com/VirtualEngine/Lability/issues/28#issuecomment-159657191. Kurz gesagt, Get-Volume liefert nicht den Laufwerksbuchstaben der ISO-Datei, allerdings liefern PS-Drive, Win32_Volume den Laufwerksbuchstaben! Mal wieder ein krasser Bug. Also Vorsicht!

$image=Mount-DiskImage –ImagePath $isoFile.Fullname –PassThru
$imageDrive=($image|Get-Volume).DriveLetter

Bootsector schreiben
Damit von dem USB-Stick auch gebootet werden kann, muss natürlich ein Boot-Sektor geschrieben werden.

Start-Process –Wait "$($ImageDrive):\Boot\BootSect.Exe" –ArgumentList "/NT60","$($drive)"

Dateien der ISO auf den Stick kopieren:

xcopy.exe "$($ImageDrive):\*.*" "$($drive):\" /s /h

So nun sollte alles auf dem Stick sein, so dass von diesem gebootet werden kann.

Noch wichtig: Was tun, wenn der Stick beim Bootvorgang nicht auftaucht? Im UEFI BIOS sollte dann die SecureBoot-Einstellung überprüft werden, ob beliebige Betriebssysteme gebootet werden können oder nur SecureBoot-fähige.

Ein späterer Artikel soll die SecureBoot- also UEFI-fähige Variante nachliefern.

Direkte Kommunikation mit Druckern unter Windows von Powershell aus

17 Oktober 2016

Manchmal ist es hilfreich, wenn man unter Windows direkt etwas ausdrucken kann. Direkt in diesem Fall bedeutet aber nicht über die üblichen Wege einen Druckertreiber anzusprechen, sondern, dass man direkt Steuerzeichen an einen Drucker senden kann. Man hat z. B. einen Druck in eine Datei umgeleitet und möchte nun diese Datei später an den Drucker senden. Dies ist mit den üblichen unter Powershell zur Verfügung stehenden Cmdlets wie Out-Printer nicht möglich.

Aber wie immer kann man das .Net Framework zu Hilfe nehmen. Grundlage für diesen Artikel ist der Knowledge Base Artikel https://support.microsoft.com/en-us/kb/322091. Dieser beschreibt die direkte Kommunikation mit Druckern unter C#. Hier hat sich nun jemand bereits die Mühe gemacht die Grundlage des Artikels an Powershell anzupassen: http://panchosoft.blogspot.de/2013/07/imprimir-en-impresora-de-etiquetas-sato.html. Das interessante an dieser Methode ist, dass es keine Rolle spielt, ob der Drucker per LPT- oder USB-Schnittstelle mit dem Rechner verbunden ist, noch ob mittels Netzwerk über TCP/IP oder WSD-Diensten mit ihm kommuniziert wird.

Die Daten finden mittels dieser Methode immer in Reinform ihren Weg zum Drucker, unabhängig vom Anschluss bzw. Übertragungsweg. Die generelle Druckvorgehensweise unter Windows ist hier beschrieben: https://msdn.microsoft.com/en-us/library/windows/desktop/dd145115%28v=vs.110%29.aspx.

Ein Aspekt ist noch wichtig. Es gibt sogenannte Typ 3 und Typ 4 Druckertreiber, dazu ein anderes Mal mehr. Typ 4 kommen verstärkt seit Windows 8 und nachfolgend zum Einsatz. Damit der Ansatz mit dem direkten senden von Daten an den Drucker klappt, muss dies berücksichtigt werden: https://msdn.microsoft.com/en-us/library/windows/desktop/ff686812(v=vs.110).aspx.

Hier zunächst das gesamte Script:

# Powershell RAW Print

$src = @‘
using System;
using System.Runtime.InteropServices;

public class RawPrinterHelper
{
// Structure and API declarions:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class DOCINFOA
{
  [MarshalAs(UnmanagedType.LPStr)]
  public string pDocName;
  [MarshalAs(UnmanagedType.LPStr)]
  public string pOutputFile;
  [MarshalAs(UnmanagedType.LPStr)]
  public string pDataType;
}

  [DllImport("winspool.Drv", EntryPoint = "OpenPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
  public static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter, out IntPtr hPrinter, IntPtr pd);

  [DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
  public static extern bool ClosePrinter(IntPtr hPrinter);

  [DllImport("winspool.Drv", EntryPoint = "StartDocPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
  public static extern bool StartDocPrinter(IntPtr hPrinter, Int32 level, [In, MarshalAs(UnmanagedType.LPStruct)] DOCINFOA di);

  [DllImport("winspool.Drv", EntryPoint = "EndDocPrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
  public static extern bool EndDocPrinter(IntPtr hPrinter);

  [DllImport("winspool.Drv", EntryPoint = "StartPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
  public static extern bool StartPagePrinter(IntPtr hPrinter);

  [DllImport("winspool.Drv", EntryPoint = "EndPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
  public static extern bool EndPagePrinter(IntPtr hPrinter);

  [DllImport("winspool.Drv", EntryPoint = "WritePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
  public static extern bool WritePrinter(IntPtr hPrinter, IntPtr pBytes, Int32 dwCount, out Int32 dwWritten);

}

‚@

Add-Type -TypeDefinition $src -Language CSharpVersion3

function Out-RawPrinter {
    [CmdletBinding()]
    Param (
        [Parameter(Mandatory=$True, ParameterSetName="Printer", Position=0)]
        [PSTypeName(‚Microsoft.Management.Infrastructure.CimInstance#ROOT/StandardCimv2/MSFT_Printer‘)]
        [ciminstance]
        $Printer,
        [Parameter(Mandatory=$True, ParameterSetName="PrinterName", Position=0)]
        [String]$PrinterName,

        [String]$Output,
        [Byte[]]$ByteArray,
        [String]$DocTitle = "Powershell RAW print",
        [String]$DataType
    )

    If ($PSCmdlet.ParameterSetName -eq "PrinterName") {
        $Printer = Get-Printer $PrinterName
    }

    #
    If (((-Not ($Output)) -and (-Not ($ByteArray)))) {
        throw "Need some data, either by providing -Output or -ByteArray"
    }

    If ($Output) {
        $ByteArray = [System.Text.Encoding]::ASCII.GetBytes($Output)
        Write-Verbose "converted Output via ASCII-Encoding into ByteArray"
    }

    # DOCInfo Struktur erzeugen
    $di=New-Object RawPrinterHelper+DOCINFOA

    If (-Not ($DataType)) {
        # https://support.microsoft.com/en-us/kb/2779300 defines XPS_PASS
        If ((Get-PrinterDriver -Name $Printer.DriverName).MajorVersion -eq 4) {
            $di.pDataType = "XPS_PASS"
        } else {
            $di.pDataType = "RAW"
        }
    } else {
        $di.pDataType = $DataType
    }
    Write-Verbose "Type: $($di.pDataType)"
    $di.pDocName= $DocTitle

    # benötigte Variablen
    $hPrinter=[IntPtr]::Zero
    $dwWritten=0
    $result = $false

    If ([RawPrinterHelper]::OpenPrinter($Printer.Name.Normalize(), [ref] $hPrinter, [intptr]::Zero)) {
        If ([RawPrinterHelper]::StartDocPrinter($hPrinter, 1, $di)) {
            #$result = [RawPrinterHelper]::StartPagePrinter($hPrinter)
            $pa=[System.Runtime.InteropServices.GCHandle]::Alloc($ByteArray, [System.Runtime.InteropServices.GCHandleType]::Pinned)
            $result = [RawPrinterHelper]::WritePrinter($hPrinter, $pa.AddrOfPinnedObject(), $ByteArray.Length, [ref] $dwWritten);$Win32Error =  [ComponentModel.Win32Exception][System.Runtime.InteropServices.Marshal]::GetLastWin32Error()
            # Win32Error, see http://www.exploit-monday.com/2016/01/properly-retrieving-win32-api-error.html
            Write-Verbose "$dwwritten Bytes sent to Printer ‚$($Printer.Name)‘, expected: $($ByteArray.Length)"
            $pa.Free()
            #$result = [RawPrinterHelper]::EndPagePrinter($hPrinter)
            $result = [RawPrinterHelper]::EndDocPrinter($hPrinter)
        }
        $result = [RawPrinterHelper]::ClosePrinter($hPrinter)
    }

}

Wie immer ist das Script nicht schön in dieser Darstellung aber es funktioniert per Copy&Paste.

Zunächst braucht man einen Druckernamen:

PS > Get-Printer| select Name

Name
—-
HP Officejet Pro X576 MFP PCL6
HP LaserJet A4/Letter PS Class Driver
HP Universal Printing PCL 6 (v6.3.0)
Microsoft XPS Document Writer
Microsoft Print to PDF
Fax
An OneNote 2013 senden

Nun wählt man am besten einen aus, in diesem Fall den ersten:

PS > $p=(get-printer)[0]
PS > $p

Name                           ComputerName    Type         DriverName
—-                           ————    —-         ———-
HP Officejet Pro X576 MFP PCL6                 Local        HP Officejet Pro X576

Nun kann man diesem Drucker Daten zukommen lassen:

$Schachttest ="$([char]27)&l4HSchacht1$([char]12)"+"$([char]27)&l1HSchacht2$([char]12)"

Out-RawPrinter –Printer $p –Output $Schachttest

Der etwas verkünstelte String druckt bei einem HP-Drucker zwei Seiten, eine vom Schacht1 (manueller) und eine vom Schacht2. Würde man in diesem Fall Out-Printer benutzen, dann würden die Steuerzeichen nicht interpretiert und als Text oder nichtdarstellbare Zeichen gedruckt.

Da die Umwandlung des Strings bei Out-RawPrinter mittels ASCII-Encoding stattfindet, stößt man auch schnell an eine Grenze, wenn man bestimmte Umlaute drucken möchte. Deshalb gibt es noch den Paramter –ByteArray anstatt –Output, somit kann man eine eigene Umwandlung durchführen und die Daten übergeben.

Dies kann man sich auch zunutze machen, wenn man einen Ausdruck in einer Datei umgelenkt hat und diese Datei dann später drucken möchte. Hier exemplarisch, wie man vorgeht:

$DruckDaten = Get-Content DruckDatei.PRN –Encoding Byte
Out-RawPrinter –Printer $p –ByteArray $DruckDaten

Neben diesen Möglichkeiten zur Kommunikation mit Druckern, möchte ich noch auf SNMP hinweisen, welches auch unter Windows 10 immer noch funktioniert, wie hier beschrieben: https://newyear2006.wordpress.com/2016/07/10/hp-netzwerkdrucker-per-remote-und-reboot-txt-neu-starten-nix-klappt-aber-snmp-bringt-die-lsung/.

Wie deaktiviert man Autorun in Windows

27 September 2011

Da gibt es viele Möglichkeiten. Einen guten Überblick bietet dieser KB-Artikel, leider kommt Windows 7 zu kurz: http://support.microsoft.com/kb/967715/en-us

Was es sonst noch so zum Thema gibt, spezifisch zu USB-Sticks: http://blog.meine-firma-und-ich.de/usb-sticks-sicher-machen/

RemoteFX in Hyper-V

10 Mai 2011

Hier ein paar Links zum verzwickten Thema RemoteFX

Guter Artikel mit Hintergründen was geht und was nicht:
http://blog.drtritsch.com/?p=145

Intel i3 und i5:
http://social.technet.microsoft.com/Forums/en/w7itproSP/thread/d15cd3c4-7d68-42e4-b5a2-0a44219279b5

Hardwareanforderungen im Technet:
http://technet.microsoft.com/en-us/library/ff817602(WS.10).aspx

USB-Redirecting bei RemoteFX:
http://blogs.msdn.com/b/rds/archive/2010/06/10/introducing-microsoft-remotefx-usb-redirection-part-1.aspx

Windows Vista, Windows 7, Windows XP Multiboot USB Stick erstellen

25 Januar 2010

Aufbauend auf den Artikel https://newyear2006.wordpress.com/2009/09/19/windows-vista-windows-7-multiboot-usb-stick-erstellen/ hier nun noch die fehlende Beschreibung wie man Windows XP noch auf den USB-Stick bekommt.

Um Windows XP zu installieren wird WINNT32.EXE aus dem I386-Verzeichnis benutzt. Dazu aber erstmal die Vorbereitung:

Auf dem aus den ersten Artikeln präparierten USB-Stick legt man ein Verzeichnis \i386 an und kopiert da den Inhalt von einer XP SP3 CD aus dem i386 Verzeichnis rein. X: sei wieder der Laufwerksbuchstabe des USB-Sticks und Y: der Laufwerksbuchstabe eines CD-ROM Laufwerks.

MD X:\I386

XCOPY Y:\I386\*.* /S X:\I386

Das wärs schon fast gewesen. Wenn man allerdings spezielle Anforderungen wie RAID-Treiber oder AHCI-Treiber für aktuelle SATA-Laufwerke hat, der sollte per nLite http://www.nliteos.com/ die aktuelle Version herunterladen und benötigte Treiber über den Punkt “Integrate Drivers” hinzufügen.

Wichtig: Bei der Auswahl des XP-Verzeichnis gibt man X:\I386 an. nLite meckert zwar, dass es sich nicht um eine vollständige XP-Installationsmedium handelt, aber das spielt keine Rolle.

So nun bootet man von seinem USB-Stick und startet am einfachsten Windows 7 Setup. Beim ersten Bildschirm mit der Regions- und Sprachauswahl drückt man Shift-F10 für die Eingabeaufforderung.

Jetzt ruft man DISKPART auf und wendet folgende Befehle an:

LIST DISK

SELE DISK 0

ACHTUNG bei DISK 0 muss die Nummer der Disk angegeben werden welche nachher die XP-Installation erhalten soll.

CLEAN

CREATE PART PRIM

FORMAT FS=NTFS QUICK

ASSIGN

LIST VOL

Nun sieht man welchen Laufwerksbuchstaben der USB-Stick hat und welchen Laufwerksbuchstaben die neue Partition bekommen hat.

Nachfolgend sei C: der Laufwerksbuchstabe von der neu erstellten Partition und D: sei der aktuelle Laufwerksbuchstabe des USB-Sticks.

Nun wechselt man ins i386-Verzeichnis mit

D:

CD \i386

und startet die XP-Installation mittels

WINNT32 /syspart:C: /tempdrive:C: /noreboot

Danach muss man noch ein paar Fragen beantworten und ab geht die Post. Wenn das erste grafische Setup beendet ist, taucht wieder die Win7 Installationsumgebung auf. Nun kann man per Eingabe von

wpeutil reboot

den Neustart des Rechners auslösen und es beginnt das gewohnte Windows XP Textmodus Setup.

USB Probleme in Windows 7 analysieren und verstehen

27 Dezember 2009

Heutzutage kommen immer mehr und mehr Geräte mit USB-Anschluss daher. Mittlerweile ist auch schon USB 3.0 mit Superspeed spezifiziert wobei Windows 7 noch keine Unterstützung von Haus aus mitbringt. Hier einige Infos zu USB 3.0 und Windows 7: http://www.usb.org/developers/presentations/pres1108/
SuperSpeed_USB_DevCon_Windows_USB_Update_GiustiAull.pdf

Was aber kann man machen wenn Geräte nicht erkannt werden oder nicht wie erwartet reagieren?

Eine Hilfe sind die neuen Log Möglichkeiten die in Windows Vista eingeführt wurden: http://blogs.msdn.com/wndp/archive/2006/03/28/wininet-etw-tracing-support-in-windows-vista.aspx

Mit dem Befehl logman.exe kann man quasi Mitschnitte von Ereignissen und Vorgängen erstellen lassen. Mit dem Befehl tracerpt.exe kann man die Datei dann z. B. in eine XML-Datei überspielen.

Eine bessere Variante ist aber mitterlweile mit dem Microsoft Network Monitor zu arbeiten, da dieser ETL-Dateien auch lesen und darstellen kann: http://blogs.technet.com/netmon/archive/2009/05/13/event-tracing-for-windows-and-network-monitor.aspx

Eine Auflistung was für Provider zur Verfügung stehen von denen Ereignisse verarbeitet werden können erhält man durch Eingabe von:

logman query provider

Übrigens kann man per logman auch die möglichen Provider eines Prozesses abfragen, somit kann man schneller entscheiden welche Provider bei einem aktuellen Problem überhaupt Sinn machen, z. B.:

logman query provider –pid 6431

Listet alle möglichen Provider auf die von dem Prozess mit der ID 6431 verwendet werden. Näheres erklärt: http://blogs.msdn.com/ntdebugging/archive/2009/09/08/exploring-and-decoding-etw-providers-using-event-log-channels.aspx

Um nun also USB Vorgänge aufzeichnen zu können gibt man folgenden Befehl ein:

logman start usbtrace –p Microsoft-Windows-USB-USBPort –o usbtrace.etl –ets
logman update usbtrace –p Microsoft-Windows-USB-USBHub –ets

Aber Vorsicht, da in der Regel heute die meisten Tastaturen und Mäuse ebenfalls per USB angeschlossen sind, bekommt man gleich mal eine Ladung an Daten nur wegen des Auslösevorgangs gesammelt!

Mittels

logman stop usbtrace –ets

wird der Vorgang dann abgeschlossen und man findet seine Daten in usbtrace.etl.

Was nun mittels Netmon herausgefunden werden kann, beschreibt dieser Artikel: http://blogs.msdn.com/usbcoreblog/archive/2009/12/21/answering-the-question-what-s-wrong-with-my-device-using-usb-etw.aspx

Primär wendet man einen USBHub Filter an, der einen auf einen Fehler bringt und von dort schaut man dann rückwärts und versucht das Problem zu finden.

Momentan ist alles noch recht mühsam, aber da die entsprechende Technik nun mittels Windows 7 voll zur Verfügung steht ist es sicherlich nur eine Frage der Zeit bis mehr und mehr Filter bzw. auch irgendwann Expertenmodule für Netmon entwickelt werden, die dann schnell weiterhelfen können.