В настоящее время вы зацикливание дважды все файлы, так что уже будет улучшение, если приращение двух переменных в том же цикле, а затем возвращают логическое значение, указывающее, отличается ли счетчик или нет:
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
}
Однако, так как вы хотите, чтобы проверить, если все файлы только для чтения было бы достаточно, чтобы вернуть $false
как только вы столкнулись первый файл записываемый:
function AllReadOnly {
Param([string]$Path)
Get-ChildItem $Path -Recurse -File | ForEach-Object {
if (-not ($_.Attributes.value__ -band 1)) {
$false
continue
}
}
$true
}
Edit:
$_.Attributes.value__
является числовым значением атрибутов файла. Бинарное значение 1 указывает, что установлен флаг только для чтения, поэтому, если бит-логический И из значения атрибутов и 1 возвращает значение! = 0, флаг установлен, в противном случае он не установлен. Это потому, что логическое И возвращает true/1, только если оба операнда истинны/1 и false/0 в противном случае.
Пример:
101001
AND 000001
------
000001 ← flag set
101000
AND 000001
------
000000 ← flag not set
См Wikipedia для получения дополнительной информации о булевой алгебре.
Спасибо большое, я отметил это как ответ на данный момент! Можете ли вы рассказать о частичной части ($ _. Attributes.value__ -band 1)? Этот синтаксис и эти ключевые слова мне незнакомы! –
И не будет продолжена проверка следующей итерации? Разве это не должно быть нарушено, потому что, если я нашел файл, который не читается, цикл должен заканчиваться? Или вернуться даже? –
См. [Здесь] (http://stackoverflow.com/a/9835285/1630171). 'return' не работал, как я и ожидал, поэтому я прибегал к' $ false; continue'. –