Jump to content
Kuddel071089

Variablen in CSV exportieren

Recommended Posts

Hallo zusammen,

 

ich habe für unsere Server einen kleinen WSUS Report geschrieben der pro Server folgenden Infos abfragt:

 

Servername

Funktion

Letzte Update Installation - Datum

Letzte Update Installation - Uhrzeit

Neustart nötig

Ausstehende Updates

Betriebssystem

Laufzeit

Startdatum

Startzeit

Abfragezeit

 

Die Infos werden jeweils in eine eigene Variable gespeiochert und am Ende der Schleife per Out-File in eine *.csv geschrieben.

 

 

Jetzt würde ich gern den ganzen Report direkt in eine formatierte CSV-Datei schreiben, so dass man die Datei direkt in Excel und große Formatierung (Text in Saplten) lesen kann.

 

Wie genau bekomme ich das hin?

 

 

 

Vielen Dank schon einmal

 

Share this post


Link to post
Share on other sites

Moin,

 

wie sieht denn dein Skript aus? Es gibt eine ganze Reihe von Möglichkeiten, aber vermutlich lassen sich einige davon einfacher in deinem Skript implementieren als andere.

 

Gruß, Nils

 

Share this post


Link to post
Share on other sites

Ich hoffe das Skript ist nicht all zu unübersichtlich ^^

 






cls
$host.ui.RawUI.WindowTitle = "WSUS Auswertung AD ausführlich v0.6"

#Mailvariablen
$Mailempfaenger= "IB1-MS-Admin@xxxx.de"
$cc = "xxxx@xxxx.de"
$smtpserver = "outlook.xxxx.de"
$absender = "VNTS413@xxxx.de"

#Startzeit für den Mailbody
$startuhrzeit = Get-Date -Format HH:mm

#Modul zur Updateabfrage importieren
Import-Module C:\Windows\System32\WindowsPowerShell\v1.0\Modules\PendingUpdates\Get-PendingUpdate.ps1 -Force

$servers = Get-ADComputer -Filter {OperatingSystem -like "Windows Server*" -and Name -notlike "VNTS2*" -and name -notlike "L*" -and Name -like "*NTS*" -or Name -like "VN4*"} | Sort

#Erstellung der Reportdatei für die Mail
$datum = Get-Date -Format dd.MM.yyyy
$report = "C:\WSUS_Report_$datum.csv"

#Alte Reports löschen
if(Test-Path $report) {Remove-Item $report}


#$output =
foreach($server in $servers) {
#Zurücksetzten der Variablen
if($funktion) {Remove-Variable -Name funktion}
if($datum) {Remove-Variable -Name datum}
if($reboot) {Remove-Variable -Name reboot}
if($os) {Remove-Variable -Name os}
if($updates) {Remove-Variable -Name updates}

#Abfrage der Serverinfos
$serverinfos = Get-ADComputer $($server.Name) -Properties *
$os = $serverinfos.operatingsystem
$funktion = $serverinfos.description

#Abfrage der WSUS-Gruppe
$wsusgruppe = Get-ADComputer $($server.name) -Properties *
if($wsusgruppe.Memberof -like "*Role-GPO-Server-IB1-WSUS-ManInst*") {$wsusgruppe = "ManInst"}
if($wsusgruppe.Memberof -like "*Role-GPO-Server-IB1-WSUS-Autoboot-3-Uhr*") {$wsusgruppe = "Autoboot-3-Uhr"}
if($wsusgruppe.Memberof -like "*Role-GPO-Server-IB1-WSUS-Autoboot-4-Uhr*") {$wsusgruppe = "Autoboot-4-Uhr"}
if($wsusgruppe.Memberof -like "*Role-GPO-Server-IB1-WSUS-Autoboot-11-Uhr*") {$wsusgruppe = "Autoboot-11-Uhr"}
if($wsusgruppe.Memberof -like "*Role-GPO-Server-IB1-WSUS-Autoboot-So-3-Uhr*") {$wsusgruppe = "Autoboot-So-3-Uhr"}
if($wsusgruppe.Memberof -like "*Role-GPO-Server-IB1-WSUS-Default*") {$wsusgruppe = "Default"}

#Aktuelle Uhrzeit
$abfragezeit = Get-Date -Format HH:mm


    #Abfragen nur ausführen, wenn der Server erreichbar ist
    if(Test-Connection $($server.Name) -Quiet) {
    ""
    
    Write-Host "+++ $($server.name) / $funktion +++" -ForegroundColor Yellow
    
    
    
    Write-Host "-Abfrage Installatonsdatum letztes Update: " -ForegroundColor Cyan -NoNewline
    #Letzten installatonszeitpuntk abfragen
    #if(Get-WUHistory -ComputerName $($server.Name) -EA SilentlyContinue) {
        $wuabfrage = Get-WUHistory -ComputerName $($server.Name) | Select-Object -first 1
        #Umwandel des Installationszeitpunktes in deutsche Uhrzeit
        $datum = $wuabfrage.Date

        if($datum) {    
        #Umwandel des Installationszeitpunktes in deutsche Uhrzeit
        $datum = $wuabfrage.Date
        #2 Stunden rauf rechnen, damit die Auswertung passt
        $date = $datum.ToString("dd.MM.yyyy")
        $uhrzeit =  (get-Date $datum).AddHours(2).ToString("HH:mm:ss")
        Write-Host "OK" -ForegroundColor Green}
        else{$datum = $null}
        #}

    Write-Host "-Abfrage Reboot nötig: " -ForegroundColor Cyan -NoNewline
    #Check, ob ein Reboot nötig ist
    if(Get-WURebootStatus -ComputerName $($server.Name) -EA SilentlyContinue) {
        $reboot = Get-WURebootStatus -ComputerName $($server.Name) -Silent
        #Konvertieren des Status
        if($reboot -eq "True") {$reboot = "ja"}
        if($reboot -ne "True") {$reboot = "nein"}
        
        Write-Host "OK" -ForegroundColor Green
      }
    

 

    Write-Host "-Abfrage ausstehende Updates: " -ForegroundColor Cyan -NoNewline
    


    #Wenn die Abfrage Get-PendingUpdate nicht funktioniert
        $updates = Invoke-Command -Computer $($server.Name) -ArgumentList $($server.Name) -ScriptBlock {
        $computer = $args[0]
        # Abfrage mit COM-Objekt
        $Searcher = New-Object -ComObject Microsoft.Update.Searcher
        $Criteria = "IsInstalled=0 and Type='Software'"
        $SearchResult = $Searcher.Search($Criteria).Updates
        $SearchResult.Count
        }

        Write-Host "OK" -ForegroundColor Green -nonewline


    #Auslesen der Uptime
    Function Get-Uptime {
        #Nur ausführen, wenn die Uptime ausgelesen werden kann
        if(Get-WmiObject win32_operatingsystem -ErrorAction SilentlyContinue -Computername $($server.Name)) {
            $os = Get-WmiObject win32_operatingsystem -ErrorAction SilentlyContinue -Computername $($server.Name)
            $uptime = (Get-Date) - $os.ConvertToDateTime($os.LastBootUpTime)
            $days = $uptime.Days
            $hours = $uptime.Hours
            $minutes = $uptime.Minutes
            if($days -gt 1 -or $days -eq 0) {$tage = "$days Tage"} else {$tage = "$days Tag"}
            if($hours -gt 1 -or $hours -eq 0) {$stunden = "$hours Stunden"} else {$stunden = "$hours Stunde"}
            if($minutes -gt 1 -or $minutes -eq 0) {$minuten = "$minutes Minuten"} else {$minuten = "$minutes Minute"}
        }
        $uptime = "$tage $stunden $minuten"
        Return $uptime
    }
    $uptime = Get-Uptime
    


    #Auslesen des Bootdate
    Function Get-Bootdate {
    $os = Get-WmiObject win32_operatingsystem -ErrorAction SilentlyContinue -Computername $($server.Name)
    $bootdate = $os.ConvertToDateTime($os.LastBootUpTime)
    $bootdate = $bootdate.ToString("dd.MM.yyyy")
    Return $bootdate
    }
    $bootdate = Get-Bootdate
    if(!($bootdate)) {$bootdate = $null}

    #Auslesen der Bootzeit
    Function Get-Boottime {
    $os = Get-WmiObject win32_operatingsystem -ErrorAction SilentlyContinue -Computername $($server.Name)
    $boottime = $os.ConvertToDateTime($os.LastBootUpTime)
    $boottime = $boottime.ToString("HH:mm:ss")
    Return $boottime
    }
    $boottime = Get-Boottime
    if(!($boottime)) {$boottime = $null}


    ""
    }

    else{
    $date = $null
    $uhrzeit = $null
    $reboot = $null
    $updates = $null
    $uptime = $null
    $boottime = $null
    $bootdate = $null
    }

""
$servername = $($server.Name)

New-Object -TypeName PSObject -Property @{

        Servername = $servername
        Funktion = $funktion
        LetzteUpdateInstallationDatum = $date
        LetzteUpdateInstallationUhrzeit = $uhrzeit
        Neustartnoetig = $reboot
        AusstehendenUpdates = $updates
        Betriebssystem = $os
        WSUSADGruppe = $wsusgruppe
        Laufzeit = $uptime
        Startdatum = $boottime
        Startzeit = $bootdate
        Abfragezeit = $abfragezeit
        } | Export-CSV -Path $report -notypeinformation -Encoding UTF8 -Append
     
    

}

 

#Report versenden

#Endzeit für Mail
$enduhrzeit = Get-Date -Format HH:mm
$body = "Startzeit: $startuhrzeit Uhr / Endzeit: $enduhrzeit Uhr"

Send-MailMessage -SmtpServer $smtpserver -to $Mailempfaenger -from $absender -Subject "+++ WSUS: Taeglicher Report  +++" -Attachments $report_mail -body $body

#CSV Datei auf C:\ löschen
Remove-Item $report

Share this post


Link to post
Share on other sites

Moin,

 

okay, und was genau soll jetzt anders? Dein Skript gibt, wenn ich das richtig sehe, ein CSV aus, das für jeden Server eine Zeile mit den Werten enthält. Der Weg über das Objekt ist dabei schon ziemlich "sophisticated".

 

Gruß, Nils

 

Share this post


Link to post
Share on other sites

Hallo Nils,

 

 

der Bereich mit dem CSV Export im Skript ist nur ein Test, der nicht funktioniert.

 

 

Die Spalten werden durcheinander geworfen, also der Servername ist nicht mehr die erste Spalte und Excel erkennt das Format nicht.

 

 

 

 

Share this post


Link to post
Share on other sites

Moin,

 

das mit Excel liegt an der deutschen Version - dazu gibt ein paar typische Lösungen:

 

[CSV-Dateien mit Excel öffnen | faq-o-matic.net]
https://www.faq-o-matic.net/2007/01/12/csv-dateien-mit-excel-oeffnen/

 

Ein anderer Ansatz wäre, die Datei mit der Endung .txt zu speichern und dann in Excel einmal den Importassistenten zu durchlaufen.

 

Was die Ausgabe angeht: Da würde ich es mir einfach machen und auf den Objektexport verzichten. Da du die Werte ja ohnehin in Variablen hast, würde ich vor der Schleife einmal die Überschriften als String in die Datei ausgeben. In der Schleife dann eine simple Ausgabe aller Werte mit Trennzeichen dazwischen: Wert1 + ';' + Wert2 + ';' ...

Das ist nicht elegant, aber einfach, und du hast volle Kontrolle. Zudem kannst du damit das Trennzeichen selbst festlegen - wenn du das Semikolon nimmst, öffnet Excel auch in der deutschen Fassung die Datei gleich korrekt.

 

Gruß, Nils

 

Edited by NilsK

Share this post


Link to post
Share on other sites

Also wäre das dann einmal ein Out-File Befehl mit den Spaltenköpfen und dann in der Schleife selber ein Out-File befehl mit den Infos richtig?

 

 

So sieht jetzt mein Export aus:

 


Servername;Funktion;Letzte Update Installation - Datum;Letzte Update Installation - Uhrzeit;Neustart nötig;Ausstehende Updates;Betriebssystem;WSUS-AD-Gruppe;Laufzeit;Startdatum;Startzeit;Abfragezeit
NTS211;xxxxxxxxxxx;18.10.2018;04:09:10;nein;1;Windows Server 2008 R2 Standard;ManInst;5 Tage 5 Stunden 10 Minuten;04:12:55;18.10.2018;09:20

 

Leider erkennt Excel diesen Output nicht als Tabelle

 

 

image.png

Edited by Kuddel071089

Share this post


Link to post
Share on other sites

Damit Excel das Automatisch kann muss man ein Tabstop als Trenner nehmen. Sonst muss man das manuell trennen (Funktion: Text in Spalten).

Share this post


Link to post
Share on other sites

Moin,

 

vor 4 Minuten schrieb Dukel:

Damit Excel das Automatisch kann muss man ein Tabstop als Trenner nehmen. Sonst muss man das manuell trennen (Funktion: Text in Spalten).

ein Semikolon sollte in einem deutschen Excel auch funktionieren. Möglicherweise liegt hier noch ein anderes Problem vor.

 

Man könnte das aber recht einfach überprüfen und die Semikola in der vorhandenen Ausgabedatei einfach durch Tabs ersetzen - öffnet Excel es dann korrekt? In dem Fall würde ich nicht mehr lange suchen, sondern das im Skript einfach ändern. Vielleicht einfach oben eine Variable deklarieren, die das Trennzeichen aufnimmt und dann mit der Variable arbeiten, dann hat man es bei späteren Änderungen einfacher.

 

Gruß, Nils

 

Edited by NilsK

Share this post


Link to post
Share on other sites

Ich habe jetzt zwei fast perfekt Lösungen hinbekommen:

 

1. In die erste Zeile sep=: schreiben

oder

2. Statt Semikolon einen Tabstop als Trennzeichen verwenden.

 

Ecel öffnet die Datei und erkennt die eizelnen Spalten.

 

Leider sind die Spalten alle gleich klein, so dass die Spaltenköpfe nicht alle lesbar sind.

 

 

Share this post


Link to post
Share on other sites

Moin,

 

naja, wenn du eine CSV-Datei einfach in Excel öffnest, weiß Excel ja nicht, wie breit du die Spalten gern hättest. Das wirst du dir dann also hinziehen müssen. Wenn du vom Öffnen einer neuen Datei weg gleich eine schöne Breite haben willst, musst du in deinem Skript eine Excel-Datei schreiben und die nötigen Eigenschaften mitgeben. Geht auch, ist nur deutlich mehr Aufwand.

 

Gruß, Nils

 

Share this post


Link to post
Share on other sites
vor 13 Minuten schrieb NilsK:

..... Geht auch, ist nur deutlich mehr Aufwand.

.... und damit der Aufwand für so etwas nicht zu groß wird, gibt es das ImportExcel-Modul von Douglas Finke...  wenn ich nicht irre, kann man da auch Fomratierungen mitgeben.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Werbepartner:



×
×
  • Create New...