0
votes

This seems like it should be simple, and I'm sure it is, but I've not cracked it the best way it should be done.

I want to search through a folder structure returning folders which meet the following conditions.

  1. Folders which contain .msi files, but don't include executable files.

  2. Folders which contain .exe files, but don't include .msi files.

  3. Folders which contain both exe and msi files.

Each of these will be piped to a column in a CSV file.

My problem is I can't work out how to effectively return folder names which include one file type, but exclude another. I know on paper this seems simple using -include *.msi, -exclude *.exe, etc., but a command such as gci -Recurse -Include *.msi -Exclude *.exe includes folders containing an msi and exe folder where I only want that folder containing msi's only to be returned.

I am using the following directory structure as a test

msi only

msi and exe

exe only

Does this make sense?

I was experimenting with | where directory -notcontains *.exe and all kinds of similar things, but none of them worked the way I wanted or expected.

1

1 Answers

2
votes

Unfortunately include and exclude only work with the recurse parameter. You won't be able to do exclusion without recursion.

Here's an alternative.

$folders = dir -path ~ -recurse | ? {$_.PsIsContainer}
$folders | ForEach-Object {
     $exe_files = $_ | dir -filter *.exe
     $msi_files = $_ | dir -filter *.msi
     $type = ''
     if ($exe_files -and $msi_files) {$type = 'Both'}
     if ($msi_files -and -not $exe_files) {$type = 'MSI_ONLY'}
     if ($exe_files -and -not $msi_files) {$type = 'EXE_ONLY'}
     if ($type) {
          New-Object -TypeName PsObject -Property @{Path=$_.FullName;Type="$type"}
     }
} | ConvertTo-Csv | Set-Content ~\out.csv