locked
Where-Object : A positional parameter cannot be found that accepts argument 'Foreach' RRS feed

  • Question

  • PS U:\> PS U:\> $OutFile = "C:\temp\Documents\Permissions1.csv" # Insert folder path where you want to save your file and its name
    $Header = "Folder Path,IdentityReference,AccessControlType,IsInherited,InheritanceFlags,PropagationFlags"
    $FileExist = Test-Path $OutFile 
    If ($FileExist -eq $True) {Del $OutFile} 
    Add-Content -Value $Header -Path $OutFile 
    $RootPath = "\\server\sharename" # Insert your share path
    Get-ChildItem $RootPath | where {$_.psiscontainer} | where { $_ | Get-Acl | select -ExpandProperty Access | where {$_.IdentityReference -contains $aclfullname}}
    $Folders = dir $RootPath -recurse | where {$_.psiscontainer -eq $true} Foreach $Folder in $Folders{
        $ACLs = get-acl $Folder.fullname | ForEach-Object { $_.Access  }
        Foreach ($ACL in $ACLs){
        $OutInfo = $Folder.Fullname + "," + $ACL.IdentityReference  + "," + $ACL.AccessControlType + "," + $ACL.IsInherited + "," + $ACL.InheritanceFlags + "," + $ACL.PropagationFlags
        Add-Content -Value $OutInfo -Path $OutFile 
        }}

    Thanks in advance.

    Tuesday, August 21, 2018 1:12 PM

All replies

  • Please use the 'Insert code block' tool provided.

    $OutFile = "C:\temp\Documents\Permissions1.csv" # Insert folder path where you want to save your file and its name
    $Header = "Folder Path,IdentityReference,AccessControlType,IsInherited,InheritanceFlags,PropagationFlags"
    $FileExist = Test-Path $OutFile 
    If ($FileExist -eq $True) {Del $OutFile} 
    Add-Content -Value $Header -Path $OutFile 
    $RootPath = "\\server\sharename" # Insert your share path
    Get-ChildItem $RootPath | where {$_.psiscontainer} | where { $_ | Get-Acl | select -ExpandProperty Access | where {$_.IdentityReference -contains $aclfullname}}
    $Folders = dir $RootPath -recurse | where {$_.psiscontainer -eq $true} Foreach $Folder in $Folders{
        $ACLs = get-acl $Folder.fullname | ForEach-Object { $_.Access  }
        Foreach ($ACL in $ACLs){
        $OutInfo = $Folder.Fullname + "," + $ACL.IdentityReference  + "," + $ACL.AccessControlType + "," + $ACL.IsInherited + "," + $ACL.InheritanceFlags + "," + $ACL.PropagationFlags
        Add-Content -Value $OutInfo -Path $OutFile 
        }}

    You will need to work on your styling. The indenting and opening/closing curly braces are not located well, thus making it hardly readable and that's why you aren't able to solve the error yourself.

    It's going wrong right here:

    $Folders = dir $RootPath -recurse | where {$_.psiscontainer -eq $true} Foreach $Folder in $Folders{

    You are initiating a ForEach-Object after the Where-Object, without using the pipeline.

    Tuesday, August 21, 2018 1:20 PM
  • $outFile = "C:\temp\Documents\Permissions1.csv" # Insert folder path where you want to save your file and its name
    $header = "Folder Path,IdentityReference,AccessControlType,IsInherited,InheritanceFlags,PropagationFlags"
    $fileExist = Test-Path $outFile 
    
    if ($FileExist -eq $true) {
        Remove-Item $outFile
    }
    
    Add-Content -Value $Header -Path $outFile 
    $rootPath = "\\server\sharename" # Insert your share path
    
    Get-ChildItem $rootPath | 
        Where-Object { $_.psiscontainer } | 
        Where-Object { $_ | 
            Get-Acl | 
            Select-Object -ExpandProperty Access | 
            Where-Object { $_.IdentityReference -contains $aclfullname}
        }
    
    $Folders = Get-ChildItem $rootPath -recurse | 
        Where-Object { $_.psiscontainer -eq $true }
    
    foreach ($folder in $folders) {
        $ACLs = get-acl $folder.fullname | ForEach-Object { $_.Access }
        foreach ($ACL in $ACLs) {
            $outInfo = $folder.Fullname + "," + $ACL.IdentityReference  + "," + $ACL.AccessControlType + "," + $ACL.IsInherited + "," + $ACL.InheritanceFlags + "," + $ACL.PropagationFlags
            Add-Content -Value $outInfo -Path $outFile 
        }
    }

    I fixed the styling here and there. There are some unnecessary nested Where-Objects. Take a look at the PowerShell Best Practices and Style Guide try and avoid using aliases (del instead of Remove-Item, dir instead of Get-ChildItem, foreach instead of ForEach-Object). Take note of where the opening and closing curly braces are location and check out the indenting used. 

    Tuesday, August 21, 2018 1:32 PM
  • Hi,

    Thanks for your question.

    Also thanks for the answer by John, I got a lot from his share.

    There are some differences between using foreach and using foreach-object. 

    When you are piping input into ForEach, it is the alias for ForEach-Object. But when you place ForEach at the beginning of the line, it is a Windows PowerShell statement. ForEach-Object is best used when sending data through the pipeline because it will continue streaming the objects to the next command in the pipeline. You cannot do the same thing with ForEach () {} because it will break the pipeline and throw error messages if you attempt to send that output to another command.

    Refer the link below:

    https://blogs.technet.microsoft.com/heyscriptingguy/2014/07/08/getting-to-know-foreach-and-foreach-object/

    Best Regards,

    Lee


    Just do it.

    Wednesday, August 22, 2018 2:38 AM
  • While all of that is true that is not what the issue is in the code you have copied.  The simple issue is that you are missing a line break and the syntax of the code is incorrect for either type of "foreach".

    This:

    $Folders =dir $RootPath -recurse | where {$_.psiscontainer -eq $true} Foreach$Folder in$Folders{

    Should be this:

    $Folders =dir $RootPath -recurse | where {$_.psiscontainer -eq $true}
    Foreach($Folder in$Folders){

    This is a common mistake caused by copying code without understanding coding or PowerShell.  Attempts to change or fix bad code lead to this kind of failure.

    There are many other issues with the code:

    This piece of code does nothing:

    Get-ChildItem $rootPath| 
        Where-Object { $_.psiscontainer } | 
        Where-Object { $_ | 
            Get-Acl | 
            Select-Object -ExpandProperty Access | 
            Where-Object { $_.IdentityReference -contains $aclfullname}
        }

    Here is how to code your task in PowerShell.  Once you learn PowerShell you will see that these things are much easier than you think.

    $csvFile = 'C:\temp\Documents\Permissions1.csv'
    $sharePath = '\\server\sharename'
    
    Get-ChildItem $sharePath -recurse -Directory -PipelineVariable fldr|
        Get-Acl  |
        Select-Object -Expand Access |
        Select-Object @{n='FolderPath';e={$fldr.Fullname}},IdentityReference,AccessControlType,IsInherited,InheritanceFlags,PropagationFlags |
        Export-Csv $csvFile -NoTypeInformation
    Selecting go variable names and function names will eliminate the need for most hard to read and understand comments.


    \_(ツ)_/


    • Edited by jrv Wednesday, August 22, 2018 3:43 AM
    Wednesday, August 22, 2018 3:41 AM