Jump to content

Pikus1234

Members
  • Gesamte Inhalte

    28
  • Registriert seit

  • Letzter Besuch

Alle erstellten Inhalte von Pikus1234

  1. Danke. Habe ich glatt übersehen. Mittlerweile habe ich schon den Weg über invoke-command probiert. Das klappt auch im Array soweit. Wie gesagt mit meinen Kenntnissen gelange ich noch oft an meine Grenzen. Noch habe ich die usb Abfrage nicht mit der registry Abfrage kombinieren können. Jede Abfrage für sich klappt super. Aber ich arbeite noch daran. Auch das ins csv exportieren zeigt immer wieder nicht das was ich am Host sehe. Nächste Baustelle die ich noch bearbeiten muss. Darum danke für eure Tipps. Die mir viel helfen.
  2. 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.
  3. Ist zwar eine neue Baustelle für mich, aber ich probiere mich mal damit aus wie weit ich komme. Vielen Dank für den Tipp erstmal. :thumb1:
  4. 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)
  5. 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
  6. 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
  7. 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: :)
  8. Leider klappt dieser Schritt nicht zufriedenstellend. Add-Content -Value....klappt aber die Ausgabe ist nicht wie gewünscht. PS scheint also alle PC entsprechend zu verarbeiten, als nur die Online-PC. Oder die Zuordnung bei der Dateispeicherung klemmt. Kurz gesagt.... Ich lasse also lieber doch die Schleifen und lese die PC wieder ein. Denn ehrlich gesagt dauert dieser Schritt gar nicht so lange. Schlimmer wird es ja in der Abfrageschleife $Inventory.... Hier habe ich, auch mit Hilfe von Euch ein Monitor-Array erstellt, um die bis zu 4 angeschlossene Monitore per WMI auslesen zu können. Das Problem ist jetzt: Wenn der PC einen WMI-Fehler aufweist und die Abfrage nicht klappt, muss ich diesen Fehler abfangen. Ihr hattet hier den Tipp gegeben es mit Try und Catch zu tun. Ich habe mich mal ausprobiert und versucht den Fehler in nachfolgender Form abzufangen.... Ideenratgeber war dazu: https://kevinmarquette.github.io/2017-04-10-Powershell-exceptions-everything-you-ever-wanted-to-know/#trycatch try {[ARRAY]$MonitorList = Get-WmiObject -Class WMIMonitorID -Namespace root\wmi -ComputerName $computer} catch {Write-Output $computer "kein Monitor erkannt"} Aber natürlich klappt das nur bedingt.....Das Script läuft zwar weiter durch (arbeitet alle PC ab) Aber wie kann ich jetzt noch dem "catch" mitteilen, dass ich dennoch zur CSV-Ausgabe eine Zeile mit dem PC-Namen erhalten will? Die anderen PC erzeugen ja entsprechende Ausgaben, welche anschließend in eine CSV-Datei gespeichert werden?! Nur 1 PC erzeugt also Fehler bei der WMI-Abfrage und in der Folge bei der Monitorarrayerstellung und erzeugt keine Zeile im CSV. Der PC fehlt mir in der CSV schlichtweg. Dennoch will ich auch diesen PC erfasst wissen. Mir würde also der Eintrag reichen : PCName ($Computer); "keine WMI-Abfrage möglich" oder ähnliches? Mhhh....Ich weiß = viele Fragen aber ich hoffe auf eure Hilfe hier und darf mich für die vielen schnellen Antworten bisher bedanken..... :thumb1: :) Hier nochmal die ganze Inventory-Abfrage und die erzeugten Fehlermeldung des 1. PC aus dieser Abfrage: $Inventory = foreach ($computer in $computers) { 12. $Bios = Get-WmiObject win32_bios -Computername $computer 13. $Hardware = Get-WmiObject Win32_computerSystem -Computername $computer 14. $Sysbuild = Get-WmiObject Win32_WmiSetting -Computername $computer 15. $OS = Get-WmiObject Win32_OperatingSystem -Computername $computer 16. $GUID = Get-wmiobject Win32_ComputerSystemProduct -Computername $computer | Select-Object -ExpandProperty UUID 17. $Networks = Get-WmiObject Win32_NetworkAdapterConfiguration -ComputerName $computer | Where-Object {$_.IPEnabled} 18. $driveSpace = Get-WmiObject win32_volume -Computername $Computer -Filter 'drivetype = 3' | 19. Select-Object PScomputerName, driveletter, label, @{LABEL='GBfreespace';EXPRESSION={'{0:N2}' -f($_.freespace/1GB)} } | 20. Where-Object { $_.driveletter -match 'C:' } 21. $cpu = Get-WmiObject Win32_Processor -Computername $computer 22. $CDROM = Get-WmiObject win32_CDROMDrive -ComputerName $computer 23. $Video = Get-WmiObject Win32_Videocontroller -ComputerName $computer -Filter "NOT name LIKE '%DameWare%'" |Select-Object 'Name*' 24. $username = Get-ChildItem "\\$computer\c$\Users" | Sort-Object LastWriteTime -Descending | Select-Object Name, LastWriteTime -first 1 25.#Fehler abfangen mit try und catch?! 26. try{[ARRAY]$MonitorList = Get-WmiObject -Class WmiMonitorID -Namespace root\wmi -ComputerName $Computer}catch{write-Output $Computer "keine WMI-Abfrage möglich"} 27. $PrinterHP = Get-WmiObject -Class Win32_Printer -ComputerName $Computer |Where-Object { $_.Local -like 'True' -and $_.Name -like 'HP*'}| Select-Object Name 28. $PrinterSamsung = Get-WmiObject -Class Win32_Printer -ComputerName $Computer |Where-Object { $_.Local -like 'True' -and $_.Name -like 'Samsung*'}| Select-Object Name 29. $PrinterCanon = Get-WmiObject -Class Win32_Printer -ComputerName $Computer |Where-Object { $_.Local -like 'True' -and $_.Name -like 'Canon*'}| Select-Object Name 30. 31. [PSCustomObject]@{ 32. ComputerName = $Computer.ToUpper() 33. Manufacturer = $Hardware.Manufacturer 34. Model = $Hardware.Model 35. Serial_Number = $Bios.serialnumber 36. MAC_Address = $Networks.MACAddress 37. Netboot_GUID = $GUID 38. IP_Address = $Networks.IpAddress[0] 39. Processor_Type = $cpu.Name 40. System_Type = $Hardware.SystemType 41. Total_Memory_GB = [math]::round($Hardware.TotalPhysicalMemory/1024/1024/1024, 2) 42. CDROM_Drive = $CDROM.Caption 43. Graphics = $Video.Name 44. Last_User = $username.Name 45. User_Last_Login = $username.LastWriteTime 46. 'C:_FreeSpace_GB' = $driveSpace.GBfreespace 47. Last_ReBoot = $OS.ConvertToDateTime($OS.LastBootUpTime) 48. Operating_System = $OS.Caption 49. Operating_System_Version = $OS.version 50. Operating_System_BuildVersion = $SysBuild.BuildVersion 51.# Fehler Abfangen wegen des Null-Arrays wenn die WMI-Abfrage nicht klappt 52. Monitor1Hersteller = If($MonitorList[0]){($MonitorList[0].ManufacturerName -notmatch '^0$' | ForEach-Object {[CHAR]$_}) -join ''}Else{'N/A'} 52. Monitor1Typ = If($MonitorList[0]){($MonitorList[0].UserFriendlyName -notmatch '^0$' | ForEach-Object {[CHAR]$_}) -join ''}Else{'N/A'} 53. Monitor1Seriennummer = If($MonitorList[0]){($MonitorList[0].SerialNumberID -notmatch '^0$' | ForEach-Object {[CHAR]$_}) -join ''}Else{'N/A'} 54. Monitor2Hersteller = If($MonitorList[1]){($MonitorList[1].ManufacturerName -notmatch '^0$' | ForEach-Object {[CHAR]$_}) -join ''}Else{'N/A'} 55. Monitor2Typ = If($MonitorList[1]){($MonitorList[1].UserFriendlyName -notmatch '^0$' | ForEach-Object {[CHAR]$_}) -join ''}Else{'N/A'} 56. Monitor2Seriennummer = If($MonitorList[1]){($MonitorList[1].SerialNumberID -notmatch '^0$' | ForEach-Object {[CHAR]$_}) -join ''}Else{'N/A'} 57. Monitor3Hersteller = If($MonitorList[2]){($MonitorList[2].ManufacturerName -notmatch '^0$' | ForEach-Object {[CHAR]$_}) -join ''}Else{'N/A'} 58. Monitor3Typ = If($MonitorList[2]){($MonitorList[2].UserFriendlyName -notmatch '^0$' | ForEach-Object {[CHAR]$_}) -join ''}Else{'N/A'} 59. Monitor3Seriennummer = If($MonitorList[2]){($MonitorList[2].SerialNumberID -notmatch '^0$' | ForEach-Object {[CHAR]$_}) -join ''}Else{'N/A'} 60. Drucker_HP = $PrinterHP.Name 61. Drucker_Samsung = $PrinterSamsung.Name 62. Drucker_Canon = $PrinterCanon.Name 63. } ### End PSCustomObject 64. 65.} ### End Foreach Computer 66. 67.$Inventory Fehler 1: Get-WmiObject : Nicht unterstützt At C:\test.ps1:26 char:36 + ... nitorList = Get-WmiObject -Class WMIMonitorID -Namespace root\wmi -Co ... Fehler 2: Cannot index into a null array. At C:\test.ps1:52 char:41 + Monitor1Hersteller = If($MonitorList[0]){($MonitorLis ... Ich hoffe nun auf eure Vorschläge.....Bedenkt bitte ich bin echter Newbie in Sachen Power Shell.
  9. Also ich stelle mich bei deiner Idee zu b***d an, da fehlt mir doch noch einiges Wissen offensichtlich. Ich erhalte nachfolgende Fehlermeldung.: Add-Content : The input object cannot be bound to any parameters for the command either because the command does not take pipeline input or the input and its properties do not match any of the parameters that take pipeline input. Ich hab es wie folgt versucht umzusetzen (streng an deinen Vorschlag) foreach ($computer in $testcomputers) { if (Test-Connection -ComputerName $computer -Quiet -count 1){ #hier liegt der Fehler weil das $computer ja wohl offensichtlich hier nicht verwendet werden kann. $computer| Add-Content -Value $computer "$PSScriptRoot\livePCs.txt" $Inventory = foreach ($computer in $computers) { $Bios = Get-WmiObject win32_bios -Computername $Computer} Wie gesagt das Ziel ist das Speichern der Live-PC in eine Datei um anschließend die Inventur mit diesen PC´s durchzuführen. Aber Wie?
  10. Danke für diese Seite, welche sehr aufschlussreich ist. Ich probiere mich aus. Super :thumb1: jetzt wo du es mir so erklärst klingt es doch schlüssig. Ich werde deinen Ansatz mal versuchen umzusetzen. Danke für den Tipp..... :thumb1: Ich lasse dich wissen ob ich es auch hinbekommen habe..... :D
  11. Erst mal danke für die Antwort, welche ja blitzschnell kam :p . Nun Ich habe die Dateien extra ausgegeben, damit ich die nicht erreichten PC´s und Online-PC trennen kann. diese PC´s können dann gesondert betrachtet, eingeschaltet und später abgefragt werden, ohne dass ich alle wiederholen müsste. Die Abfragemenge variiert schon stark je nach Anforderung. :) Und zum Fehler selbst lese ich mich natürlich ein. Über ein Beispiel in diesem speziellen Fall würde ich mich freuen, da ich sonst alle Hilfethemen sehr abstrakt finde und oftmals Verständnisprobleme dabei habe. Danke :jau:
  12. Hallo, Ich bin gerade dabei eine umfangreiche Inventory für Hardwareabfragen zu basteln. Jetzt komme ich leider nicht weiter und hoffe auf eure Hilfe. Im Script wird durch eine WMI-Abfrage eben ein Monitor-Array von bis zu 4 Monitoren abgefragt und erstellt. Das läuft auch, sofern der WMI der Remotemaschine läuft und Daten liefert Aber wenn der WMI nicht läuft und keine Daten liefert, bekomme ich entsprechende Fehlermeldungen, welche ich nun abfangen bzw. durch Ersatz auffüllen muss. Wer kann da helfen.... Weitere Fehler sind natürlich durch den nicht erfolgten Zugriff auf die WMI möglich.....viell. habe ich auch einen Denkfehler beim Aufbau drin. Ich bin noch nicht so fit in Powershell, weshalb ich eure Hilfe benötige. $testcomputers = '#Name des Remote-PC' # normal wird hier eine bestimmte txt.Datei eingelesen, welche mir die Namen liefert foreach ($computer in $testcomputers) { if (Test-Connection -ComputerName $computer -Quiet -count 1){ Add-Content -value $computer -Force "$PSScriptRoot\livePCs.txt" }else{ Add-Content -value $computer -Force "$PSScriptRoot\deadPCs.txt" } } $computers = #die PC-Namen aus der Liste "livePCs.txt" oder '#Name des Remote-PC' $Inventory = foreach ($computer in $computers) { $Bios = Get-WmiObject win32_bios -Computername $computer $Hardware = Get-WmiObject Win32_computerSystem -Computername $computer $Sysbuild = Get-WmiObject Win32_WmiSetting -Computername $computer $OS = Get-WmiObject Win32_OperatingSystem -Computername $computer $GUID = Get-wmiobject Win32_ComputerSystemProduct -Computername $computer | Select-Object -ExpandProperty UUID $Networks = Get-WmiObject Win32_NetworkAdapterConfiguration -ComputerName $computer | Where-Object {$_.IPEnabled} $driveSpace = Get-WmiObject win32_volume -Computername $Computer -Filter 'drivetype = 3' | Select-Object PScomputerName, driveletter, label, @{LABEL='GBfreespace';EXPRESSION={'{0:N2}' -f($_.freespace/1GB)} } | Where-Object { $_.driveletter -match 'C:' } $cpu = Get-WmiObject Win32_Processor -Computername $computer $CDROM = Get-WmiObject win32_CDROMDrive -ComputerName $computer $Video = Get-WmiObject Win32_Videocontroller -ComputerName $computer -Filter "NOT name LIKE '%DameWare%'" |Select-Object 'Name*' $username = Get-ChildItem "\\$computer\c$\Users" | Sort-Object LastWriteTime -Descending | Select-Object Name, LastWriteTime -first 1 #hier muss der Fehler abgefangen werden, dass es bei scheitern keine Daten gibt - es muss ersatzdaten geben::::::: [ARRAY]$MonitorList = $null $ MonitorList = $ null [ARRAY]$MonitorList = Get-WmiObject -Class WmiMonitorID -Namespace root\wmi -ComputerName $computer $PrinterHP = Get-WmiObject -Class Win32_Printer -ComputerName $Computer |Where-Object { $_.Local -like 'True' -and $_.Name -like 'HP*'}| Select-Object Name $PrinterSamsung = Get-WmiObject -Class Win32_Printer -ComputerName $Computer |Where-Object { $_.Local -like 'True' -and $_.Name -like 'Samsung*'}| Select-Object Name $PrinterCanon = Get-WmiObject -Class Win32_Printer -ComputerName $Computer |Where-Object { $_.Local -like 'True' -and $_.Name -like 'Canon*'}| Select-Object Name [PSCustomObject]@{ ComputerName = $Computer.ToUpper() Manufacturer = $Hardware.Manufacturer Model = $Hardware.Model Serial_Number = $Bios.serialnumber MAC_Address = $Networks.MACAddress Netboot_GUID = $GUID IP_Address = $Networks.IpAddress[0] Processor_Type = $cpu.Name System_Type = $Hardware.SystemType Total_Memory_GB = [math]::round($Hardware.TotalPhysicalMemory/1024/1024/1024, 2) CDROM_Drive = $CDROM.Caption Graphics = $Video.Name Last_User = $username.Name User_Last_Login = $username.LastWriteTime 'C:_FreeSpace_GB' = $driveSpace.GBfreespace Last_ReBoot = $OS.ConvertToDateTime($OS.LastBootUpTime) Operating_System = $OS.Caption Operating_System_Version = $OS.version Operating_System_BuildVersion = $SysBuild.BuildVersion Monitor1Hersteller = If($MonitorList[0]){($MonitorList[0].ManufacturerName -notmatch '^0$' | ForEach-Object {[CHAR]$_}) -join ''}Else{'N/A'} Monitor1Typ = If($MonitorList[0]){($MonitorList[0].UserFriendlyName -notmatch '^0$' | ForEach-Object {[CHAR]$_}) -join ''}Else{'N/A'} Monitor1Seriennummer = If($MonitorList[0]){($MonitorList[0].SerialNumberID -notmatch '^0$' | ForEach-Object {[CHAR]$_}) -join ''}Else{'N/A'} Monitor2Hersteller = If($MonitorList[1]){($MonitorList[1].ManufacturerName -notmatch '^0$' | ForEach-Object {[CHAR]$_}) -join ''}Else{'N/A'} Monitor2Typ = If($MonitorList[1]){($MonitorList[1].UserFriendlyName -notmatch '^0$' | ForEach-Object {[CHAR]$_}) -join ''}Else{'N/A'} Monitor2Seriennummer = If($MonitorList[1]){($MonitorList[1].SerialNumberID -notmatch '^0$' | ForEach-Object {[CHAR]$_}) -join ''}Else{'N/A'} Monitor3Hersteller = If($MonitorList[2]){($MonitorList[2].ManufacturerName -notmatch '^0$' | ForEach-Object {[CHAR]$_}) -join ''}Else{'N/A'} Monitor3Typ = If($MonitorList[2]){($MonitorList[2].UserFriendlyName -notmatch '^0$' | ForEach-Object {[CHAR]$_}) -join ''}Else{'N/A'} Monitor3Seriennummer = If($MonitorList[2]){($MonitorList[2].SerialNumberID -notmatch '^0$' | ForEach-Object {[CHAR]$_}) -join ''}Else{'N/A'} Drucker_HP = $PrinterHP.Name Drucker_Samsung = $PrinterSamsung.Name Drucker_Canon = $PrinterCanon.Name } ### End PSCustomObject } ### End Foreach Computer $Inventory #Wie erwähnt wird nun beim [ARRAY]$MonitorList = Get-WmiObject -Class WmiMonitorID #-Namespace root\wmi -ComputerName $computer ein Fehler gezeigt. #Get-WmiObject : Nicht unterstützt #At C:\Test\fehlerabfangen.ps1:25 char:31 #+ ... nitorList = Get-WmiObject -Class WmiMonitorID -Namespace root\wmi -Co ... #+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # + CategoryInfo : InvalidOperation: (:) [Get-WmiObject], ManagementException # + FullyQualifiedErrorId : #GetWMIManagementException,Microsoft.PowerShell.Commands.GetWmiObjectCommand # #Cannot index into a null array. #At C:\Test\fehlerabfangen.ps1:50 char:41 #+ Monitor1Hersteller = If($MonitorList[0]){($MonitorLis ... #+ ~~~~~~~~~~~~~~~ # + CategoryInfo : InvalidOperation: (:) [], RuntimeException # + FullyQualifiedErrorId : NullArray Unterste Zeilen im Code stellen die Fehlermeldung im Script dar. Danke für eure Unterstützung :thumb1: :) Pikus
  13. :schreck: :D :jau: so einfach kann es sein..... Ich sagte ja "Anfänger" grinsss. Da hab ich die Macht der geschweiften Klammern unterschätzt. Vielen Dank natürlich für den erfahrenen Weitblick. Jetzt bin ich tatsächlich hochauf und zufrieden mit dem Ergebnis. Also weiter im Text und schauen wie Drucker und Scanner sich finden lassen. Vielen Dank. Neue Fragen werden kommen. :thumb1: :thumb1: :thumb1: :thumb1:
  14. Link ist gespeichert und wird natürlich eingehend gesichtet. Nebenbei schau ich ja auch von Peter Kriegel die Youtube-Reihe "German Powershell Basis Video Tutorial. Also Stück für Stück wird's werden. Nun zum Script = Stand heute: Ich habe deinen Sciptvorschlag eingebaut und bin zu einem fast akzeptablen Ergebnis gelangt. Eine CimSession kann ich in unserem Netzwerk nicht eröffnen, weil die Ports wahrscheinlich nicht geöffnet sind, oder Dienste nicht entsprechend konfiguriert sind. Wie auch immer, es war keine Kommunikation über diesen Weg möglich. Ich habe weiter über den WMI der Rechner die Daten abgefragt. Mein vorläufig funktionierend fertiges Script. Nur der CSV-Export funktioniert nur korrekt, wenn ich es in 2 Dateien speichern lasse. Ich hätte gern nur 1 CSV-Datei. Daran arbeite ich jetzt noch. # *** THIS SCRIPT IS PROVIDED WITHOUT WARRANTY, USE AT YOUR OWN RISK *** $testcomputers = "PCHostName1", "PCHostname2" #oder Get-Content -Path 'C:\computers.txt' $exportLocation = 'C:\pcInventoryPC.csv' $exportLocation1 = 'C:\pcInventoryMon.csv' # PC Connection Test bevor die PC´s ihre Inventur bekommen (Wenn online = speichern in live-PCs.txt Start Inventory, wenn offline = Gespeichert in dead.pcs.txt = keine Aktion) foreach ($computer in $testcomputers) { if (Test-Connection -ComputerName $computer -Quiet -count 2){ Add-Content -value $computer -path C:\livePCs.txt }else{ Add-Content -value $computer -path C:\deadPCs.txt } } # Nun wissen wir welche PC online sind # Prozedur mit der Inventory $computers = Get-Content -Path 'C\livePCs.txt' $Inventory = foreach ($computer in $computers) { $Bios = Get-WmiObject win32_bios -Computername $computer $Hardware = Get-WmiObject Win32_computerSystem -Computername $computer $Sysbuild = Get-WmiObject Win32_WmiSetting -Computername $computer $OS = Get-WmiObject Win32_OperatingSystem -Computername $computer $Networks = Get-WmiObject Win32_NetworkAdapterConfiguration -ComputerName $computer | Where-Object {$_.IPEnabled} $driveSpace = Get-WmiObject win32_volume -computername $Computer -Filter 'drivetype = 3' | Select-Object PScomputerName, driveletter, label, @{LABEL='GBfreespace';EXPRESSION={'{0:N2}' -f($_.freespace/1GB)} } | Where-Object { $_.driveletter -match 'C:' } $cpu = Get-WmiObject Win32_Processor -computername $computer $username = Get-ChildItem "\\$computer\c$\Users" | Sort-Object LastWriteTime -Descending | Select-Object Name, LastWriteTime -first 1 $totalMemory = [math]::round($Hardware.TotalPhysicalMemory/1024/1024/1024, 2) $lastBoot = $OS.ConvertToDateTime($OS.LastBootUpTime) $IPAddress = $Networks.IpAddress[0] $MACAddress = $Networks.MACAddress $systemBios = $Bios.serialnumber [ARRAY]$MonitorList = Get-WmiObject -Class WMIMonitorID -Namespace root\wmi -ComputerName $computer [PSCustomObject]@{ ComputerName = $computer PCSerial = $Bios.serialnumber Monitor1Hersteller = If($MonitorList[0]){($MonitorList[0].ManufacturerName -notmatch '^0$' | ForEach-Object {[CHAR]$_}) -join ''}Else{'N/A'} Monitor1Typ = If($MonitorList[0]){($MonitorList[0].UserFriendlyName -notmatch '^0$' | ForEach-Object {[CHAR]$_}) -join ''}Else{'N/A'} Monitor1Seriennummer = If($MonitorList[0]){($MonitorList[0].SerialNumberID -notmatch '^0$' | ForEach-Object {[CHAR]$_}) -join ''}Else{'N/A'} Monitor2Hersteller = If($MonitorList[1]){($MonitorList[1].ManufacturerName -notmatch '^0$' | ForEach-Object {[CHAR]$_}) -join ''}Else{'N/A'} Monitor2Typ = If($MonitorList[1]){($MonitorList[1].UserFriendlyName -notmatch '^0$' | ForEach-Object {[CHAR]$_}) -join ''}Else{'N/A'} Monitor2Seriennummer = If($MonitorList[1]){($MonitorList[1].SerialNumberID -notmatch '^0$' | ForEach-Object {[CHAR]$_}) -join ''}Else{'N/A'} Monitor3Hersteller = If($MonitorList[2]){($MonitorList[2].ManufacturerName -notmatch '^0$' | ForEach-Object {[CHAR]$_}) -join ''}Else{'N/A'} Monitor3Typ = If($MonitorList[2]){($MonitorList[2].UserFriendlyName -notmatch '^0$' | ForEach-Object {[CHAR]$_}) -join ''}Else{'N/A'} Monitor3Seriennummer = If($MonitorList[2]){($MonitorList[2].SerialNumberID -notmatch '^0$' | ForEach-Object {[CHAR]$_}) -join ''}Else{'N/A'} } $OutputObj = New-Object -Type PSObject $OutputObj | Add-Member -MemberType NoteProperty -Name ComputerName -Value $Computer.ToUpper() $OutputObj | Add-Member -MemberType NoteProperty -Name Manufacturer -Value $Hardware.Manufacturer $OutputObj | Add-Member -MemberType NoteProperty -Name Model -Value $Hardware.Model $OutputObj | Add-Member -MemberType NoteProperty -Name Processor_Type -Value $cpu.Name $OutputObj | Add-Member -MemberType NoteProperty -Name System_Type -Value $Hardware.SystemType $OutputObj | Add-Member -MemberType NoteProperty -Name Operating_System -Value $OS.Caption $OutputObj | Add-Member -MemberType NoteProperty -Name Operating_System_Version -Value $OS.version $OutputObj | Add-Member -MemberType NoteProperty -Name Operating_System_BuildVersion -Value $SysBuild.BuildVersion $OutputObj | Add-Member -MemberType NoteProperty -Name Serial_Number -Value $systemBios $OutputObj | Add-Member -MemberType NoteProperty -Name IP_Address -Value $IPAddress $OutputObj | Add-Member -MemberType NoteProperty -Name MAC_Address -Value $MACAddress $OutputObj | Add-Member -MemberType NoteProperty -Name Last_User -Value $username.Name $OutputObj | Add-Member -MemberType NoteProperty -Name User_Last_Login -Value $username.LastWriteTime $OutputObj | Add-Member -MemberType NoteProperty -Name C:_FreeSpace_GB -Value $driveSpace.GBfreespace $OutputObj | Add-Member -MemberType NoteProperty -Name Total_Memory_GB -Value $totalMemory $OutputObj | Add-Member -MemberType NoteProperty -Name Last_ReBoot -Value $lastboot $OutputObj | Export-Csv $exportLocation -Append -NoTypeInformation -Force } $Inventory $Inventory | Export-Csv $exportLocation1 -Append -NoTypeInformation -Force #Wenn jetzt noch beide CSV-Dateien in eine zusammenverarbeitet werden können, ohne dass #die Daten verlorengehen (noClobber, Add-Content etc.) dann würde ich sagen = Super! Write-Host "Script beendet" Soweit meine Gedanken und Umsetzung zur Thematik. Abschließend ist diese Inventory natürlich noch nicht, denn weitere noch fehlende Hardware ist: angeschlossene Scanner und lokale Drucker mit Ihren Daten : Hersteller, Modell, Seriennummer. Aber das wird nach ersten Recherchen wohl verdammt schwierig. Hilfe ist natürlich auf jeden Fall erwünscht. :thumb1: :thumb1: :)
  15. Hallo Ihr Beiden, Natürlich melde ich mich nochmal. Und auch nachdem ich eure Gedanken umsetzen konnte. Heute komme ich leider nicht mehr dazu , und werde mich morgen wieder meinem Script widmen können. Natürlich sieht der Code recht komplex aus. Aber nicht vergessen......Copy and Paste by Google. Deshalb sieht´s besser aus als es ist. Ich verstehe im Groben ja auch was da passiert. Ich habe die einzelnen Schritte versucht in der PS.exe nachzuvollziehen. Da fehlt mir schon ein großes Stück wissen. Ich betreibe hier also Learning by Doing. Daher bin ich für jede gute Erklärung und Erkenntnis im Rahmen dessen glücklich. Aber ich bin lernwillig und fähig. Werde über die Fortschritte berichten und bestimmt wieder "anstrengende Fragen" haben, wo ich einfach auf Eure Hilfe hoffe. Mehr dazu wie gesagt ab Morgen. Vielen Dank :thumb1: :ph34r:
  16. Ja das würde ich gern in einer Schleife erledigen und gleich mit den Daten in eine CSV schreiben lassen. Leider fehlt mir dazu das KnowHow. Meine Versuche mittels Google und meinem Verständnis das umzusetzen habe ich nach 2 Tagen intensiven Testens aufgegeben. Deswegen bin ich doch jetzt auf Hilfe von Euch angewiesen. Maximal können in unserer Struktur 3 Displays am PC verwendet sein. (Die evtl. mit angeschlossenen Beamer werden hier nicht betrachtet.)
  17. Hallo an die Gemeinde und Wissenden hier. Ich hab wieder eine Frage an Euch. Ich möchte eine Hardwareinventur per Powershell bei mir aufbauen. 2 bekannte und gut funktionierende Scripte habe ich dazu gefunden und auf meine Bedürfnisse angepasst . 1.) PC Inventory 2.) EDID-Abfrage nach aktiven Monitoren des PC Nun sollen diese Scripte entsprechend die Daten in CSV ausgeben, damit SIe weiterverarbeitet werden können. Es ist dabei zu erwähnen, dass die PC aus einer txt.Datei ausgelesen, auf OnlineStatus geprüft und abgefragt werden. Bei der Ausgabe der Monitore zum PC komme ich aber an meine Grenze, denn ich bekomme den dazugehörigen Monitor nicht dem PC zugeordnet. Die Ausgabe in Powershell zeigt unter Computername immer alle Namen aus der o.g. Txt-Datei {Name,Name....} an und ordnet diesen nicht den gefundenen Monitoren korrekt zu. Hier gebe ich sicherlich die Objekte in der Pipeline falsch aus bzw. sortiere Sie nicht korrekt. Sicherlich ist die Lösung sooo einfach, aber ich komme (Anfänger pur) nicht auf die Lösung. #######Ab hier werden die ermittelten PC´s aus der txt-Datei ausgelesen! $computers = Get-Content -Path 'C:\livePCs.txt' foreach ($computer in $computers) { $Bios = Get-WmiObject win32_bios -Computername $Computer $Hardware = Get-WmiObject Win32_computerSystem -Computername $Computer $systemBios = $Bios.serialnumber $OutputObj = New-Object -Type PSObject $OutputObj | Add-Member -MemberType NoteProperty -Name ComputerName -Value $Computer.ToUpper() $OutputObj | Add-Member -MemberType NoteProperty -Name Serial_Number -Value $systemBios #####Nun werden diese Daten in eine CSV gespeichert und weiter zu den Monitoren.... ###################### ab hier werden Infos über die angeschlossenen Monitore gesammelt $computer = Get-Content -Path 'C:\livePCs.txt' $ActiveMonitors = Get-WmiObject -Namespace root\wmi -Class wmiMonitorID -ComputerName $computer $monitorInfo = @() $Serial_Number = $systemBios $ComputerName = $Computer $i= 1 foreach ($monitor in $ActiveMonitors) { $mon = $null $mon = New-Object PSObject $manufacturer = $null $dspserial = $null $name = $null $week = $null $year = $null $monitor.ManufacturerName | foreach {$manufacturer += [char]$_} $monitor.SerialNumberID | foreach {$dspserial += [char]$_} $monitor.UserFriendlyName | foreach {$name += [char]$_} $mon | Add-Member NoteProperty ComputerName $Computer.ToUpper() $mon | Add-Member NoteProperty Serial_Number $systemBios $mon | Add-Member NoteProperty Manufacturer $manufacturer $mon | Add-Member NoteProperty SerialNumber $dspserial $mon | Add-Member NoteProperty Name $name $mon | Add-Member NoteProperty Week $monitor.WeekOfManufacture $mon | Add-Member NoteProperty Year $monitor.YearOfManufacture $mon.SerialNumber = $dspserial.trim() $monitorInfo += $mon $i++ } #Hier sieht man im Output, wenn es mehr als 1 PC ist, dass die Ausgabe falsch ist und #zwar exakt die Ausgabe der PC-Daten zum Array der Monitore. #Wer kann helfen die Zuordnung mit anschließendem Export zu CSV zu komplettieren. Write-Output $monitorInfo #Ausgabe ist: # Die Monitore sind stimmig = nur die PC und Seriennummer-Zuordnung ist fehlerhaft #ComputerName : {xxxxxxx, xxxxxxxxx} #PCSerial : xxxxxxxx - nur 1 Seriennummer des 1. PC leider #Manufacturer : GSM #SerialNumber : 609NTUW6W678 #Name : 22MB65 #Week : 9 #Year : 2016 #ComputerName : {xxxxxxx, xxxxxxxxx} #PCSerial : xxxxxxxx - nur 1 Seriennummer des 1. PC leider (wieder dieselbe S/N) #Manufacturer : GSM #SerialNumber : 609NTAB6W680 #Name : 22MB65 #Week : 9 #Year : 2016 Ich hoffe hier hat jemand das Problem erkannt und kann mir helfen die Ausgabe der Daten zu korrigieren, Nämlich zu jeden erkannten Monitor muss der korrekte PC mit Seriennummer zugeordnet werden. Natürlich wäre es noch schöner wenn die Ausgabe-CSV der PC Daten mit der Ausgabe der Monitordaten nur ergänzt würde. Aber da bin ich gänzlich gescheitert und hab das erst mal verworfen, weil mir das KnowHow fehlt. Trotz Google war nichts zu machen. MfG Pikus
  18. Hallo, Ich möchte gern ein Script entwickeln, das über Eingabefelder PC-Namen aufliefert, welche dann weiterverarbeitet werden können. ICh muss dazu sagen, Powershell-Anfänger pur! Die Dialogbox soll eben die Eingabe grafischer darstellen. Die eingegebenen PC-Namen sollen nun auf ihren Online-Status überprüft werden und anschließend entsprechend die Hardware abgefragt werden. 1.) Eingabe der Namen über eine Messagebox 2.) Test auf Online-Status mit Bestätigung (Rücklieferung der IP-Adresse aktuell) 3.) Bei Offlinestatus soll das Script sich beenden bzw. keine weitere Abfrage starten 4.) Bei Onlinestatus dann Abfrage der Hardware incl. Speicherung in einer Excel-Tabelle ICh habe die Hardwareabfrage schon fertig. Die Daten kann ich bereits auslesen. Leider gelingt mir 1 - 3 niocht so richtig. ICh schaffe es nicht die eingegebenen Daten weiter zu verarbeiten, da hab ich wohl einen Denkfehler drin oder komme nicht weiter, da egal welchen Wert ich verwende der Ping nicht läuft. function button ($title,$PC1, $PC2, $PC3) { ###################Load Assembly for creating form & button###### [void][System.Reflection.Assembly]::LoadWithPartialName( “System.Windows.Forms”) [void][System.Reflection.Assembly]::LoadWithPartialName( “Microsoft.VisualBasic”) #####Define the form size & placement $form = New-Object “System.Windows.Forms.Form”; $form.Width = 500; $form.Height = 150; $form.Text = $title; $form.StartPosition = [System.Windows.Forms.FormStartPosition]::CenterScreen; ##############Define text label1 $textLabel1 = New-Object “System.Windows.Forms.Label”; $textLabel1.Left = 25; $textLabel1.Top = 15; $textLabel1.Text = $PC1; ##############Define text label2 $textLabel2 = New-Object “System.Windows.Forms.Label”; $textLabel2.Left = 25; $textLabel2.Top = 50; $textLabel2.Text = $PC2; ##############Define text label3 $textLabel3 = New-Object “System.Windows.Forms.Label”; $textLabel3.Left = 25; $textLabel3.Top = 85; $textLabel3.Text = $PC3; ############Define text box1 for input $textBox1 = New-Object “System.Windows.Forms.TextBox”; $textBox1.Left = 150; $textBox1.Top = 10; $textBox1.width = 200; ############Define text box2 for input $textBox2 = New-Object “System.Windows.Forms.TextBox”; $textBox2.Left = 150; $textBox2.Top = 50; $textBox2.width = 200; ############Define text box3 for input $textBox3 = New-Object “System.Windows.Forms.TextBox”; $textBox3.Left = 150; $textBox3.Top = 90; $textBox3.width = 200; #############Define default values for the input boxes $defaultValue = “” $textBox1.Text = $defaultValue; $textBox2.Text = $defaultValue; $textBox3.Text = $defaultValue; #############define OK button $button = New-Object “System.Windows.Forms.Button”; $button.Left = 360; $button.Top = 80; $button.Width = 100; $button.Text = “Ok”; #############define cancel button $button1 = New-Object “System.Windows.Forms.Button”; $button1.Left = 360; $button1.Top = 15; $button1.Width = 100; $button1.Text = “cancel”; ############# This is when you have to close the form after getting values $eventHandler = [System.EventHandler]{ $textBox1.Text; $textBox2.Text; $textBox3.Text; $form.Close();}; $button.Add_Click($eventHandler) ; $button1.Add_Click($eventHandler) ; #############Add controls to all the above objects defined $form.Controls.Add($button); $form.Controls.Add($button1); $form.Controls.Add($textLabel1); $form.Controls.Add($textLabel2); $form.Controls.Add($textLabel3); $form.Controls.Add($textBox1); $form.Controls.Add($textBox2); $form.Controls.Add($textBox3); $ret = $form.ShowDialog(); #################return values $textBox1.Text, $textBox2.Text, $textBox3.Text } $return= button “PC Namen mit Suffix eintragen!” “PC Namen 1” “PC Namen 2” “PC Namen 3” $return[0] $return[1] $return[2] ##############egal was ich beim Ping einsetze, bekomme ich keinen Ping mit den Return-##############Werten hin? $ping = Test-Connection ???????? -quiet foreach($p in $ping) { if ($p -eq $false) { [System.Windows.Forms.MessageBox]::Show("PC nicht errerichbar!","PC-Status",0) } } Viell. könnte jemand hier helfend ein paar Tipps geben?
  19. Au ersteinmal vielen Dank für die unkomplizierte Hilfe. Ich habe deinen Vorschlag jetzt mal gespeichert und probiere mich mal daran aus. Nur als Zusatz habe ich das Problem, so profan es auch klang, gelöst und das Script läuft nun wie es soll. Am Ende muss es lauten: if IPadr = "" then MsgBox "Von " & PCname & " konnte die IP-Adr. nicht ermittelt werden! Ursache: Offline oder Abbruch", , WScript.ScriptName if not IPadr = "" then MsgBox PCname & " hat die IP-Adr. " & IPadr , , WScript.ScriptName if IPadr = "" then Wscript.quit Nur falls jemand überhaupt daran interessiert sein sollte. Am Ende war es so einfach dass man darauf nur zuletzt kommt. Jetzt werde ich doch mehr in Richtung Powershell schauen und mich daran versuchen. Vielen Dank allen Mitdenkenden. :thumb1: LG :jau: :)
  20. Schade sunny, ich habe versucht alle Eventualitäten schriftlich in meinem Post zu erfassen. Es ging auch nicht darum, dass mir jemand bei der Neuausrichtung der Admin-Struktur oder Ähnlichem hilft. ICh wollte hier ein Script erarbeiten, welches im Bedarfsfall eine schnelle Hilfe darstellt. Und dazu benötige ich eben die nette Hilfe hier im Forum. Stand bisher dazu ist: Das Script tut schon seine Arbeit wie es soll. Allerdings habe ich es noch nicht geschafft das Script sauber zu beenden, wenn der Remotehost nicht erreichbar ist. Noch will das Script weiter den Dienst neu starten. Darum sollte ja die Routine vorher die IP ermitteln und so den Onlinestatus checken. Jetzt muss es aber heißen. if IPadr = "" then MsgBox "Von " & PCname & " konnte die IP-Adr. nicht ermittelt werden! Ursache: Offline oder Abbruch", , WScript.ScriptName dann beende dich an dieser Stelle!!!! Weder Exit noch End Sub klappen. Bei Wscript.quit beendet sich leider das Script auch wenn der Remotehost online ist. Ist der Remotehost online..... if not IPadr = "" then MsgBox PCname & " hat die IP-Adr. " & IPadr , , WScript.ScriptName dann soll ja der Dienst neu gestartet werden. Viell. hat hier jemand eine schnelle unkomplizierte Hilfe für mich parat. :)
  21. Vielen Dank für die anregende Diskussion wer was machen soll/darf. Bei uns ist dies etwas anders geregelt. Künftige Ausrichtungen sehen viell. andere Möglichkeiten für den HelpDesk vor. Derzeit sind sie begrenzt. Die Domainadmins kümmern sich um nicht um die Clients. Dafür ist der Netzwerkaufbau einfach zu groß. Für die Clients sind letztlich wie erwähnt die Workstation-Admins zuständig. Der HelpDesk ist nur 1. Anlaufpunkt zur Erfassung des Problems und Steuerung in den jeweiligen Fachbereich. (mit vereinfachten administrativen Aufgaben). Der WorkstationAdmin hat eben sämtliche Endgerätetechnik zu administrieren. Ich bin also auch nur ein Teil des Ganzen. Bei der Fülle an Problemen in solch einem großen Netzwerk sind die kleinsten Hilfen auf Arbeitsebene immer hilfreicher als einen Incident auszulösen um Fachbereiche mit einem Dienst-Neustart zu belasten. Also helfen kleine Batches und Scripte immer mal die Arbeit zu erleichtern. So kleines Update-----Ich hab die VBS ans Laufen bekommen. Sie tut was Sie soll. Jetzt fehlt mir nur noch das Stoppen des gesamten Scripts, wenn der PC offline ist. Derzeit will das Script immer noch den Dienst neu starten. Danke aber erstmal für die Ansätze von Euch. Powershell wollte ich mir ohnehin mal ansehen. Gruß Jan
  22. Und diese Batch soll dann entsprechend 1200 Rechner prüfen? Verstehe ich das richtig? Das Problem ist ja leider nicht auf 1 PC oder auf zeitliche Regeln zu reduzieren, Meist ruft ja der AW an und meldet sein Problem. Das Script ist dann die Hilfe zur Hilfe. Eine GPO oder einen Taskplaner zu implementieren wäre nicht der Ansatz den ich verfolge. Ich hoffe ich habe deinen Post korrekt interpretiert. :)
×
×
  • Neu erstellen...