2009-10-04 3 views
3

Я новичок в PowerShell. Я использовал образец сценария и заменил get-item на get-content в первой строке. Модифицированный сценарий выглядит следующим образом:Как изменить атрибут чтения для списка файлов?

$file = get-content "c:\temp\test.txt" 
if ($file.IsReadOnly -eq $true) 
{ 
$file.IsReadOnly = $false 
} 

Таким образом, в сущности, я пытаюсь пунктов действий, содержащихся в test.txt хранящегося как пути UNC

\\testserver\testshare\doc1.doc 
\\testserver2\testshare2\doc2.doc 

При запуске сценария ошибки не сообщается и никаких действий выполняется даже при первом входе.

ответ

8

Короткий ответ:

sp (gc test.txt) IsReadOnly $false 

Длинный ответ ниже


Ну, некоторые вещи не так с этим.

$file на самом деле string[], содержащий строки вашего файла. Таким образом, свойство IsReadOnly относится к string[], а не к фактическим файлам, представленным этими строками, которые являются именами файлов.

Итак, если я правильно понимаю вас, вы пытаетесь прочитать файл, содержащий другие имена файлов, по одному в каждой строке. И очистите атрибут «только для чтения» для этих файлов.

Начиная с Get-Content здесь не все правильно. Мы определенно понадобятся:

$filenames = Get-Content test.txt 

Теперь у нас есть список имен файлов. Чтобы получить доступ к атрибутам файла, нам нужно либо преобразовать эти имена файлов в фактические объекты FileInfo, и работать с ними. Или мы передаем имена файлов аргументу -PathSet-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 при использовании в качестве логического значения. Но я думаю, что здесь хватает сокращения.

2

У Йоханнеса есть сводная информация о теории, с которой вы столкнулись. Я просто хотел бы отметить, что, если вам случится быть с помощью PowerShell Community Extensions вы можете выполнить это с помощью Set-записываемой и Set-ReadOnly команды, которые трубопровод известен, например:

Get-Content "c:\temp\test.txt" | Set-Writable 

или короткая, совмещенная форма:

gc "c:\temp\test.txt" | swr 

Псевдоним для Set-ReadOnly is sro. Я использую эти команды еженедельно, если не ежедневно.

+0

Ах, хорошо. Похоже, я должен глубже изучить PSCX. В ярости я их только установил для работы в Out-Clipboard. – Joey