Для этого, я думаю, вам нужен другой подход, где вы рекурсивно получаете коллекцию файлов * .lnk и фильтруете, чтобы получить только те, которые имеют свойство BaseName
, которое можно найти в CSV.
Затем используйте Group-Object
для группировки (создания под-коллекций) этих объектов FileInfo на основе их BaseName.
Согласно документам , параметр Path
в командлете Add-NTFSAccess
может принимать массив путей (свойства FullName), и они могут быть переданы по нему, поэтому мы можем отправить все подколлекции одновременно:
$FolderPath = "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Accessories"
$file = "C:\Users\adm\Desktop\Group.csv"
$groups = Import-Csv -Path $file
# get a list of *.lnk FileIfo objects where the file's BaseName can be found in the
# CSV column 'Name'. Group these files on their BaseName properties
$linkfiles = Get-ChildItem -Path $FolderPath -Filter '*.lnk' -File -Recurse -Force |
Where-Object { $groups.Name -contains $_.BaseName } |
Group-Object BaseName
# iterate through the grouped *.lnk files
$linkfiles | ForEach-Object {
$baseName = $_.Name # the name of the Group is the BaseName of the files in it
$adGroup = ($groups | Where-Object { $_.Name -eq $baseName }).AD
# pipe all items in the group through to the Add-NTFSAccess cmdlet
# see parameter Path at https://ntfssecurity.readthedocs.io/en/latest/Cmdlets/Add-NTFSAccess/
$_.Group | Add-NTFSAccess -Account $adGroup -AccessRights ReadAndExecute
}
ОБНОВЛЕНИЕ
# this is where the output 'log' csv file goes
$outputFile = "C:\Users\adm\Desktop\GroupReport.csv"
# get a list of *.lnk FileIfo objects where the file's BaseName can be found in the
# CSV column 'Name'. Group these files on their BaseName properties
$linkfiles = Get-ChildItem -Path $FolderPath -Filter '*.lnk' -File -Recurse -Force |
Where-Object { $groups.Name -contains $_.BaseName } |
Group-Object BaseName
# iterate through the grouped *.lnk files and add the group permission
# capture the results in a variable $log to output as CSV
$linkfiles | ForEach-Object {
$baseName = $_.Name # the name of the Group is the BaseName of the files in it
$adGroup = ($groups | Where-Object { $_.Name -eq $baseName }).AD
# create a new access rule
# see: https://docs.microsoft.com/en-us/dotnet/api/system.security.accesscontrol.filesystemaccessrule
$rule = [System.Security.AccessControl.FileSystemAccessRule]::new($adGroup, "ReadAndExecute", "Allow")
$_.Group | ForEach-Object {
# get the current ACL of the file
$acl = Get-Acl -Path $_.FullName
# add the new rule to the ACL
$acl.SetAccessRule($rule)
$acl | Set-Acl $_.FullName
# output for logging csv
[PsCustomObject]@{
'Group' = $adGroup
'File' = $_.FullName
}
}
} | Export-Csv -Path $outputFile -NoTypeInformation