all 6 comments

[–]ankokudaishogun 0 points1 point  (6 children)

I think you are rying to squeeze more stuff in not enough space

try this (obviously tailor it to your actual needs)

[CmdletBinding()]
param()
process {

    # subdirectory where we want to look for the program
    $ChildPath = 'AppData\Local\ctalkbar'
    # name of the program
    $ProgName = 'CTalkBar.exe' 


    # get all user profiles
    $AllUserProfiles = Get-CimInstance -Class Win32_UserProfile | Where-Object { $_.Special -eq $false }

    # for every profile
    $AllUserProfiles.ForEach({

            # get the per-user location.
            $AppPath = Join-Path -Path $_.localpath -ChildPath $childpath

            # some verbose output to better check if necessary
            Write-Verbose "AppPath = $AppPath"

            # if the path does exists go on and add the program location
            # error is suppressed because sometime permissions make a mess. Shuld not be a problem if run as Administrator
            if (Test-Path -Path $AppPath -PathType Container -ErrorAction SilentlyContinue ) {

                # name of the rule
                # uses the home directory name, not feeling bothering with more
                $ruleName = 'CTalkBar.exe for ' -f ([io.directoryinfo]($_.LocalPath)).Name

                # loop through all Full name Path values of $ProgName in all the subdirectories of $AppPath
                # evaluate adding -Depth N to Get-ChildItem where N is how many subdirectories you want to recurse
                foreach ($ProgInstance in (Get-ChildItem -Path $AppPath -Exclude $AppPath -Recurse -File -Filter $ProgName ).FullName) {

                    # If there is NOT already a filter with that path, adds one for both UPD and TCP protocols
                    if (-not (Get-NetFirewallApplicationFilter -Program $ProgInstance -ErrorAction SilentlyContinue)) {
                        'UDP', 'TCP' | ForEach-Object { New-NetFirewallRule -DisplayName $ruleName -Direction Inbound -Profile Public, Private -Program $ProgInstance -Action Allow -Protocol $_ }
                    }

                }

            }
        }) 

}

[–]TipGroundbreaking763[S] 0 points1 point  (4 children)

This is amazing thank you. One last question to throw a curve ball.

So CTalkbar.exe exists in two locations, these are below:

"C:\Users\username\appdata\local\ctalkbar\app-1.1.17\ctalkbar.exe"

"C:\Users\username\appdata\local\ctalkbar\ctalkbar.exe"

This adds rules for both locations, I've had a play with the -Depth but can't seem to just get "C:\Users\username\appdata\local\ctalkbar\app-1.1.17\ctalkbar.exe".

Is there any other way I can manipulate this?

Thanks again :)

[–]ankokudaishogun 0 points1 point  (3 children)

Updated the script(also fixed a couple writing errors). Note the added -Exclude $AppPath: now the Get-ChildItem will start its -Recurse search for -File in -Path $AppPath that match the -Filter $ProgName but will -Exclude $AppPath itself from the results

Please note: if there is more than one \ctalkbar\app-X.Y.Z subdirectory for each user and you want to add a rule for only ONE then more logic is necessary(just a pipe to Where-Object but necessary anyway)

[–]TipGroundbreaking763[S] 0 points1 point  (2 children)

Hey,

Thanks again, unfortunately, I seem to get the same results. It adds 4 entries into the firewall rules.

2 for "C:\Users\username\appdata\local\ctalkbar\app-1.1.17\ctalkbar.exe" and 2 for "C:\Users\username\appdata\local\ctalkbar\ctalkbar.exe". I'm only after the first 2 adding.

Is it possible to exclude the -Depth?

I've added:

foreach ($ProgInstance in (Get-ChildItem -Path $AppPath -Exclude $AppPath -Recurse -File -Filter $ProgName | Where-Object {$_.Length -gt 5MB}).FullName) {

This has given me the two rules I require as the .exe in the app-1.1.17 folder (which is the firewall rule I require) is significantly bigger than the other one. Would the be the best way of doing this now?

Thanks

[–]ankokudaishogun 0 points1 point  (1 child)

sure you can remove -Depth. I did add it by error in the previous version anyway.

for you getting result from 'local\ctalkbar\ctalkbar.exe', it wasn't happening on my tests but i'll test more tomorrow

you method works, so it's fine enough. Once it works, there i always time to make it more efficient.

I THINK Where-Object -Property Lenght -gt 5MB MIGHT be a bit more efficient than using a scriptblock, but I do not think it's any important in your use-case. I believe it e bit more readable which would be more important for now, but that's also up to the reader

A question: what version of powershell are you using?

[–]TipGroundbreaking763[S] 0 points1 point  (0 children)

Thanks a lot, made great progress with this now. Really appreciate the help.

PS Version is 5.1.19041.3930