Read SIDs and set ACLs The following script reads a set of SIDs inside firewall rules and uses them to set ACL rules in a folder.

The question is: Is this syntax ok or is there better ways to write this script, considering powershell syntax features? (by the way, this code works)

param([Parameter(Mandatory)]$foldername)

$result=""

(Get-NetFirewallRule | Where-Object { ($_.Direction -eq "Outbound") -and ($_.DisplayName -like "*appcontainer*")}) |
         %{ ($_ | Get-NetFirewallApplicationFilter) | 
        %{  $acl = Get-Acl $foldername
            $sec= New-Object System.Security.Principal.SecurityIdentifier($_.Package)
            $AccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule($sec,"FullControl",(1 -bor 2),0, "Allow") 
            $acl.SetAccessRule($AccessRule)
            $acl | Set-Acl $foldername
          } }
nope! [grin]   

this is almost entirely about style, not performance. you will note that most points are about readability ... the following line is quite true ...     

better readability gives better understanding gives better maintainability.    

[1] never use aliases or short names in a script that will be shared or reused
why? code is READ far more often than written, so make it easy to read.    

[2] use consistent indents
your indentation makes it needlessly unclear where each stage begins and ends. see [1] for why that is important.    

[3] you need comments describing the purpose of the code
again, someone who reads your code next month [perhaps you] needs some sort of idea as to the intent of your code.    

[4] avoid long lines
you have two lines that run well off to the right. since PoSh knows that things like pipe symbols WILL be followed by more stuff, you can wrap after such. that also applies to commas, open parens, and other such "more to come" items.    

why bother? once again, it is about reading. there is a reason why most wide-format publications to use multiple columns ... people tend to read more comfortably when the lines require minimal side-to-side eye movement. that works out to about 80 to 100 chars per line.    

make use of the vertical space you have available. folks scan vertically somewhat more easily than horizontally.    

[5] use consistent variable case
you use lowercase and PascalCase. try to stick with ONE such style ... and PascalCase is the one usually recommended.    

[6] read the officially referenced unofficial style &amp; best practices guide
this ...   

PoshCode/PowerShellPracticeAndStyle: The Unofficial PowerShell Best Practices and Style Guide
— https://github.com/PoshCode/PowerShellPracticeAndStyle    

[7] remove unused code
you define $Result ... but never use it. i would remove that.    

[8] define the type for your parameter
your $FolderName parameter type is not defined. i suspect it is [string], tho.    

[9] avoid sending things across a pipe if you can
you send $_ to Get-NetFirewallApplicationFilter via a pipe. pipeline ops are slower than direct ops &amp; it looks like you could call that out by using the parameter name directly.    



here's how i would rework your code layout ...  

Param (
    [Parameter(
        Mandatory)]
        [string]
        $FolderName
    )

Get-NetFirewallRule |
    Where-Object {
        $_.Direction -eq "Outbound" -and
        $_.DisplayName -like "*appcontainer*"
        } |
    ForEach-Object {
        # i wonder if the next two lines could be done as 
        #    Get-NetFirewallApplicationFilter -AssociatedNetFirewallRule $_
        $_ |
        Get-NetFirewallApplicationFilter | 
        ForEach-Object {
            $Acl = Get-Acl $FolderName
            $Sec= New-Object System.Security.Principal.SecurityIdentifier($_.Package)
            $AccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule(
                $Sec,
                "FullControl",
                (1 -bor 2),
                0,
                "Allow"
                )
            $Acl.SetAccessRule($AccessRule)
            $Acl |
                Set-Acl $FolderName
            } # end 2nd FE-O
        } # end 1st FE-O