flodsche
Goto Top

Mit Batchdatei Informationen auslesen und diese strukturiert in Excel ausgeben

Hallo,

ich habe folgendes Vorhaben:
Ich bin dabei ein Script zu schreiben welches zur Inventarerfassung der vorhandenen Computer dient.
D.h. es liest einige Computerdaten aus und speichert diese dann (bis jetzt) in einer Textdatei.
So sieht das Script aus:

@echo off
title Inventariesierungsscript
color 0C
echo.
echo.
echo.
echo Hallo %USERNAME%!
echo.
echo.
echo Programm erfasst nun, aus Inventariesierungs-Gruenden, Ihre Systemdaten.
echo Bitte Programm nicht manuell schliessen! Programm schliesst nach Ablauf selbst!
echo.
echo.
set Pfad= \\ivsserv08\prog\HOME\SPRINGMANN\RechnerInventarIVS\%Computername%.txt
::###Info Ausgabe###::
echo Benutzername: %Username% > %Pfad%
echo Computername: %Computername% >> %Pfad%
systeminfo | find /i "Urspr" >> %Pfad%  
systeminfo | find /i "Prozessor" >> %Pfad%  
systeminfo | find /i "mhz" >> %Pfad%  
systeminfo | find /i "Gesamter physikalischer Speicher" >> %Pfad%  
fsutil volume diskfree c: | find /i "Gesamtanzahl Bytes" >> %Pfad%  
::###Bestimmung OS###::
VER |find /i "Windows 95" >NUL   
IF NOT ERRORLEVEL 1 GOTO 95 
VER |find /i "Windows 98" >NUL   
IF NOT ERRORLEVEL 1 GOTO 98 
VER |find /i "Windows Millennium" >NUL   
IF NOT ERRORLEVEL 1 GOTO ME 
VER | find "XP" > nul   
IF %errorlevel% EQU 0 GOTO XP
VER | find "2000" > nul   
IF %errorlevel% EQU 0 GOTO 2000 
VER | find "NT" > nul   
IF %errorlevel% EQU 0 GOTO NT 
VER | find "Microsoft Windows [Version 6.0" > nul   
IF %errorlevel% EQU 0 GOTO Vista 
VER | find "Microsoft Windows [Version 6.1" > nul   
IF %errorlevel% EQU 0 GOTO W7 
VER | find "Microsoft Windows [Version 6.2" > nul   
IF %errorlevel% EQU 0 GOTO W8 
VER | find "Microsoft Windows [Version 5" > nul   
IF %errorlevel% EQU 0 GOTO 2003 
goto unknown 
:unknown
echo Betriebsystem:		Unbekanntes Betriebssystem >> %Pfad%
goto end
:95
echo Betriebsystem:		Microsoft Windows 95 >> %Pfad%
goto end
:98
echo Betriebsystem:		Microsoft Windows 98 >> %Pfad%
goto end
:ME
echo Betriebsystem:		Microsoft Windows Millennium >> %Pfad%
goto end
:NT
echo Betriebsystem:		Microsoft Windows NT >> %Pfad%
goto end
:2000
echo Betriebsystem:		Microsoft Windows 2000 >> %Pfad%
goto end
:XP
echo Betriebsystem:		Microsoft Windows XP >> %Pfad%
goto end
:Vista
echo Betriebsystem:		Microsoft Windows Vista >> %Pfad%
goto end
:W7
echo Betriebsystem:		Microsoft Windows 7 >> %Pfad%
goto end
:W8
echo Betriebsystem:		Microsoft Windows 8 >> %Pfad%
goto end
:2003
echo Betriebsystem:		Microsoft Windows 2003 >> %Pfad%
goto end
:end
wmic bios get version | find /i "HP" >> %Pfad%  
exit

Es gibt dann ungefähr das hier aus:

unbenannt


Nun der springende Punkt:
Es ist sehr umständlich bei mehreren 100 PC's immer jede einzelne Textdatei zu öffnen um eine gesuchte Information heraus zu suchen...
Ist es möglich die Ausgabe in eine csv oder am besten direkt in eine xls datei zu schreiben? Und das am besten in "eine" Datei.
Leider komm ich nicht drauf wie ich dem Batch script noch irgendwo Semikolons beifügen kann um eine trennung durch Spalten zu ermöglichen.

Es wäre perfekt wenn das ganze dann ungefähr so in der Art aussehen würde:

unbenannt2


grüße
Florian

Content-Key: 319778

Url: https://administrator.de/contentid/319778

Ausgedruckt am: 29.03.2024 um 05:03 Uhr

Mitglied: 131339
Lösung 131339 02.11.2016 aktualisiert um 10:40:47 Uhr
Goto Top
Viel zu umständlich... Die Infos ließt man heute direkt mit WMI aus
Als CSV ausgeben lässt sich das ganze dann per export-csv

Gruß Schluckauf
Mitglied: Pjordorf
Pjordorf 02.11.2016 um 11:12:20 Uhr
Goto Top
Hallo,

Zitat von @Flodsche:
Ist es möglich die Ausgabe in eine csv oder am besten direkt in eine xls datei zu schreiben? Und das am besten in "eine" Datei.
Nein, nicht mit BATCH (DOS). Mit anderen Werkzeuge wie WMI, VBS, Powershell ist es schon möglich.

Leider komm ich nicht drauf wie ich dem Batch script noch irgendwo Semikolons beifügen kann um eine trennung durch Spalten zu ermöglichen.
Na, hinter jeden Wert eben ein ; setzten. CSV made by hand. Eine CSV ist keine Excel Datei. Excel kann aber eine CSV datei recht gut erkennen und einlesen. CSV = Comma Seperatet Values ungleich ein .xlx(x) Dateiaufbau. Speichere mal ein leeres Excelblatt und schau dir die Datei an (im Editor). Das willst du nicht mit Batch nachbauen.
Powershell kennt aber wie es ein Excelblatt macht.

Es wäre perfekt wenn das ganze dann ungefähr so in der Art aussehen würde:
Das ist ein reines Excelblatt und hatz selbst mit einer CSV null zu tun, das CSV liefert höchstens die Daten/Werte aber keinerlei weitere Infos, wei Formatierung, Formeln usw.

Gruß,
Peter
Mitglied: Flodsche
Flodsche 02.11.2016 um 11:28:51 Uhr
Goto Top
Hi,

danke für die Antworten.
Hab mir schon halb gedacht, dass das mit einer Batch nicht realisierbar ist, bzw nur unter großen umständen.

Was Powershell angeht hab ich leider null Erfahrung, wusste nicht mal wie man einen Powershellcode ausführt. Hab es allerdings mal mit dem Code von "AnkhMorpork" (link) versucht, in dem ich ihn als .ps1 abgespeichert habe und mit "Windows PowerShell ISE" geöffnet habe. Wen ich ihn dort debugge gibt er mir wie gewünscht viele Informationen aus (zu viele, aber ich denke das bekomme ich selbst abgespeckt). Jetzt geht es halt nur wieder darum diese Informationen in einer, ich lege mich jetzt einfach fest, Excel Datei auszugeben. Lassen wir .csv einfach ganz außen vor.
Dabei geht es mir eigentlich nur um die Anordnung bezüglich Spalten/Zeilen, der rest ist egal. Bekommt man das nicht so realisiert wie auf dem Bild?

Das Script wird wen es fertig ist in die Log-In-Domäne gelegt, sprich es wird ausgeführt nachdem sich ein User in der Domäne anmeldet und diese Informationen sollen von jedem PC/Benutzer in diese eine Excel Datei geschrieben werden. Da wäre es Sinvoll eine gewisse Struktur und Übersichtlichkeit vor zu finden, damit man auch gezielt Informationen suchen kann, falls das nötig ist.

Was schlagt ihr vor?

Gruß
Florian
Mitglied: timlg07
timlg07 02.11.2016 um 23:08:00 Uhr
Goto Top
Naja wenn es nur um die Struktur und gezielte Informationensuche geht, lässt sich das ja auch mit einer .txt Datei realisieren. Mit ein bischen Stringmanipulation Tabstopps rein, vllt ein paar Sonderzeichen zum Trennen. So dass mans übersichtlich anschauen und mithilfe einer for schleife (+findstr) wieder einlesen/suchen kann. Aber um in Excel zu schreiben brauchste da was anderes.
LG Tim
Mitglied: Flodsche
Flodsche 04.11.2016 um 12:26:27 Uhr
Goto Top
Hi,

hab jetzt die powershell Version genommen, aus dem ersten link hier im Thread.
Hab das ganze angepasst (von den Informationen her) wie es mir passt.
Nun steh ich aber wieder vor dem gleichen Problem, wie bringe ich das jetzt in Excel? Geht dies mit Powershell nun einfacher?
Es muss auch nicht zwingend Excel sein, ein kleines Datenbank System auf zu bauen wäre sicher auch etwas geschicktes.
Es geht mir halt da drum das ich gewisse Aspekte suchen und Filtern kann, z.B. "Zeig mir alle Computer mit 8gb ram" oder "Zeig mir alle Computer, die vor 2012 Aufgesetzt wurden" etc. versteht ihr was ich meine?

Danke für eure Hilfe

Gruß
Florian
Mitglied: Pjordorf
Lösung Pjordorf 04.11.2016 um 18:43:14 Uhr
Goto Top
Mitglied: Flodsche
Flodsche 05.11.2016 um 17:53:59 Uhr
Goto Top
Hi Peter,

danke, ich werde mich mal durcharbeiten.

Gruß
Florian
Mitglied: Flodsche
Flodsche 08.11.2016 um 11:39:17 Uhr
Goto Top
Hi,

im Bezug auf den ersten Link, gibt es in diesem Script den Bereich:

Function Get-OSInfo
{
$Line + "BETRIEBSSYSTEM:"  
"-----------------"  
# collect OS data
$colItems = Get-WmiObject -class win32_OperatingSystem -Computername $Computer

ForEach($objItem in $colItems)
{
"Hersteller: " + $objItem.Manufacturer  
"Name: " + $objItem.Name  
"Version: " + $objItem.Version  
"Build Nummer: " + $objItem.BuildNumber  
"Build Typ: " + $objItem.BuildType  
"Code set: " + $objItem.CodeSet  
"System Ordner: " + $objItem.SystemDirectory  
"Gesammter Virtueler Speicher: " + [Math]::Round($objItem.TotalVirtualMemorySize/1MB,2) + " MB"  
"Seriennummer: " + $objItem.SerialNumber  
$Line
} #ForEach
} #Function

Ist es möglich beim OS auch noch das Datum der Installation von Windows auszugeben?

also zb. mit
$objItem.BuildDate
oderso (was nicht funktioniert hat)

Gruß
Florian
Mitglied: Flodsche
Flodsche 08.11.2016 um 14:59:33 Uhr
Goto Top
Hallo,

danke nochmal für die links, durch dass das ich noch nie mit Powershell gearbeitet hab, haben die Links mir sehr weitergeholfen.
Ich hab nun das Script fast so hinbekommen wie ich es wollte, aktuell sieht es so aus:

$ComputerSystem = Get-WmiObject -class win32_ComputerSystem
$DiskDrive = Get-WmiObject -class win32_DiskDrive
$VideoController = Get-WmiObject -class cim_PCVideoController
$Processor = Get-WmiObject -class win32_Processor
$OperatingSystem = Get-WmiObject -class win32_OperatingSystem
$Bios = Get-WmiObject -class win32_Bios
$NetworkAdapter = Get-WmiObject Win32_NetworkAdapterConfiguration
$excel = new-object -comobject excel.application
$excel.visible = $false
$workbook = $excel.workbooks.add()
$workbook.workSheets.item(3).delete()
$workbook.WorkSheets.item(2).delete()
$workbook.WorkSheets.item(1).Name = "RechnerInventar"  
$sheet = $workbook.WorkSheets.Item("RechnerInventar")  
$x = 2
$lineStyle = "microsoft.office.interop.excel.xlLineStyle" -as [type]  
$colorIndex = "microsoft.office.interop.excel.xlColorIndex" -as [type]  
$borderWeight = "microsoft.office.interop.excel.xlBorderWeight" -as [type]  
$chartType = "microsoft.office.interop.excel.xlChartType" -as [type]  
For($b = 1 ; $b -le 17 ; $b++) {
$sheet.cells.item(1,$b).font.bold = $true
$sheet.cells.item(1,$b).borders.ColorIndex = $colorIndex::xlColorIndexAutomatic
$sheet.cells.item(1,$b).borders.weight = $borderWeight::xlMedium }
For($a = 1 ; $a -le 2 ; $a++) {
$sheet.cells.item($a,1).font.bold = $true
$sheet.cells.item($a,1).borders.ColorIndex = $colorIndex::xlColorIndexAutomatic
$sheet.cells.item($a,1).borders.weight = $borderWeight::xlMedium }
$sheet.cells.item(1,1) = "Computername"  
$sheet.cells.item(1,2) = "Hersteller"  
$sheet.cells.item(1,3) = "Modell"  
$sheet.cells.item(1,4) = "Domain"  
$sheet.cells.item(1,5) = "RAM in GB"  
$sheet.cells.item(1,6) = "System Typ"  
$sheet.cells.item(1,7) = "Festpl. Vol. in GB"  
$sheet.cells.item(1,8) = "Grafikkarte"  
$sheet.cells.item(1,9) = "Prozessor"  
$sheet.cells.item(1,10) = "Proz. Geschw."  
$sheet.cells.item(1,11) = "Proz. Kerne"  
$sheet.cells.item(1,12) = "Betriebssystem"  
$sheet.cells.item(1,13) = "BIOS Datum"  
$sheet.cells.item(1,14) = "IPv4 Adresse"  
$sheet.cells.item(1,15) = "Subnetzmaske"  
$sheet.cells.item(1,16) = "Standard Gateway"  
$sheet.cells.item(1,17) = "MAC Adresse"  
Foreach($process in $ComputerSystem) {
$sheet.cells.item($x,1) = $process.Name
$sheet.cells.item($x,2) = $process.Manufacturer
$sheet.cells.item($x,3) = $process.Model
$sheet.cells.item($x,4) = $process.Domain
$sheet.cells.item($x,5) = [Math]::Round($process.TotalPhysicalMemory/1GB, 2)
$sheet.cells.item($x,6) = $process.SystemType
$x++ } #end foreach
Foreach($process in $DiskDrive) {
$sheet.cells.item($x2,7) =[Math]::Round($process.Size/1GB,2)
$x++ } #end foreach
Foreach($process in $VideoController) {
$sheet.cells.item($x2,8) = $process.Name
$x++ } #end foreach
Foreach($process in $Processor) {
$sheet.cells.item($x2,9) = $process.Name.Trim()
$sheet.cells.item($x2,10) = $process.CurrentClockSpeed
$sheet.cells.item($x2,11) = $process.NumberOfCores
$x++ } #end foreach
Foreach($process in $OperatingSystem) {
$sheet.cells.item($x2,12) = $process.Name
$x++ } #end foreach
Foreach($process in $Bios) {
$sheet.cells.item($x2,13) = $process.Version
$x++ } #end foreach
Foreach($process in $NetworkAdapter) {
$sheet.cells.item($x2,14) = $process.IPAddress
$sheet.cells.item($x2,15) = $process.IPSubnet
$sheet.cells.item($x2,16) = $process.DefaultIPGateway
$sheet.cells.item($x2,17) = $process.MACAddress
$x++ } #end foreach
$range = $sheet.usedRange
$range.EntireColumn.AutoFit() | out-null
IF(Test-Path "F:\HOME\SPRINGMANN\RechnerInventarIVS\Script\ComputerInfo.xlsx") {  
Remove-Item "F:\HOME\SPRINGMANN\RechnerInventarIVS\Script\ComputerInfo.xlsx"  
$Excel.ActiveWorkbook.SaveAs("F:\HOME\SPRINGMANN\RechnerInventarIVS\Script\ComputerInfo.xlsx") }  
ELSE { $Excel.ActiveWorkbook.SaveAs("F:\HOME\SPRINGMANN\RechnerInventarIVS\Script\ComputerInfo.xlsx") }  

Ein einziges Problem habe ich noch, das Script soll ja auf vielen verschiedenen Rechnern ausgeführt und die Daten gesammelt werden von den unterschiedlichen Rechnern.

Diese If Abfrage löscht ja aber die alte Datei und fügt ihren Eintrag nicht der Datei hinzu, wie ich mir das vorstelle:
IF(Test-Path "F:\HOME\SPRINGMANN\RechnerInventarIVS\Script\ComputerInfo.xlsx") {  
Remove-Item "F:\HOME\SPRINGMANN\RechnerInventarIVS\Script\ComputerInfo.xlsx"  
$Excel.ActiveWorkbook.SaveAs("F:\HOME\SPRINGMANN\RechnerInventarIVS\Script\ComputerInfo.xlsx") }  
ELSE { $Excel.ActiveWorkbook.SaveAs("F:\HOME\SPRINGMANN\RechnerInventarIVS\Script\ComputerInfo.xlsx") }  

Hier muss ich vermutlich auch noch was änderen, denn dort wird ja angegeben das die Informationen in die 2. Zeile geschrieben werden:
$x = 2
Ich möchte ja aber das die Informationen angehängt werden pro Script das auf einem Rechner gestartet wird, d.H. die Info's sollten immer in die nächst frei Zeile geschrieben werden. Wahrscheinlich geht das auch mit einer IF-Abfrage oder? Leider weiß ich nicht genau wie.

Kann mir vileicht jemand die Codes geben, bzw mir auf die Sprünge helfen?

Danke

Gruß
Florian