2

I have a PS script, which loops through file folders and archive some of them:

$CSV = import-csv -path C:\folder\Builds\ApplicationsMappingNew.csv
$Application = $CSV.Application

$GetAppPath = Get-ChildItem -Path $DestinationDir\Server\*

foreach($line in $GetAppPath){

        $AppPath = $Line.fullname
        $AppName = Split-Path $AppPath -Leaf
        $RAR_Destination = "C:\folder\Builds\test1\SOA-ConfigurationManagement"+"\"+"$AppName"+"_st-FTP.rar"
        Push-Location $AppPath
        & "C:\Program Files (x86)\WinRAR\rar" a -r $RAR_Destination 
}

And I have a CSV file, which has an Application column:

enter image description here

My question is - how, inside a foreach loop, can I compare the $Appname loop variable value with the values inside the $Application array variable?

And, if the value of $AppName equals a value inside the $Application array, execute Push-Location and execute a winrar command. If not, skip to next element in foreach($line in $GetAppPath)?

mklement0
  • 382,024
  • 64
  • 607
  • 775
Vasyl Stepulo
  • 1,493
  • 1
  • 23
  • 43

2 Answers2

3

To answer the question as asked:

if the value of $AppName equals a value inside the $Application array

Use either of the following tests:

if ($AppName -in $Application) { ... 
if ($Application -contains $AppName) { ... 

The above performs literal, whole-value, case-insensitive matching to see if $AppName is contained in (matches an element of) array $Application - see the bottom section for details.


Based on your own answer, what you actually needed was not equality comparison, but wildcard matching.

You can use the -like operator, because - like many PowerShell comparison operators, it can operate on arrays (collections):

if ($Application -like "$AppName*") { ... }

Note that this works slightly differently, in that -like with an array-valued LHS doesn't return a Boolean, but acts as an array filter; that is, it returns an array of matching elements; if nothing matches, you get an empty array.

Thanks to PowerShell's implicit to-Boolean conversion, however, the returned array can be treated like a Boolean, so the conditional is effectively $false if nothing matches (empty array), and $true if at least one element matched (non-empty array with nonempty strings).


PowerShell's containment operators, -in and -contains:

PowerShell offers two (collection) containment operators:

  • <potential-member> -in <collection> (the negation exists too: -notin)
  • <collection> -contains <potential-member> (the negation exists too: -notcontains)

Both essentially perform an -eq test of <potential-member> agains each element of <collection> and return a Boolean ($true or $false) to indicate if (at least) one element of the collection matches the potential member.

For strings, as with -eq, each element is tested against the potential member using literal, whole-value, case-insensitive matching.

For more information about these operators, see this answer.

mklement0
  • 382,024
  • 64
  • 607
  • 775
0

Using @mklement0 hint, I've assembled following solution:

$CSV = import-csv -path C:\test\ApplicationsMappingNew.csv
$Application = $CSV.Application
$GetAppPath = Get-ChildItem -Path $DestinationDir\Server\*

foreach($line in $GetAppPath){

    $AppPath = $Line.fullname
    $AppName = Split-Path $AppPath -Leaf
    $Appswitch = "$AppName"+"*"
    $RAR_Destination = "C:\folder\Builds\test1\SOA-ConfigurationManagement"+"\"+"$AppName"+"_st-FTP.rar"
    switch ($Appswitch) {$Application -like $_} { 
        Push-Location $AppPath
        &"C:\Program Files (x86)\WinRAR\rar" a -r $RAR_Destination 
        } 
        default {Write-Host "Application $AppName is not in csv file."}
}
Vasyl Stepulo
  • 1,493
  • 1
  • 23
  • 43
  • 1
    That is a little convoluted. You could use `switch ($Application) -Wildcard { $Appswitch { ... } }`, but note that simply using `if ($Application -like $Appswitch) { ... }` is sufficient in your case. – mklement0 Nov 22 '19 at 13:05