Краткий ответ:
sp (gc test.txt) IsReadOnly $false
Длинный ответ ниже
Ну, некоторые вещи не так с этим.
$file
на самом деле string[]
, содержащий строки вашего файла. Таким образом, свойство IsReadOnly
применяется к string[]
, а не к фактическим файлам, представленным теми строками, которые являются именами файлов.
Итак, если я правильно вас понимаю, вы пытаетесь прочитать файл, содержащий другие имена файлов, по одному в каждой строке. И очистите атрибут «Только чтение» для этих файлов.
Начиная с Get-Content
здесь все не так. Нам определенно это понадобится:
$filenames = Get-Content test.txt
Теперь у нас есть список имен файлов. Чтобы получить доступ к атрибутам файла, нам нужно либо преобразовать эти имена файлов в реальные FileInfo
объекты и работать с ними. Или мы передаем имена файлов в аргумент -Path
Set-ItemProperty
.
Сначала я выберу первый подход, а затем перейду к другому. Итак, у нас есть куча имен файлов и мы хотим получить FileInfo
объекты из них. Это можно сделать с помощью цикла foreach
(поскольку нам нужно сделать это для каждого файла в списке):
$files = (foreach ($name in $filenames) { Get-Item $name })
Затем вы можете зациклить имена файлов и установить свойство IsReadOnly
для каждого из них:
foreach ($file in $files) {
$file.IsReadOnly = $false
}
Это был длинный и громоздкий вариант. Но тот, который, вероятно, больше всего подходит людям, не имеющим опыта работы с PowerShell. Вы можете уменьшить потребность в наличии множества коллекций вещей, используя конвейер. Конвейер переносит объекты из одного командлета в другой, и эти объекты по-прежнему имеют типы.
Итак, написав
Get-Content test.txt | Get-Item | ForEach-Object { $_.IsReadOnly = $false }
мы достигаем точно такого же результата. Мы читаем содержимое файла, получая кучу string
с. Они передаются в Get-Item
, который знает, что делать с конвейером: он обрабатывает эти объекты как пути к файлам; именно то, что нам нужно здесь. Get-Item
затем отправляет FileInfo
объектов дальше по конвейеру, после чего мы зацикливаемся на них и устанавливаем для свойства только для чтения значение false
.
Теперь, это было короче и, с небольшой практикой, может быть, даже проще. Но это все еще далеко от идеала. Как я уже говорил, мы можем использовать Set-ItemProperty
, чтобы установить свойство «только для чтения» для файлов. И мы можем воспользоваться тем фактом, что Set-ItemProperty
может принимать массив строк в качестве входных данных для своего параметра -Path
.
$files = Get-Content test.txt
Set-ItemProperty -Path $files -Name IsReadOnly -Value $false
Здесь мы используем временную переменную, поскольку Set-ItemProperty
не будет принимать входящие строки в качестве значений для -Path
напрямую. Но мы можем встроить эту временную переменную:
Set-ItemProperty -Path (Get-Content test.txt) -Name IsReadOnly -Value $false
Круглые скобки вокруг вызова Get-Content
необходимы, чтобы сообщить PowerShell, что это единственный аргумент, и его следует сначала оценить.
Затем мы можем воспользоваться тем фактом, что каждый из этих параметров используется в той позиции, где Set-ItemProperty
ожидает его, поэтому мы можем опустить имена параметров и придерживаться только значений:
Set-ItemProperty (Get-Content test.txt) IsReadOnly $false
И затем мы можем сократить имена командлетов до их псевдонимов по умолчанию:
sp (gc test.txt) IsReadOnly $false
Мы могли бы написать $false
как 0
, чтобы сэкономить еще больше места, поскольку 0
преобразуется в $false
при использовании в качестве логического значения. Но я думаю, что здесь достаточно сокращения.