erobby
erobby

Reputation: 47

Powershell count matching variables in a single column

I have this CSV file that I kind of do a lot to. My most recent task is to add a summary sheet.

With that said I have a CSV file I pull from a website and send through lot of checks. Code Below:

$Dups = import-csv 'C:\Working\cylrpt.csv' | Group-Object -Property 'Device Name'| Where-Object {$_.count -ge 2} | ForEach-Object {$_.Group} | Select @{Name="Device Name"; Expression={$_."Device Name"}},@{Name="MAC"; Expression={$_."Mac Addresses"}},Zones,@{Name="Agent"; Expression={$_."Agent Version"}},@{Name="Status"; Expression={$_."Is online"}}
$Dups | Export-CSV $working\temp\01-Duplicates.csv -NoTypeInformation
$csvtmp = Import-CSV $working\cylrpt.csv | Select @{N='Device';E={$_."Device Name"}},@{N='OS';E={$_."OS Version"}},Zones,@{N='Agent';E={$_."Agent Version"}},@{N='Active';E={$_."Is Online"}},@{N='Checkin';E={[DateTime]$_."Online Date"}},@{N='Checked';E={[DateTime]$_."Offline Date"}},Policy
$csvtmp | %{
    if ($_.Zones -eq ""){$_.Zones = "Unzoned"}
    }
$csvtmp | Export-Csv $working\cy.csv -NoTypeInformation
import-csv $working\cy.csv | Select Device,policy,OS,Zones,Agent,Active,Checkin,Checked | % {
    $_ | Export-CSV -path $working\temp\$($_.Zones).csv -notypeinformation -Append
    }
  1. The first check is for duplicates, I used separate lines of code for this because I wanted to create a CSV for duplicates.
  2. The second check backfills all blank cells under the Zones column with "UnZoned"
  3. The third thing is does is goes through the entire CSV file and creates a CSV file for each Zone

So this is my base. I need to add another CSV file for a Summary of the Zone information. The Zones are in the format of XXX-WS or XXX-SRV, where XXX can be between 3 and 17 letters.

I would like the Summary sheet to look like this

ABC         ###
ABC-WS      ##
ABC-SRV     ##

DEF         ###
DEF-WS      ##
DEF-SRV     ##

My thoughts are to either do the count from the original CSV file or to count the number of lines in each CSV file and subtract 1, for the header row.

Now the Zones are dynamic so I can't just say I want ZONE XYZ, because that zone may not exist.

So what I need is to be able to either count the like zone type in the original file and either output that to an array or file, that would be my preferred method to give the number of items with the same zone name. I just don't know how to write it to look for and count matching variables. Here is the code I'm trying to use to get the count:

import-csv C:\Working\cylrpt.csv | Group-Object -Property 'Zones'| ForEach-Object {$_.Group} | Select @{N='Device';E={$_."Device Name"}},Zones | % {
$Znum = ($_.Zones).Count
   If ($Znum -eq $null) {
            $Znum = 1
        } else {
            $Znum++
    }

}
$Count = ($_.Zones),$Znum | Out-file C:\Working\Temp\test2.csv -Append

Here is the full code minus the report key:

$cylURL = "https://protect.cylance.com/Reports/ThreatDataReportV1/devices/"
$working = "C:\Working"
Remove-item -literalpath "\\?\C:\Working\Cylance Report.xlsx"
Invoke-WebRequest -Uri $cylURL -outfile $working\cylrpt.csv
$Dups = import-csv 'C:\Working\cylrpt.csv' | Group-Object -Property 'Device Name'| Where-Object {$_.count -ge 2} | ForEach-Object {$_.Group} | Select @{Name="Device Name"; Expression={$_."Device Name"}},@{Name="MAC"; Expression={$_."Mac Addresses"}},Zones,@{Name="Agent"; Expression={$_."Agent Version"}},@{Name="Status"; Expression={$_."Is online"}}
$Dups | Export-CSV $working\temp\01-Duplicates.csv -NoTypeInformation
$csvtmp = Import-CSV $working\cylrpt.csv | Select @{N='Device';E={$_."Device Name"}},@{N='OS';E={$_."OS Version"}},Zones,@{N='Agent';E={$_."Agent Version"}},@{N='Active';E={$_."Is Online"}},@{N='Checkin';E={[DateTime]$_."Online Date"}},@{N='Checked';E={[DateTime]$_."Offline Date"}},Policy
$csvtmp | %{
    if ($_.Zones -eq ""){$_.Zones = "Unzoned"}
    }
$csvtmp | Export-Csv $working\cy.csv -NoTypeInformation
import-csv $working\cy.csv | Select Device,policy,OS,Zones,Agent,Active,Checkin,Checked | % {
    $_ | Export-CSV -path $working\temp\$($_.Zones).csv -notypeinformation -Append
    }

cd $working\temp;
Rename-Item "Unzoned.csv" -NewName "02-Unzoned.csv"
Rename-Item "Systems-Removal.csv" -NewName "03-Systems-Removal.csv"
$CSVFiles = Get-ChildItem -path $working\temp -filter *.csv 
$Excel = "$working\Cylance Report.xlsx"
$Num = $CSVFiles.Count
Write-Host "Found the following Files:  ($Num)"

ForEach ($csv in $CSVFiles) {
    Write-host "Merging $CSVFiles.Name"
}
    $EXc1 = New-Object -ComObject Excel.Application
    $Exc1.SheetsInNewWorkBook = $CSVFiles.Count
    $XLS = $EXc1.Workbooks.Add()
    $Sht = 1
ForEach ($csv in $CSVFiles) {
    $Row = 1
    $Column = 1
    $WorkSHT = $XLS.WorkSheets.Item($Sht)
    $WorkSHT.Name = $csv.Name -Replace ".csv",""
    $File = (Get-Content $csv)
    ForEach ($line in $File) {
        $LineContents = $line -split ',(?!\s*\w+")'
        ForEach ($Cell in $LineContents) {
            $WorkSHT.Cells.Item($Row,$Column) = $Cell -Replace '"',''
            $Column++
        }
        $Column = 1
        $Row++
    }
    $Sht++
}
$Output = $Excel
$XLS.SaveAs($Output)
$EXc1.Quit()
Remove-Item *.csv
cd ..\

Upvotes: 0

Views: 670

Answers (1)

erobby
erobby

Reputation: 47

Found the solution

$Zcount = import-csv C:\Working\cylrpt.csv | where Zones -ne "$null" | select @{N='Device';E={$_."Device Name"}},Zones | group Zones | Select Name,Count
$Zcount | Export-Csv -path C:\Working\Temp\01-Summary.csv -NoTypeInformation

Upvotes: 1

Related Questions