Короткий ответ:
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
s. Они передаются в 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
при использовании в качестве логического значения. Но я думаю, что здесь хватает сокращения.
Ах, хорошо. Похоже, я должен глубже изучить PSCX. В ярости я их только установил для работы в Out-Clipboard. – Joey