Currently you're looping twice over all files, so it would already be an improvement if you incremented two variables in the same loop, and then returned a boolean value indicating whether the count is different or not:
function AllReadOnly {
Param([string]$Path)
$all = 0
$ro = 0
Get-ChildItem $Path -Recurse -File | ForEach-Object {
$all++
if ($_.Attributes.value__ -band 1) { $ro++ }
}
$all -eq $ro
}
However, since you want to check if all files are read-only it would suffice to return $false
as soon as you encounter the first writable file:
function AllReadOnly {
Param([string]$Path)
Get-ChildItem $Path -Recurse -File | ForEach-Object {
if (-not ($_.Attributes.value__ -band 1)) {
$false
continue
}
}
$true
}
Edit:
$_.Attributes.value__
is the numeric value of the file's attributes. The binary value 1 indicates that the read-only flag is set, so if a bitwise/logical AND of the attributes value and 1 returns a value != 0 the flag is set, otherwise it's not set. That's because a logical AND returns true/1 only if both operands are true/1 and false/0 otherwise.
Example:
101001
AND 000001
------
000001 ← flag set
101000
AND 000001
------
000000 ← flag not set
See Wikipedia for further information about Boolean algebra.