简短的回答:
sp (gc test.txt) IsReadOnly $false
下面长答案
好吧,有些事情是错误的。
$file
实际上是 a 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 经验的人。通过使用管道,您可以减少对多个事物集合的需求。管道将对象从一个 cmdlet 传输到另一个,并且这些对象仍然具有类型。
所以通过写
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
然后我们可以将 cmdlet 名称缩短为其默认别名:
sp (gc test.txt) IsReadOnly $false
我们实际上可以写$false
as0
来节省更多空间,因为当用作布尔值时0
会转换为。$false
但我认为在这里缩短就足够了。