2009-10-04 6 views
3

Je suis novice powershell. J'ai utilisé un exemple de script et fait un substitut de get-item à get-content dans la première ligne. Le script modifié ressemble ci-dessous:Comment changer l'attribut read pour une liste de fichiers?

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

Donc, en substance, je suis en train de points d'action contenus dans test.txt stockés sous forme de chemins UNC

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

Lorsque l'exécution du script sans erreurs sont signalées et aucune action est effectuée même lors de la première entrée.

Répondre

8

Réponse courte:

sp (gc test.txt) IsReadOnly $false 

Réponse longue ci-dessous


Eh bien, certaines choses sont mal à cela.

$file est en fait un string[], contenant les lignes de votre fichier. Donc, la propriété IsReadOnly s'applique à le string[] et non aux fichiers réels représentés par ces chaînes, qui se trouvent être des noms de fichiers. Donc, si je vous comprends bien, vous essayez de lire un fichier, contenant d'autres noms de fichiers, un sur chaque ligne. Et désactivez l'attribut en lecture seule sur ces fichiers. À partir de Get-Content ne se trompe pas ici. Nous allons certainement en avoir besoin:

$filenames = Get-Content test.txt 

Maintenant, nous avons une liste de noms de fichiers. Pour accéder aux attributs du fichier, nous devons soit convertir ces noms en objets réels FileInfo et opérer sur ceux-ci. Ou nous passons les noms de fichiers à un argument -Path de Set-ItemProperty. Je vais d'abord prendre la première approche et ensuite passer à l'autre. Donc, nous avons un tas de noms de fichiers et voulons FileInfo objets d'eux. Cela peut se faire avec une boucle foreach (puisque nous devons le faire pour chaque fichier dans la liste):

$files = (foreach ($name in $filenames) { Get-Item $name }) 

Vous pouvez ensuite en boucle sur les noms de fichiers et définir la propriété IsReadOnly sur chacun d'eux:

foreach ($file in $files) { 
    $file.IsReadOnly = $false 
} 

C'était la variante longue et encombrante. Mais celui qui convient le mieux aux gens sans expérience préalable à PowerShell. Vous pouvez réduire le besoin d'avoir plusieurs collections de choses qui traînent en utilisant le pipeline. Le pipeline transporte des objets d'une cmdlet à une autre et ces objets ont toujours des types.

en écrivant

Get-Content test.txt | Get-Item | ForEach-Object { $_.IsReadOnly = $false } 

nous réaliser exactement le même résultat. Nous lisons le contenu du fichier, obtenant un tas de string s. Ceux-ci sont passés à Get-Item qui sait ce qu'il faut faire avec l'entrée de pipeline: Il traite ces objets comme des chemins de fichier; exactement ce dont nous avons besoin ici.Get-Item envoie ensuite FileInfo objets plus bas dans le pipeline, à quel point nous sommes en boucle sur eux et en définissant la propriété en lecture seule à false. Maintenant, c'était plus court et, avec un peu de pratique, peut-être même plus facile. Mais c'est encore loin d'être idéal. Comme je l'ai déjà dit, nous pouvons utiliser Set-ItemProperty pour définir la propriété en lecture seule sur les fichiers. Et nous pouvons profiter du fait que Set-ItemProperty peut prendre un tableau de chaînes en entrée pour son paramètre -Path.

$files = Get-Content test.txt 
Set-ItemProperty -Path $files -Name IsReadOnly -Value $false 

Nous utilisons ici une variable temporaire, puisque Set-ItemProperty n'acceptera pas les chaînes entrantes sous forme de valeurs pour -Path directement. Mais nous pouvons inline cette variable temporaire:

Set-ItemProperty -Path (Get-Content test.txt) -Name IsReadOnly -Value $false 

Les parenthèses autour du Get-Content appel sont nécessaires pour dire que ce PowerShell est un argument unique et doit être évalué en premier.

Nous pouvons alors tirer profit du fait que chacun de ces paramètres est utilisé dans la position où Set-ItemProperty attend qu'il soit, afin que nous puissions laisser les noms de paramètres et simplement coller aux valeurs:

Set-ItemProperty (Get-Content test.txt) IsReadOnly $false 

Et nous pouvons raccourcir les noms de cmdlet à leurs alias par défaut:

sp (gc test.txt) IsReadOnly $false 

nous pourrions écrire $false comme 0 pour économiser encore plus d'espace, puisque 0 est converti en $false lorsqu'il est utilisé en tant que valeur booléenne. Mais je pense qu'il suffit de raccourcir ici.

2

Johannes a le scoop sur la théorie derrière le problème que vous rencontrez. Je voulais juste signaler que si vous arrive d'utiliser la PowerShell Community Extensions vous pouvez effectuer cela en utilisant le Set inscriptibles et les commandes Set-ReadOnly qui sont pipeline au courant, par exemple:

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

ou la forme courte, aliasé:

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

L'alias de Set-ReadOnly est sro. J'utilise ces commandes chaque semaine sinon tous les jours.

+0

Ah, bien. On dirait que je devrais regarder plus en profondeur dans PSCX. Actuellement, je les ai seulement installés au travail pour Out-Clipboard. – Joey

Questions connexes