none
Import-CSV soll leere "Werte" ignorieren

    Frage

  • Hallo zusammen,

    ich habe ein kleines PowerShell Script geschrieben, welches Druckertreiber installiert, Ports anlegt, Drucker installiert und anschließend AD Gruppen erstellt. Das klappt alles einwandfrei.

    Aktuell nutze ich aber für jeden Schritt eine separate CSV Datei. Also kam mir die Idee, die CSV Datene zu konsolidieren und nur noch eine Datei zu nehmen, mit allen Informationen, die benötigt werden. Nun kommt allerdings mein Problem. Gesetz den Fall, Spalte A hat weniger Werte als Spalte B, ich möchte aber nur Spalte A gerade verarbeiten, wenn erhalte ich bei der Verarbeitung allerdings folgenden Fehler

    "Cannot validate argument on parameter 'Name'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again"

    Warum das passiert verstehe ich, für PowerShell steht in dem Bereich nichts, daher der Fehler. Allerdings ist meine Frage, ob ich diese leeren Bereiche ignorieren kann. Anbei mal ein Teil meines Scripts. Mir ist bewußt, dass ein PS Experte Verbesserungspotential sieht, für meinen Teil reicht es erstmal ;-) Weiter unten ist ein Beispiel einer CSV Datei. Wie zu sehen, fehlt ein Eintrag bei der Spalte "AvailableDrivers" und dieser erzeugt dann den oben genannten Fehler. Wenn ich also 1000 Drucker habe, mit 100 verschiedenen Treibern, dann würde mein Script 900 Fehler erzeugen.

    Vielleicht hat ja jemand eine Idee, wie man das simpel umsetzen kann.

    Code Schnipsel

    $a = new-object -comobject wscript.shell
    $intAnswer = $a.popup("Sollen die Druckertreiber wirklich installiert werden?",30,"Schritt 2: Treiberinstallation",4) #first number is timeout, second is display.
    If ($intAnswer -eq "7") {
    Add-Content -path $DataOutputEvents -Value "Skipped: Schritt 2: Druckertreiber installieren"
    }
    else
    {
    Add-Content -path $DataOutputEvents -Value "`r`nSchritt 2: Treiberinstallation`r`n"
    #Treiberliste vor Installation exportieren
    #get-printerdriver | sort Name | select Name | export-csv $DataOutputPrevDrivers -Delimiter `t -Encoding unicode -NoTypeInformation
    #Datei, welche im Userabschnitt definiert ist, einlesen und die dort enthaltenen Treiber aus dem Treiberstore installieren
    Import-Csv -Path $DataInput -delimiter ";"| Select-Object AvailableDrivers |

    foreach-object {
        
        $AvlDriver = $_.AvailableDrivers

    try {Add-PrinterDriver -ErrorAction Stop -Name $AvlDriver
    #Logging in eine Datei
    "Erfolgreich Installiert: Treiber: " + $AvlDriver | Out-File $DataOutputEvents -append
    }
    #Ausgabe der Fehlermeldung in der Konsole
    catch {Write-Host $_.Exception.Message -ForegroundColor Yellow; Write-Host $AvlDriver
    $_.Exception.Message + " >>>>> Drivername: " + $AvlDriver | Out-File $DataOutputEvents -append
    }

    #Finally wird immer ausgeführt: Erneuter Export der Treiberliste, um ein Vorher/Nachher Vergleich zu haben
    finally {get-printerdriver | sort Name | select Name | export-csv $DataOutputPostDrivers -Delimiter `t -Encoding unicode -NoTypeInformation}
    }
    }

    CSV:

    PRT;UsedDriver;AvailableDrivers
    TST-000001;2500ci KX;2550ci KX
    TST-000002;2500ci KX;2500ci KX
    TST-000003;2550ci KX;

    Dienstag, 5. Dezember 2017 12:55

Antworten

  • Hallo zusammen,

    ich konnte das Problem endlich beheben, Ihre Tips haben dabei sehr geholfen. Ich frage, wie bereits vorgeschlagen, die Werte ab, ob sie nicht leer sind, mit denen ich dann später arbeiten möchte. Ich habe den Overhead mal rausgenommen, mein Code sieht dann in etwa so aus (siehe fett markierten Teil).

    Bei den anderen Schritten frage ich dann andere Werte ab, ob diese nicht leer sind und lasse weiterarbeiten. Vielen Dank für die Hilfe.

    $a = new-object -comobject wscript.shell
        $intAnswer = $a.popup("Sollen die Druckertreiber wirklich installiert werden?",30,"Schritt 2: Treiberinstallation",4) #first number is timeout, second is display.
        If ($intAnswer -eq "7") {
            Add-Content -path $DataOutputEvents -Value "Skipped: Schritt 2: Druckertreiber installieren"
            }
        else
            {
            Add-Content -path $DataOutputEvents -Value "`r`nSchritt 2: Treiberinstallation`r`n"
            Import-Csv -Path $DataInput -delimiter ";"| foreach-object {
        
                $AvlDriver = $_.AvailableDrivers

        If ($AvlDriver -ne "$Null")
            {
                    try {Add-PrinterDriver -ErrorAction Stop -Name $AvlDriver

            "Erfolgreich Installiert: Treiber: " + $AvlDriver | Out-File $DataOutputEvents -append
            }
            catch {Write-Host $_.Exception.Message -ForegroundColor Yellow; Write-Host $AvlDriver
            $_.Exception.Message + " >>>>> Drivername: " + $AvlDriver | Out-File $DataOutputEvents -append
            }
     
        finally {get-printerdriver | sort Name | select Name | export-csv $DataOutputPostDrivers -Delimiter `t -Encoding unicode -NoTypeInformation}
            }
            }
            }

    • Als Antwort markiert PaWäl Donnerstag, 7. Dezember 2017 14:32
    Donnerstag, 7. Dezember 2017 14:32

Alle Antworten

  • $_.AvailableDrivers auf den Wert NULL prüfen:

    if ($_.AvailableDrivers) { 'not empty' } else { 'empty' }

    Dienstag, 5. Dezember 2017 13:08
  • Guten Morgen,

    danke für die Info. Allerdings weiß ich nicht, wie ich diese Prüfung sinnvoll in das Script integriere. An welcher Stelle muss ich das verwenden?

    Vielen Dank und beste Grüße

    PaWäl

    Mittwoch, 6. Dezember 2017 09:17
  • if ($AvlDriver) { Add-PrinterDriver -Name $AvlDriver -ErrorAction Stop; # ... }

    Übrigens: Fehlermeldung werden immer mit Write-Error nach StdErr geschrieben. Siehe auch Write-Host Considered Harmful


    Mittwoch, 6. Dezember 2017 11:06
  • Hallo Herr Meyer,

    vielen Dank für den Hinweis zur Fehlerbehandlung. Das werde ich mir noch anschauen und korrigieren.

    Leider bin ich nicht in der Lage mein Problem zu lösen, deswegen hoffe ich nochmal auf Ihre Hilfe. Ich habe vielleicht noch eine nicht ganz unwichtige Information vergessen zu melden:

    Der Teil mit dem Treiber ist in diesem Beispiel kleiner, als der Teil der anzulegenden Drucker. Da ich das Script aber als "allrounder" bauen wollte, kann es durchaus passieren, dass die Anzahl der Treiber größer ist, als die Anzahl der Drucker, die installiert werden sollen.

    Versuche ich die Lösung nun anzuwenden, kann ich mit ein wenig Korrektur zumindest die Treiberinstallation durchführen, im nächsten Schritt werden dann aber keine Drucker mehr angelegt, es passiert einfach nichts. Nach ein wenig verschieben, klappt die Druckeranlage wieder, aber es erscheint auch direkt wieder die Fehlermeldung wie im Eingangspost zu sehen.

    Ich würde mich freuen, wenn Sie mir hier nocheinmal Hilfestellung geben könnten.

    Besten Dank im Voraus

    Donnerstag, 7. Dezember 2017 09:59
  • Pauschal kann ich dazu nur sagen, dass ich vor der Ausführung einer Funktion prüfen sollte, ob alle relevanten Variablen hierfür belegt sind.

    if ($V1 and $V2 ...) { <Aktion> }

    Donnerstag, 7. Dezember 2017 12:18
  • Hallo zusammen,

    ich konnte das Problem endlich beheben, Ihre Tips haben dabei sehr geholfen. Ich frage, wie bereits vorgeschlagen, die Werte ab, ob sie nicht leer sind, mit denen ich dann später arbeiten möchte. Ich habe den Overhead mal rausgenommen, mein Code sieht dann in etwa so aus (siehe fett markierten Teil).

    Bei den anderen Schritten frage ich dann andere Werte ab, ob diese nicht leer sind und lasse weiterarbeiten. Vielen Dank für die Hilfe.

    $a = new-object -comobject wscript.shell
        $intAnswer = $a.popup("Sollen die Druckertreiber wirklich installiert werden?",30,"Schritt 2: Treiberinstallation",4) #first number is timeout, second is display.
        If ($intAnswer -eq "7") {
            Add-Content -path $DataOutputEvents -Value "Skipped: Schritt 2: Druckertreiber installieren"
            }
        else
            {
            Add-Content -path $DataOutputEvents -Value "`r`nSchritt 2: Treiberinstallation`r`n"
            Import-Csv -Path $DataInput -delimiter ";"| foreach-object {
        
                $AvlDriver = $_.AvailableDrivers

        If ($AvlDriver -ne "$Null")
            {
                    try {Add-PrinterDriver -ErrorAction Stop -Name $AvlDriver

            "Erfolgreich Installiert: Treiber: " + $AvlDriver | Out-File $DataOutputEvents -append
            }
            catch {Write-Host $_.Exception.Message -ForegroundColor Yellow; Write-Host $AvlDriver
            $_.Exception.Message + " >>>>> Drivername: " + $AvlDriver | Out-File $DataOutputEvents -append
            }
     
        finally {get-printerdriver | sort Name | select Name | export-csv $DataOutputPostDrivers -Delimiter `t -Encoding unicode -NoTypeInformation}
            }
            }
            }

    • Als Antwort markiert PaWäl Donnerstag, 7. Dezember 2017 14:32
    Donnerstag, 7. Dezember 2017 14:32
  • Hallo,

    hier geht's übrigens nicht so formell zu, hier ist es üblich, sich zu duzen.

    Die ein oder andere Sache, die mir noch aufgefallen ist:

    • In Scripts solltest du keine Aliase verwenden (Select-Object anstatt select).
    • Dein Code sieht aus, als ob du einen Editor ohne IntelliSense-Unterstützung für PowerShell verwendest. Mit PowerShell ISE oder Visual Studio Code brauchst du die Befehle i.d.R. nicht vollständig tippen und der Editor ergänzt die korrekte Groß- und Kleinschreibung automatisch (Get-PrinterDriver anstatt get-printerdriver).
    • Die Variable $null musst du nicht in Anführungszeichen einschließen.

    Gruß



    Sonntag, 10. Dezember 2017 15:43