Jump to content
Pikus1234

USB-Geräteabfrage nach bestimmten Geräten in Powershell

Empfohlene Beiträge

Hallo Ich hab hier eine schöne USB-Geräteabfrage gefunden die ich aber abändern müsste, weil ich nicht alle gefundenen Geräte bräuchte. Allerdings verstehe ich nicht ganz wie ich das genau filtern kann

 

Ich suche in der Abfrage also nach Manufacturer HP, Canon, etc. und will dann die DeviceID weiternutzen um dann in der Registry nach bestimmten Einträgen und somit die Seriennummer zu suchen. Viell hat hier jemand Hilfe für mich parat?

 $Computer = '.'


 gwmi Win32_USBControllerDevice -ComputerName $Computer | foreach-object {[wmi]($_.Dependent)} | Sort Caption,Manufacturer,Description,DeviceID `
| Ft -GroupBy Manufacturer Description,Service,DeviceID

#Ich möchte jetzt diese Ausgabe nach bestimmten Werten abgleichen:
#etwa in dieser Form

if(DeviceID -like oder -contains '*Canon*' oder 'HP'){

speicher es in die variable $Canongerät (evtl. gleich in die Registry Pfad xy) 
}else{
write-Output 'kein Gerät vorhanden'
}

#Dann würde ich mit dieser Variablen gern die Registry nach der Serial durchsuchen.
#Die Registrypfade habe ich mir schon zusammengesucht

 

Ich komme irgendwie nicht weiter die Propertys zu vergleichen. Bestimmt ein Denkfehler drin.

 

Hoffe ihr könnt mir helfen. :confused:  :thumb1:  :)

 

 

Diesen Beitrag teilen


Link zum Beitrag
Auf anderen Seiten teilen

Hallo,

ich habe mal eine Eventlog Abfrage gemacht, und dann nur die Felder Warnungen und Fehler übernommen.

Vielleicht hilft es ja.

Get-Eventlog "Application" | Where-Object {$_.EntryType -eq "Warning" -or $_.EntryType -eq "Error"} | Where-Object {($_.TimeWritten).Date -eq (Get-Date).Date} | Select-Object EntryType, TimeGenerated, EventID, Message | ConvertTo-HTML -title "Anwendungsereignisse Information" | Set-Content c:\PSSkript\application-report.html 

Diesen Beitrag teilen


Link zum Beitrag
Auf anderen Seiten teilen

Ich glaube das war nicht für mich gedacht. Zumindest kann mir das nicht weiterhelfen.

Ich bekomme dadurch nur einen Fehler bei der Anwendung eines Gruppenrichtlinienobjektes angezeigt.

Ist ja auch ein Auslesen aus den Event-Log´s.

 

Ich will wie gesagt eigentlich nur die angeschlossenen USB-Geräte auslesen. Dabei soll aber zusätzlich noch nach bestimmten Geräten gefiltert werden.

 

Ich suche nach entweder Manufacturer oder gleich DeviceID, alle anderen Geräte brauche ich nicht

 

Manufacturer 'HP', Manufacturer 'Samsung', Manufacturer 'Canon' gleiches gilt für DevicID, welche den korrekten Gerätenamen beinhaltet

 

Sollten diese Geräte lokal vorhanden sein = true , möchte ich dann anschließend die Serial´s dieser Geräte ermitteln.

 

Diese Abfrage stellt also nur erstmal fest ob so ein Gerät am PC ist und wie es heißt = Druckermodel

 

Daher sollte dieser Code, der super funktioniert, nur eine entsprechende Filterfunktion nach HP, Samsung und Canon erhalten, was ich nicht hinbekomme.

 $Computer = '.'

 gwmi Win32_USBControllerDevice -ComputerName $Computer | foreach-object {[wmi]($_.Dependent)} | Sort Caption,Manufacturer,Description,DeviceID `
| Ft -GroupBy Manufacturer Description,Service,DeviceID

Diesen Beitrag teilen


Link zum Beitrag
Auf anderen Seiten teilen
'%HP%', '%Samsung%', '%Canon%' | foreach{Get-WmiObject -Class win32_Printer -Filter "name like '$_'"}

sollte mit deiner Abfrage ähnlich funktionieren :)

bearbeitet von marcx2

Diesen Beitrag teilen


Link zum Beitrag
Auf anderen Seiten teilen
 $Computer = '.'


 gwmi Win32_USBControllerDevice -ComputerName $Computer | foreach-object {[wmi]($_.Dependent)} | Sort Caption,Manufacturer,Description,DeviceID `
| Ft -GroupBy Manufacturer Description,Service,DeviceID

 

Mach mal aus deinem "Sort" ein "Select-Object" und bis der interne Test funktioniert, macht man so wenig Argumente wie möglich. Ich würde das "-ComputerName $Computer" auch entfernen, bis das ganze lokal klappt.

bearbeitet von MurdocX

Diesen Beitrag teilen


Link zum Beitrag
Auf anderen Seiten teilen

Hallo,

jetzt aber, mit Filter. ;-)

$Computer = '.'

Get-WmiObject Win32_USBControllerDevice -ComputerName $Computer | foreach-object {[wmi]($_.Dependent)} | Where-Object -FilterScript { ($_.Manufaturer -eq "Canon") -or ($_.Manufacturer -eq "HP") } | Select-Object -Property Manufacturer,DeviceID  

Eventuell auch mal mit "Win32_USBController" probieren.

Greez


Mit meinem ersten Post, wollte ich Dir nur zeigen, wie ich filtere.

Aber die jungen Leute wollen ja alles komplett fertig vor die Nase gesetzt bekommen. ;-D

Diesen Beitrag teilen


Link zum Beitrag
Auf anderen Seiten teilen

Ich habe jetzt die USB-Abfrage generieren können. Das Thema hat wie gewünscht geklappt.

 

Als nächster Schritt soll nun explizit die Registry abgefragt werden, um die Seriennummer zu ermitteln. Aber da hab ich wieder so meine Probleme.

 

Und zwar klappt die Abfrage mit 1 Client-PC stets einwandfrei. Aber sobald es mehrere PC´s sein sollen, (Foreach-Schleife) stosse ich an meine Grenzen. 

 

Viell. hat da ja jemand den Durchblick und erkennt den Fehler??

#Einzelabfrage funktioniert einwandfrei: Beispielabfrage nach bestimmten Registryeintrag (hier Samsung-Geräte)
$Computers = "PC-Name","PC-Name""PC-Name"
foreach ($ComputerName in $Computers){
$SubKey = "SYSTEM\CurrentControlSet\services\usbprint\Enum"
$RegField="LocalMachine"
$RootType = [Microsoft.Win32.RegistryHive]::$RegField
$RootKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($RootType,$ComputerName)
$RegKey = $RootKey.OpenSubKey($SubKey)

 Try{
   $Value="0" 
   [Microsoft.Win32.RegistryValueKind]$RegistryValueKind=$RegKey.GetValueKind($Value)
   [String]$Data=$RegKey.GetValue($Value)
   "{0}   {1}   {2} `n" -f $Value,$RegistryValueKind,$Data
   #hier wird der registryschlüssel immer in 3 teile zerlegt mittels trennzeichen \ (Teil 3=Serial wird in PS aber durch Zählung 0,1,2..=2)
   $SamsungSerial = $Data.Split("\") 
 }Catch{
  "Ein Fehler ist aufgetreten. Wahrscheinlich ist ein Wert nicht vorhanden"
}
}#end foreach

#Ausgabe am Host
$SamsungSerial[2]

Fehlermeldung wenn ich das so ausprobiere:
#Exception calling "OpenRemoteBaseKey" with "2" argument(s): "Der Netzwerkpfad wurde #nicht gefunden.
#"
#At line:8 char:1
#+ $RootKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($RootType ...
#+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
#    + FullyQualifiedErrorId : IOException

Diesen Beitrag teilen


Link zum Beitrag
Auf anderen Seiten teilen
Firewall.. Sind auf der Maschine, auf die zugegriffen werden soll, auch die benötigten Ports offen?

 

Als Alternative einfach via Powershell auf die Maschine ( New-PSsession ) und dann die Keys per WMI oder Powershell auslesen.



Get-Item -Path HKLM:\SYSTEM\CurrentControlSet\Services\usbprint\enum

Diesen Beitrag teilen


Link zum Beitrag
Auf anderen Seiten teilen

Ja die Ports sind offen, denn ich kann ja einen einzelnen PC jederzeit korrekt abfragen.

 

Irgendwie scheint also die Schleife nicht zu funktionieren. Da liegt der Fehler scheinbar.

 

Ich dachte viell. siegt ein sehender den Fehler sofort.

 

Zeile 8, wo der Fehler passiert ist also die Zeile

$RootKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($RootType,$ComputerName)

Diesen Beitrag teilen


Link zum Beitrag
Auf anderen Seiten teilen

Das ist klar, deswegen hast du von mir eine Alternative bekommen. Warum .Net, wenn Powershell (der Befehl) schneller, einfacher und effektiver funktioniert?

Diesen Beitrag teilen


Link zum Beitrag
Auf anderen Seiten teilen

Ich glaube dieser Weg über die New-PSSession ist zwar möglich, aber nicht der richtige Weg. Es erscheint doch für größere Abfragemengen. (100 PC und mehr) nicht geeignet.

Der Aufbau von so vielen Verbindungen über WinRM ist ziemlich lang andauernd und ggf. bei den Clients fehlerbehaftet.

 

Ich wollte wie gesagt den o.g. Weg über open remotebasekey gehen und mir dadurch eine schnelle unkomplizierte Abfrage erhoffen. 

 

Stellt man das Script um, indem man die Foreach-Schleife löscht und als $ComputerName nur 1 Client-PC angibt, klappt es jedes mal super und schnell.

 

Der Fehler liegt einzig darin, dieses Script für mehrere PC´s umzustellen. Da habe ich mir Hilfe erhofft, dass jemand hier den richtigen Tipp für mich hat wie es gehen könnte.

 

 

 

Ich habe jetzt die USB-Abfrage generieren können. Das Thema hat wie gewünscht geklappt.

 

Als nächster Schritt soll nun explizit die Registry abgefragt werden, um die Seriennummer zu ermitteln. Aber da hab ich wieder so meine Probleme.

 

Und zwar klappt die Abfrage mit 1 Client-PC stets einwandfrei. Aber sobald es mehrere PC´s sein sollen, (Foreach-Schleife) stosse ich an meine Grenzen. 

 

Viell. hat da ja jemand den Durchblick und erkennt den Fehler??

#Einzelabfrage funktioniert einwandfrei: Beispielabfrage nach bestimmten Registryeintrag (hier Samsung-Geräte)
$Computers = "PC-Name","PC-Name""PC-Name"
foreach ($ComputerName in $Computers){
$SubKey = "SYSTEM\CurrentControlSet\services\usbprint\Enum"
$RegField="LocalMachine"
$RootType = [Microsoft.Win32.RegistryHive]::$RegField
$RootKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($RootType,$ComputerName)
$RegKey = $RootKey.OpenSubKey($SubKey)

 Try{
   $Value="0" 
   [Microsoft.Win32.RegistryValueKind]$RegistryValueKind=$RegKey.GetValueKind($Value)
   [String]$Data=$RegKey.GetValue($Value)
   "{0}   {1}   {2} `n" -f $Value,$RegistryValueKind,$Data
   #hier wird der registryschlüssel immer in 3 teile zerlegt mittels trennzeichen \ (Teil 3=Serial wird in PS aber durch Zählung 0,1,2..=2)
   $SamsungSerial = $Data.Split("\") 
 }Catch{
  "Ein Fehler ist aufgetreten. Wahrscheinlich ist ein Wert nicht vorhanden"
}
}#end foreach

#Ausgabe am Host
$SamsungSerial[2]

Fehlermeldung wenn ich das so ausprobiere:
#Exception calling "OpenRemoteBaseKey" with "2" argument(s): "Der Netzwerkpfad wurde #nicht gefunden.
#"
#At line:8 char:1
#+ $RootKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($RootType ...
#+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
#    + FullyQualifiedErrorId : IOException

Diesen Beitrag teilen


Link zum Beitrag
Auf anderen Seiten teilen

Ich glaube dieser Weg über die New-PSSession ist zwar möglich, aber nicht der richtige Weg. Es erscheint doch für größere Abfragemengen. (100 PC und mehr) nicht geeignet.

Der Aufbau von so vielen Verbindungen über WinRM ist ziemlich lang andauernd und ggf. bei den Clients fehlerbehaftet.

 

Ich arbeite nur so und es dauert ca. 1 Min für 120 Rechner.. Die Zeit sollte sein ;-) 

 

Als Tipp: Du kannst Abfragen auch als "Jobs" nutzen und diese später wieder abfragen. Ich ab mir so mein eigenes Deploymenttool geschrieben.

 

Vielleicht findet sich einer der den passenden Tipp hat. Ich kann Dir auf diesem Weg nicht weiterhelfen. Viel Erfolg  ;) 

Diesen Beitrag teilen


Link zum Beitrag
Auf anderen Seiten teilen

Erstelle ein Benutzerkonto oder melde dich an, um zu kommentieren

Du musst ein Benutzerkonto haben, um einen Kommentar verfassen zu können

Benutzerkonto erstellen

Neues Benutzerkonto für unsere Community erstellen. Es ist einfach!

Neues Benutzerkonto erstellen

Anmelden

Du hast bereits ein Benutzerkonto? Melde dich hier an.

Jetzt anmelden

×