none
Wieso bekomme ich keine Werte übergeben? RRS feed

  • Frage

  • Ich habe eine Hashtable wo Rechnernamen drinnen stehen, nun möchte ich nur bestimmte Rechner an eine andere Hashtable über geben. Hier wird dann nur dies in das Array übergeben: System.Collections.DictionaryEntry

    Hier der Code wo dies passiert:

    #Der String wird in ein Array aufgeteilt mit dem Befehl split( ), das Signal für den Split ist ein Komma [Int[]]$Ar = $Abfraget.Split(",") $ComputerNew = @{} for($Num = 0;$Num -le $Ar.count-1; $Num++){ $ComputerNew[$Num] = $Computernamen[$Ar[$Num]] } #Starten des Skriptes mit den gewünschten PCs abfrage $ComputerNew #abfrage ist eine Funktion


    Wenn ich $ComputerNe ausgeben, wird mir der Rechnername angezeigt, aber in der Funktion steht nur noch "System.Colletions.Hashtable". Wie bekomme ich es hin, dass er mir die Rechnernamen an das neue Array übergibt?


    • Bearbeitet Isenherz Montag, 30. September 2013 14:24
    Montag, 30. September 2013 13:58

Antworten

  • Da für dieses Problem kein neuer Lösungsansatz kam, habe ich was rumprobiert und den Script etwas umgeschrieben.

    Unter der Funktion main habe ich nun in der ersten if auch Zahlen die übergeben werden.

    if($Abfraget -eq "all"){
    		$Ar = @()
    		#Start des Scriptes mit allen PCs
    		$Anz = $Computernamen.Count
    		for($T=0;$T -lt $Anz;$T++){
    			$Ar += $T
    		}
    		abfrage $Ar
    	}elseif ($Abfraget -eq "exit"){
    		#Bestätigung das der Script abgebrochen wurde
    		Write-Host -BackgroundColor Red -ForegroundColor Black "Der Script wird abgebrochen."
    		ende1 #Beendet den Script	
    	}elseif($Abfraget){
    		#Der String wird in ein Array aufgeteilt mit dem Befehl split( ), das Signal für den Split ist ein Komma
    		[Int[]]$Ar = $Abfraget.Split(",")
    		#Starten des Scriptes mit den gewünschten PCs
    		abfrage $Ar
    	}else{
    	Write-Host -ForegroundColor Red "Es wurde nichts eingeben, versuchen Sie es erneut!"
    	ende1
    	}

    Und dem entsprechend hab ich unter abfrage ein paar Sachen geändert. Hier musste ich es so umschreiben das ich direkt auf die Werte von $Computernamen zugreifen konnte.

    Auch habe ich die For-Schleife angepasst! Aus der foreach wurde eine For-Schleife
    Hinzu gekommen sind:

    $PCAnz = $Ar.Count
    
    $Pc = $Computernamen[$Ar[$R]]


    mfg Isenherz

    • Als Antwort markiert Isenherz Dienstag, 1. Oktober 2013 11:10
    Dienstag, 1. Oktober 2013 11:10

Alle Antworten

  • Du benutzt die Hashtable wie ein Array mit dem indexer [$Num].

    Hashtable besteht aus Key=Value Paaren!

    Eine Hashtable wird mit Keys und dem Punktoperator angesprochen.

    Ändere die Zeile in der die Hashtabel ihre Werte zugewiesen bekommt.

    $ComputerNew.$Num = $Computernamen[$Ar[$Num]]

    #Der String wird in ein Array aufgeteilt mit dem Befehl split( ), das Signal für den Split ist ein Komma
    		[Int[]]$Ar = $Abfraget.Split(",")
    		$ComputerNew = @{}
    		for($Num = 0;$Num -le $Ar.count-1; $Num++){
    			$ComputerNew.$Num = $Computernamen[$Ar[$Num]]
    		}
    		#Starten des Skriptes mit den gewünschten PCs
    		abfrage $ComputerNew #abfrage ist eine Funktion


    Meine PowerShell Artikel, Buchtipps und kostenlose PowerShell Tutorials + E-Books
    Mein deutscher PowerShell Blog
    Mein 21 Teiliger PowerShell Video Grundlehrgang
    Deutsche PowerShell Videos auf Youtube
    Folge mir auf:
    Twitter | Facebook | Google+ | Deutsches PowerShell Forum (TechNet)

    Montag, 30. September 2013 14:27
  • Leider übergibt er immer noch nicht die Werte, sondern macht nur den Verweis oder sowas ähnliches.

    Ich poste hier mal den ganzen Script, den Abschnitt um den es hier geht findet man unter der Funktion main:

    Clear #Import des Modul Active Directory für die PowerShell Import-Module ActiveDirectory #Errormeldung werden unterdrückt #$ErrorActionPreference = "SilentlyContinue" #Warnungen werden unterdrückt #$WarningPreference ="SilentlyContinue" #Pfad Bereitstellung $Filepath1="E:\PowerShell\AD\software.xlsx" $Pfad = "k:\""

    $Leerzeichen ="" #Varaible $Computernamen = @{} $Excel $Excel1 $Anzahl $ComputerNew #Filter, hier wird überprüft ob der PC Online ist filter select-Online{#Filter wird bei der Anzeige der Rechner eingesetzt #Abspeichern des Status, 0 = online, 1 = offline $Status = Get-WmiObject Win32_PingStatus -Property StatusCode -filter "Address='$Pc'" #Status wird zurück geben an das Programm return $Status } filter select-Online-Auswahl{#Filter wird zur Überprüfung in der Inventur eingesetzt #Abspeichern des Status, 0 = online, 1 = offline $Status = Get-WmiObject Win32_PingStatus -Property StatusCode -filter "Address='$Pca'" #Status wird zurück geben an das Programm return $Status } function domain{ #Import der Domain $Domain = Get-ADDomain | select-object -ExpandProperty Name #Import der Computernamen $Computert = Get-ADComputer -Filter {*} | ForEach-Object{$_.name} #Selectieren der einzelnen Objecte $Computernamen = computeronline $Computert #Ausgabe auf der Console Write-Host "Gefundene Rechner in der Domain '$Domain':" $Anzcom = $Computernamen.Count $Anzcom = $Anzcom -1 for($O=0;$O -le $Anzcom; $O++){ Write-Host $O "-" $Computernamen[$O] } Write-Host "------------------------------------------------------------------" main } function main{ #Angabe der Optionen vom Script Write-Host "Befehle zum steuern des Scriptes:" Write-Host "all: Alle Inventarisieren" Write-Host "exit: Script beenden" Write-Host "Mehrere Rechner bitte mit Komma trennen!" #Warten auf Eingabe $Abfraget = Read-Host "Bitte Option eingeben" $Leerzeichen #Abfrage welche Option gewählt wurde if($Abfraget -eq "all"){ #Start des Scriptes mit allen PCs $test = abfrage $Computernamen }elseif ($Abfraget -eq "exit"){ #Bestätigung das der Script abgebrochen wurde Write-Host -BackgroundColor Red -ForegroundColor Black "Der Script wurde abgebrochen." Write-Host "Der Script wurde beendet" }elseif($Abfraget){ #Der String wird in ein Array aufgeteilt mit dem Befehl split( ), das Signal für den Split ist ein Komma [Int[]]$Ar = $Abfraget.Split(",") $ComputerNew = @{} for($Num = 0;$Num -le $Ar.count-1; $Num++){ $ComputerNew.$Num = $Computernamen[$Ar[$Num]] } Write-Host $Rechner #Starten des Scriptes mit den gewünschten PCs $test = abfrage $ComputerNew }else{ Write-Host -ForegroundColor Red "Es wurde nichts eingeben, versuchen Sie es erneut!" ende1 } } function abfrage ($Computernamen){ #Erstellung einer Excel-Datei $Excel = New-Object -ComObject Excel.Application #Excel soll nicht angezeigt werden $Excel.visible = $false #Anlegen der Tabellenblätter $Excel.SheetsInNewWorkbook = $Computernamen.Count $Workbook = $Excel.Workbooks.Add() #Counter Variable für Arbeitsblätter $I = 1 foreach ($Pc in $Computernamen){ #Aufruf der Funktion ob Pc-Online $Ping = select-Online Write-Host "Es wird überprüft, ob der $Pc Online ist." #Überprüfung des Statuses if ($Ping.StatusCode -eq 0){ #öffnen der arbeitsmappe $Sheet = $Workbook.Worksheets.Item($I++) #Bennen der Tabelleblätter $Sheet.Name = $Pc Write-Host $Sheet.Name $intRow = 1 Write-Host $Pc" ist Online." #Erstellung der Zellen Überschriften $Sheet.Cells.Item($intRow,1) = "NAME:" #Eintragen des PC-Namen $Sheet.Cells.Item($intRow,2) = $Pc.ToUpper(); #Formatierung der ersten Zeile $Sheet.Cells.Item($intRow,1).Font.Bold = $true $Sheet.Cells.Item($intRow,2).Font.Bold = $true $Sheet.Cells.Item($intRow,3).Font.Bold = $true $Sheet.Cells.Item($intRow,4).Font.Bold = $true $Sheet.Cells.Item($intRow,1).Interior.ColorIndex = 50 $Sheet.Cells.Item($intRow,2).Interior.ColorIndex = 50 $Sheet.Cells.Item($intRow,3).Interior.ColorIndex = 50 $Sheet.Cells.Item($intRow,4).Interior.ColorIndex = 50 $intRow++ #Anlegen der Zellenüberschriften $Sheet.Cells.Item($intRow,1) = "Name" $Sheet.Cells.Item($intRow,2) = "Version" $Sheet.Cells.Item($intRow,3) = "Install Datum" $Sheet.Cells.Item($intRow,4) = "Erwartete Version" #Formatierung der Zellen-Überschriften for($col = 1; $col -le 4; $col++){ $Sheet.Cells.Item($intRow,$col).Font.Bold = $true $Sheet.Cells.Item($intRow,$col).Interior.ColorIndex = 48 $Sheet.Cells.Item($intRow,$col).Font.ColorIndex = 0 } $intRow++ Write-Host $Pc" wird Inventarisiert ..." #Aufruf der Funktion zum Abrufen der Software $software = software $Pc #Eintragen der Software Spalte für Spalte foreach ($objItem in $software){ $Sheet.Cells.Item($intRow, 1) = $objItem.Name $Sheet.Cells.Item($intRow, 2) = $objItem.Version $Sheet.Cells.Item($intRow, 3) = $objItem.InstallDate $intRow ++ } $Sheet.UsedRange.EntireColumn.AutoFit() $Leerzeichen }else{ Write-Host -ForegroundColor Red $Pc" ist nicht online." $Leerzeichen ende } } vergleich } function software($Pc){#Funktion zum auslesen der Software #Der Rückgabewert ist die Softwareliste return Get-WmiObject -ComputerName $Pc -Class Win32_Product | Sort-Object Name } function computeronline($Computert){ $PcOnline = @() foreach ($Pca in $Computert){ $Ping = select-Online-Auswahl if ($Ping.StatusCode -eq 0){ $PcOnline += $Pca } } return $PcOnline } function vergleich{ #Aufbereitung der Anzahl für die Schleife $Anzahl = $Computernamen.Count $Anz =1 Write-Host "Einlesen der Quell-, Vergleichsdatei und Start des Vergleichens" Write-Host "Der Script wird jetzt mehrere Minuten die Zeilen vergleichen!" #*================================================================================= #* Öffnet die ersten Exceldatei und liest das relevante Sheet aus für den Vergleich #*================================================================================= $Excel1 = New-Object -ComObject Excel.Application # Excel ComObjekt erstellen $Excel1.visible = $false $Workbook1=$Excel1.Workbooks.open($Filepath1) $Sheet1 = $Workbook1.Worksheets.Item("Software") if($Sheet1){ Write-Host -ForegroundColor Green "Die Datei '$Filepath1' wurde geladen" } #*============================================================================= #* Öffnet die zweite Exceldatei und liest das relevante Sheet aus #*============================================================================= #$Workbook=$Excel.Workbooks.open($Pfad) foreach($PC in $Computernamen){ $Sheet = $Excel.Worksheets.Item($Anz++) if($Sheet){ Write-Host -ForegroundColor Green "Die Datei '$Pfad $Pc' wurde geladen" } #*============================================================================= #* Vergleich von z.B. Zeile A mit allen Zeilen der zweiten Datei #*============================================================================= for ($S=3;$S -le 100000; $S++){ $Inhalt = $Sheet.Cells.Item($S,1).Text $Version = $Sheet.Cells.Item($S,2).Text if($Inhalt -eq ""){ $S = 100001 break } Write-Host -ForegroundColor White -BackgroundColor Black $Inhalt $Version "wird abgeglichen." for($E=2;$E -le 100000; $E++){ $Inhalt1 = $Sheet1.Cells.Item($E,1).Text $Version1 = $Sheet1.Cells.Item($E,2).Text #Write-Host $Inhalt1 $Version1 if($Inhalt1 -eq ""){ $E = 100001 break }elseif($Inhalt -eq $Inhalt1 -and $Version -eq $Version1){ #Write-Host -BackgroundColor Green $Inhalt $Version " ist gleich!" $Sheet.Cells.Item($S,1).Interior.ColorIndex = 4 $Sheet.Cells.Item($S,2).Interior.ColorIndex = 4 $Sheet.Cells.Item($S,3).Interior.ColorIndex = 4 $Sheet.Cells.Item($S,4).Interior.ColorIndex = 4 $E = 100001 }elseif($Inhalt -eq $Inhalt1 -and $Version -ne $Version1){ #Write-Host -BackgroundColor Yellow $Inhalt $Version " ist nicht gleich wie "$Inhalt1 $Version1 $Sheet.Cells.Item($S,1).Interior.ColorIndex = 27 $Sheet.Cells.Item($S,2).Interior.ColorIndex = 27 $Sheet.Cells.Item($S,3).Interior.ColorIndex = 27 $Sheet.Cells.Item($S,4).Interior.ColorIndex = 27 $Sheet.Cells.Item($S,4) = $Version1 $E = 100001 }elseif($Inhalt -ne $Inhalt1){ #Write-Host -BackgroundColor Red $Inhalt $Version " ist nicht gleich in der Liste!" $Sheet.Cells.Item($S,1).Interior.ColorIndex = 3 $Sheet.Cells.Item($S,2).Interior.ColorIndex = 3 $Sheet.Cells.Item($S,3).Interior.ColorIndex = 3 $Sheet.Cells.Item($S,4).Interior.ColorIndex = 3 } } } } speichern } function speichern{ #Speichern von der Excel-Datei, als erstes wird überprüft ob die Datei schon exestiert IF(Test-Path $Pfad) { #Löschen der alten Datei Remove-Item $Pfad #Speichern $Workbook.SaveAs($Pfad) } ELSE { #Speichern $Workbook.SaveAs($Pfad) } Write-Host "Es wird gewartet bis gespeichert wurde." Start-Sleep 10 #Pausiert den Script für x Sekunden #Write-Host "Script läuft" Write-Host "Es wird gewartet bis Excel geschloßen wurde." $Excel.Application.DisplayAlerts = $false #Schaltet den Speicherdialog ab $Workbook.close() #Arbeitsmappe wird geschloßen Start-Sleep 5 #Pausiert den Script für x Sekunden $Excel.Quit() #Schließen der Anwendung $Excel1.Application.DisplayAlerts = $false #Schaltet den Speicherdialog ab $Workbook1.close() #Arbeitsmappe wird geschloßen Start-Sleep 5 #Pausiert den Script für x Sekunden $Excel1.Quit() #Schließen der Anwendung Start-Sleep 10 #Pausiert den Script für x Sekunden Write-Host "Excel wurde beendet!" <#Write-Host "Es wird gewartet das Excel geschlossen wurde" Start-Sleep 15 #Pausiert den Script für x Sekunden #Kill des Prozesses Excel, wenn nicht auf normalen Weg geschloßen werden konnte $ExcelProcess=get-process excel $ExcelProcess | foreach {stop-process ($_.id)} #> [System.Runtime.Interopservices.Marshal]::ReleaseComObject($Excel) #Entfernen des ComObjekts aus dem Speicher [System.Runtime.Interopservices.Marshal]::ReleaseComObject($Excel1) #Entfernen des ComObjekts aus dem Speicher } $Leerzeichen function ende{#Überprüfung ob der Script ohne Speichern beendet werden kann. if($Computernamen.Count -eq 1){#Überprüfung ob nur ein ein Rechner in dem Array steht. Write-Host "Das Script wurde beendet, versuchen Sie es erneut mit den Richtigen Namen!" exit } } function ende1{ Write-Host "Der Script wurde beendet!" exit } #Mainprogramm, durch laufen der einzelnen PCs Write-Host "Geben Sie den vollständigen Pfad zum speichern der Datei an." Write-Host "Aufbau wie der Windows Pfad: k:\Ordner\Name.xlsx" $Pfad = Read-Host "Hier eingeben" Write-Host "Wollen Sie die Datei unter $Filepath1 verwenden? (Y/N)" $Vergleich = Read-Host #Abfrage ob der Pfad verwendet werden soll. if($Vergleich -eq "N"){ Write-Host "Geben Sie den vollständigen Pfad zu der Vergleichsdatei an." Write-Host "Aufbau wie der Windows Pfad: k:\Ordner\Name.xlsx" $Filepath1 = Read-Host "Hier eingeben" } $Leerzeichen #Abfrage ob der Pfad exestiert $TestPfad = Test-Path $Filepath1 -pathType Any if($TestPfad -eq "False"){ #Aufruf der beiden Hauptprogramme Write-Host "Die Datei wird auf folgendem Pfad ausgeben: "$Pfad domain }else{ $Filepath1 = Read-Host "Die Datei '$Filepath1' exestiert nicht unter dem Pfad, geben Sie bitte einen anderen an" #Überprüfung ob der neue Pfad exestiert $TestPfad = Test-Path $Filepath1 -pathType Any if($TestPfad -eq "False"){ #Aufruf des Hauptprogrammes domain }else{ #Abbruch des ganzen Programm Write-Host "Pfad exestiert nicht, versuchen Sie es erneut! Das Script wurde beendet!" } }



    mfg Isenherz


    • Bearbeitet Isenherz Montag, 30. September 2013 14:49 " hinzugfügt da Farben verügt gespielt haben
    Montag, 30. September 2013 14:40
  • Da für dieses Problem kein neuer Lösungsansatz kam, habe ich was rumprobiert und den Script etwas umgeschrieben.

    Unter der Funktion main habe ich nun in der ersten if auch Zahlen die übergeben werden.

    if($Abfraget -eq "all"){
    		$Ar = @()
    		#Start des Scriptes mit allen PCs
    		$Anz = $Computernamen.Count
    		for($T=0;$T -lt $Anz;$T++){
    			$Ar += $T
    		}
    		abfrage $Ar
    	}elseif ($Abfraget -eq "exit"){
    		#Bestätigung das der Script abgebrochen wurde
    		Write-Host -BackgroundColor Red -ForegroundColor Black "Der Script wird abgebrochen."
    		ende1 #Beendet den Script	
    	}elseif($Abfraget){
    		#Der String wird in ein Array aufgeteilt mit dem Befehl split( ), das Signal für den Split ist ein Komma
    		[Int[]]$Ar = $Abfraget.Split(",")
    		#Starten des Scriptes mit den gewünschten PCs
    		abfrage $Ar
    	}else{
    	Write-Host -ForegroundColor Red "Es wurde nichts eingeben, versuchen Sie es erneut!"
    	ende1
    	}

    Und dem entsprechend hab ich unter abfrage ein paar Sachen geändert. Hier musste ich es so umschreiben das ich direkt auf die Werte von $Computernamen zugreifen konnte.

    Auch habe ich die For-Schleife angepasst! Aus der foreach wurde eine For-Schleife
    Hinzu gekommen sind:

    $PCAnz = $Ar.Count
    
    $Pc = $Computernamen[$Ar[$R]]


    mfg Isenherz

    • Als Antwort markiert Isenherz Dienstag, 1. Oktober 2013 11:10
    Dienstag, 1. Oktober 2013 11:10
  • Hashtables werden in der PowerShell mit den geschweiften Klammern erzeugt @{}.
    Arrays werden in der PowerShell mit den runden Klammern erzeugt @()

    Du verwechselst Hashtables und Arrays kennst du den Unterschied?

    Beschäftige dich mit Arrays
    http://www.colorconsole.de/PS_Windows/de/about_arrays.htm
    und Hashtables:
    http://www.colorconsole.de/PS_Windows/de/about_hash_tables.htm

    Ich möchte dich nicht demotivieren, aber dein gesamtes Script ist sehr unstrukturiert, vieles darin macht keine Sinn.

    Dir Fehlen sehr viele wichtige Grundkenntnisse im Umgang mit Scripts oder Programmierung!
    Lies bitte ein gutes PowerShell Buch!

    Schau mal auf meinen Blog da habe ich gute Tipps für PowerShell Bücher und E-books.


    Meine PowerShell Artikel, Buchtipps und kostenlose PowerShell Tutorials + E-Books
    Mein deutscher PowerShell Blog
    Mein 21 Teiliger PowerShell Video Grundlehrgang
    Deutsche PowerShell Videos auf Youtube
    Folge mir auf:
    Twitter | Facebook | Google+ | Deutsches PowerShell Forum (TechNet)

    Dienstag, 1. Oktober 2013 12:23
  • Ja, zu dem Script fehlen mir noch viele Grundlagen und auch hatte ich mir das schon gedacht, dass der Script total unstrukturiert ist. Mit der PowerShell beschäftige ich mich jetzt erst seit zwei Wochen, das war/ist eine Aufgabenstellung von meinem Ausbilder.

    Wenn ich $Computernamen anspreche wie normal üblich bei einer Hashtable, sagte er mir einen Fehler. So wie ich jetzt oben drauf zugreife, kommt keine Fehlermeldung "$Computernamen[$Ar[$R]]" und es wird der richtige Wert ausgeben. Wenn ich mit der Maus auf "$Computernamen" gehe sagt er mir, dies sei eine Hashtable. Daher hatte ich auch von Hashtable geschrieben.

    Das ich jetzt im letzten Post im Code ein Array erstellt hab, war Absicht, da es hiermit funktioniert und ich so die Liste in Excel ausgeben bekomme.


    mfg Isenherz

    Dienstag, 1. Oktober 2013 12:58
  • Danke für deine Hilfe und die schnellen Antworten!

    mfg Isenherz

    Dienstag, 1. Oktober 2013 13:02