1

ProcessName UserName             PSComputerName

AnyDesk     NT-AUTORITÄT\SYSTEM  localhost
csrss                            dc-01
ctfmon      SAD\Administrator    rdscb-01
            SAD\Administrator    srv-01

Remove the second and last row here

  • This is a programmer's Q&A site; I don't see a question or any code of what you have tried so far. – Bill_Stewart Apr 13 '20 at 22:22
  • https://stackoverflow.com/help/how-to-ask --- Show your code and errors. This is not a complicated thing you are after, as there are many articles on the use case of file and string parsing (csv/txt), on the web and videos on Youtube, using comparison operators, Select-String, ConvertFrom-String cmdlets or RegEx. We can help, but we need to see what you've done so far. – postanote Apr 13 '20 at 22:28
  • @postanote I can do this by just using "-ne" for every row but that seems too much to me so I just want to get a dynamic solution. I didn't find any dynamic solution. " $data = $data | Select-Object ProcessName, UserName, PSComputerName | Where-Object{$_.UserName -ne ""} | Format-Table " – Mahesh Mistry Apr 13 '20 at 22:39
  • Your collection may have _come from_ a CSV file, but I don't think this is a CSV-specific question. [How do I get properties that ONLY have populated values?](https://stackoverflow.com/q/44368990/150605) gets close, but filters out empty properties instead of objects with empty properties. – Lance U. Matthews Apr 13 '20 at 22:59
  • Not really, since you are importing a csv file, it is coming in one row at a time, thus process each row is a prudent thing to do. Yet it sounds like you are asking, that you want to dynamically capture all columns regardless of the number returned, use the header name in processing the rows one at a time while using that capture columnname to validate content of that cell. This requires reqined the file, capturing the columns then process it lines. So, at minimum, you'll need to counters for the loop. This still menas either -not or -ne per row, while dynamically grabbing column headers. – postanote Apr 13 '20 at 23:08

2 Answers2

5

Based on your comments, if $data is read from a CSV file and contains custom objects, you can do the following:

$data | where { $_.PsObject.Properties.Value -notcontains $null -and $_.PsObject.Properties.Value -notcontains '' }

This will apply to every property and won't require supplying named properties.

AdminOfThings
  • 23,946
  • 4
  • 17
  • 27
  • ;-} --- Like I said above, more elegant ways exist, as AdminOfThings is showing. --- ;-} – postanote Apr 13 '20 at 23:19
  • Thanks, @AdminOfThings it seems to be working but it didn't work when I just used "-ne" instead of "-notcontains". – Mahesh Mistry Apr 14 '20 at 14:04
  • Yes, you can't use `-ne` with `$_.PsObject.Properties.Value` because `.Value` is going to return a collection. `-notcontains` is used for containment to compare a single item against a collection of items. – AdminOfThings Apr 14 '20 at 18:58
1

There are more elegant ways, but, here is a kind of ugly answer, to illustrate this...

$Data = @"
"ProcessName","UserName","PSComputerName"
"AnyDesk","NT-AUTORITÄT\SYSTEM","localhost"
"csrss","","dc-01"
"ctfmon","SAD\Administrator","rdscb-01"
 "","SAD\Administrator","srv-01"
"@ | Out-File -FilePath 'D:\Temp\ProcData.csv'

$headers = (
    (Get-Content -Path 'D:\Temp\ProcData.csv') -replace '"','' | 
    select -First 1
) -split ','

$data    = Import-Csv -Path 'D:\Temp\ProcData.csv'
$colCnt  = $headers.count
$lineNum = 0

:newline
foreach ($line in $data)
{
    $lineNum++
    for ($i = 0; $i -lt $colCnt; $i++)
    {
        # test to see if contents of a cell is empty
        if (-not $line.$($headers[$i]))
        {
            Write-Warning -Message "$($lineNum): $($headers[$i]) is blank"
            continue newline
        }
    }
    "$($lineNum): OK"
    # Perform other actions with good data
}

<#
# Results

1: OK
WARNING: 2: UserName is blank
3: OK
WARNING: 4: ProcessName is blank
#>
postanote
  • 15,138
  • 2
  • 14
  • 25