Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[Powershell] Import-CSV met filter

Pagina: 1
Acties:

  • YellowOnline
  • Registratie: Januari 2005
  • Laatst online: 28-03-2023

YellowOnline

BEATI PAVPERES SPIRITV

Topicstarter
Het is iets ingewikkelder dan de titel doet vermoeden, maar het aantal karakters is beperkt :)

Ik zoek me suf op een oplossing voor mijn probleem. Eerst en vooral zal ik de opzet uitleggen: verschillende CSVs worden in dezelfde vorm gegoten en gemerged. Dat lukt allemaal perfect.

Maar...

Bij het importeren van één specifieke CSV wil ik bepaalde machines niet importeren als ze al bestaan in een bepaalde array. Er moet een mogelijk zijn met Where-Object zodat ik niet moet beginnen ForEach'en, maar ik vind het maar niet.

Een stukje code:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
    #Array population BEGIN
    Write-Log "Populating arrays..." $logFile
     $arrAgentInstallFailed =   Import-CSV $inputFileFromFailed -Delimiter ";" | `
                                Select-Object `
                                @{Name="Host Name";Expression={$_."Computers"}} `
                                -Unique
                                
            $arrNewEpoQuery =   Import-CSV $inputFileFromNewEpo -Delimiter "," | `
                                Select-Object `
                                @{Name="Host Name";Expression={$_."System Name"}}, `
                                @{Name="IP Address";Expression={$_."IP Address"}}, `
                                @{Name="Domain";Expression={$_."Domain Name"}}, `
                                @{Name="Agent Version";Expression={$_."Product Version (Agent)"}}, `
                                @{Name="Engine Version";Expression={$_."Engine Version (VirusScan Enterprise)"}}, `
                                @{Name="DAT Version";Expression={$_."DAT Version (VirusScan Enterprise)"}}, `
                                @{Name="Last Communication";Expression={$_."Last Communication"}}, `
                                @{Name="Hotfix / Patch Version";Expression={$_."Hotfix/Patch Version (VirusScan Enterprise)"}}, `
                                @{Name="Free System Drive Space";Expression={$_."Free System Drive Space"}}, `
                                @{Name="Operating System";Expression={$_."OS Type"}}, `
                                @{Name="Service Pack";Expression={$_."OS Service Pack Version"}} `
                                -Unique
    
            $arrOldEpoQuery =   Import-CSV $inputFileFromOldEpo -Delimiter "," `
                                | Where-Object `
                                {($_."Computer Name" -NE <een van de waardes in hetzelfde veld in $arrAgentInstallFailed>) 
                                #Hier zijn nog enkele -ORs in werkelijkheid, maar die doen er even niet toe.
                                | Select-Object `
                                @{Name="Host Name";Expression={$_."Computer Name"}}, `
                                @{Name="IP Address";Expression={$_."IP Address"}}, `
                                @{Name="Domain";Expression={$_."Domain Name"}}, `
                                @{Name="Agent Version";Expression={$_."Agent Verson"}}, `
                                @{Name="Engine Version";Expression={$_."Engine Version"}}, `
                                @{Name="DAT Version";Expression={$_."DAT Version"}}, `
                                @{Name="Last Communication";Expression={$_."Last Contact"}}, `
                                @{Name="Hotfix / Patch Version";Expression={$_."Hotfix Version"}}, `
                                @{Name="Free System Drive Space";Expression={$_."Free Disk Space"}}, `
                                @{Name="Operating System";Expression={$_."OS Type"}}, `
                                @{Name="Service Pack";Expression={$_."OS Service Pack"}} `
                                -Unique
    #Array population END

(Sorry, moto-moi, maar ik heb nog geen tijd gehad om een PS lexer te schrijven :+)

M'n probleem is de Where-Object {($_."Computer Name" -NE <een van de waardes in hetzelfde veld in $arrAgentInstallFailed>)

Ik heb al allerlei constructies geprobeerd zoals
code:
1
Where-Object {($_."Computer Name" -notcontain ($arrAgentInstallFailed | Select-Object "Host Name"))


Helaas. Ik ga verder blijven zoeken uiteraard want ik heb m'n oplossing voor morgen nodig :) Als ik zelf een oplossing vind update ik wel. Als intussen iemand een geweldig idee heeft: shoot!

Edit: Oh, voor wie zich afvraagt wat ik doe: CSV1 zijn de ePO 3.6 agents die nog niet gemigreerd zijn, CSV2 de ePO 4.5 agents die problemen rapporteren en CSV3 de agents die niet geïnstalleerd zijn. Kwestie van alles in één CSV te hebben en niet op drie verschillende plekken naar de probleemgevallen te moeten zoeken - en dat alles in één uniform formaat ook. De reden voor die filter is dat agents van de oude ePO die niet meegenomen moeten worden als ze al in de lijst zitten van mislukte installs (die enkel de 4.5 bevat).

Snapt iemand die uitleg eigenlijk? :+

[ Voor 7% gewijzigd door YellowOnline op 18-08-2010 22:37 ]


  • DR
  • Registratie: December 2000
  • Niet online

DR

Moet het perse met Where-Object? Wellicht dat je nog iets kan met Compare-Object om zodoende te filteren :)

[edit]
Naja geen where-object word lastig, maar eerste gedeelte moet wellicht wel lukken met Compare

[ Voor 33% gewijzigd door DR op 18-08-2010 21:59 ]


  • YellowOnline
  • Registratie: Januari 2005
  • Laatst online: 28-03-2023

YellowOnline

BEATI PAVPERES SPIRITV

Topicstarter
DR schreef op woensdag 18 augustus 2010 @ 21:53:
Moet het perse met Where-Object? Wellicht dat je nog iets kan met Compare-Object om zodoende te filteren :)

[edit]
Naja geen where-object word lastig, maar eerste gedeelte moet wellicht wel lukken met Compare
Compare-Object hier in krijgen lijkt me niet vanzelfsprekend. Bovendien is Compare-Object geen praktische cmdlet: hij vertoont buggy behaviour in combinatie met Import-CSV (er zijn behoorlijk wat bugs nog in V2) en de richtingwijzer is een NoteProperty die minder gemakkelijk werkt dan een échte Property (enkel via Select-Object ipv .NoteProperty).

* YellowOnline probeert verder

Where-Object {$arrAgentInstallFailed -NotLike $_."Computer Name") was een goed idee maar deze volgorde slikt PS niet :(

Edit

Uiteindelijk doe ik het dan toch met een ForEach :(

code:
1
2
3
4
5
6
7
8
9
10
11
    #Array filtering BEGIN
    #It's a dirty way to filter, but there seems to be no way to make Where-Object look at different
    #values in a given array. Furthermore NoteProperties are not supported so we need to clean some
    #metadata in quite an inventive way.
    ForEach ($objAgentInstallFailed in $arrAgentInstallFailed)                  
        {
        $filterHostName = $objAgentInstallFailed -Replace "@{Host Name=", ""
        $filterHostName = $filterHostName -Replace "}", ""
        $arrOldEpoQuery =   $arrOldEpoQuery | Where-Object {$_."Host Name" -NotContains $filterHostName}    
        }
    #Array filtering END


Als iemand alsnog een oplossing weet: laat maar komen, mijn code kan altijd geoptimaliseerd worden.

Voor de geïnteresseerden het volledige script met syntax highlighting op Pastebin: http://pastebin.com/SrhdN9px .

[ Voor 34% gewijzigd door YellowOnline op 18-08-2010 23:48 ]


  • YellowOnline
  • Registratie: Januari 2005
  • Laatst online: 28-03-2023

YellowOnline

BEATI PAVPERES SPIRITV

Topicstarter
Alsnog een oplossing gevonden *O*

Echt mooi is het waarschijnlijk niet: ik converteer via .NET m'n hele array naar één gigantische string en dan kan ik eenvoudige operatoren gebruiken. Voor andere siuaties is dit waarschijnlijk geen oplossing. Misschien dat er in PS V3 betere ondersteuning voor multidimensionele arrays komt; dwz. dat een (Note-)Property excpliciet gespecifieerd kan worden bij -Contain of bij Compare-Object; of dat er gewoon een .Contain() voor arrays komt.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
    $arrOldEpoQuery =           Import-CSV $inputFileFromOldEpo -Delimiter ";" `
                                | Where-Object `
                                {
                                $arrToStringAgent = [system.string]::Join(" ",$arrAgentInstallFailed)
                                $arrToStringNewEpo = [system.string]::Join(" ",$arrNewEpoQuery)
                                $computerNameProperty = $_."Computer Name"
                                $lastContactProperty = $_."Last Contact"
                                (([datetime]::ParseExact($lastContactProperty, "yyyyMMddHHmmss", $null)) -GT ($(Get-Date).AddMonths(-1))) `
                                                                                -AND ($arrToStringAgent   -NotLike "*$computerNameProperty*") `
                                                                                -AND ($arrToStringNewEpo  -NotLike "*$computerNameProperty*") `
                                } `
                                | Select-Object `
                                @{Name="Host Name";Expression={$_."Computer Name"}}, `
                                @{Name="IP Address";Expression={$_."IP Address"}}, `
                                @{Name="Domain";Expression={$_."Domain Name"}}, `
                                @{Name="Agent Version";Expression={$_."Agent Verson"}}, `
                                @{Name="Engine Version";Expression={$_."Engine Version"}}, `
                                @{Name="DAT Version";Expression={$_."DAT Version"}}, `
                                @{Name="Last Communication";Expression={$_."Last Contact"}}, `
                                @{Name="Hotfix / Patch Version";Expression={$_."Hotfix Version"}}, `
                                @{Name="Free System Drive Space";Expression={$_."Free Disk Space"}}, `
                                @{Name="Operating System";Expression={$_."OS Type"}}, `
                                @{Name="Service Pack";Expression={$_."OS Service Pack"}} `
                                -Unique

Of, voor liefhebbers van one-liners (want dat is het uiteindelijk):
code:
1
$arrOldEpoQuery = Import-CSV $inputFileFromOldEpo -Delimiter ";" | Where-Object {$arrToStringAgent = [system.string]::Join(" ",$arrAgentInstallFailed); $arrToStringNewEpo = [system.string]::Join(" ",$arrNewEpoQuery);$computerNameProperty = $_."Computer Name";$lastContactProperty = $_."Last Contact"; (([datetime]::ParseExact($lastContactProperty, "yyyyMMddHHmmss", $null)) -GT ($(Get-Date).AddMonths(-1))) -AND ($arrToStringAgent   -NotLike "*$computerNameProperty*") -AND ($arrToStringNewEpo  -NotLike "*$computerNameProperty*")} | Select-Object @{Name="Host Name";Expression={$_."Computer Name"}}, @{Name="IP Address";Expression={$_."IP Address"}}, @{Name="Domain";Expression={$_."Domain Name"}}, @{Name="Agent Version";Expression={$_."Agent Verson"}}, @{Name="Engine Version";Expression={$_."Engine Version"}}, @{Name="DAT Version";Expression={$_."DAT Version"}}, @{Name="Last Communication";Expression={$_."Last Contact"}}, @{Name="Hotfix / Patch Version";Expression={$_."Hotfix Version"}}, @{Name="Free System Drive Space";Expression={$_."Free Disk Space"}}, @{Name="Operating System";Expression={$_."OS Type"}}, @{Name="Service Pack";Expression={$_."OS Service Pack"}} -Unique


Oh, en de $_.<value> oproepen gaf ook problemen, hoe creatief met haakjes ik ook was. Uiteindelijk heb ik dat euvel verholpen door die property een eigen variabele te geven.

[ Voor 23% gewijzigd door YellowOnline op 19-08-2010 17:12 ]