web-dev-qa-db-fra.com

Remplacement du contenu d'un fichier texte à l'aide de PowerShell

J'ai parcouru tout ce site et je n'arrive pas à trouver quoi que ce soit qui correspond à ma situation. Fondamentalement, j'essaie d'écrire un ajout au fichier NETLOGON qui remplacera le texte d'un fichier texte sur tous les ordinateurs de bureau de nos utilisateurs. Le texte actuel est statique dans tous les domaines.

Le texte que je souhaite modifier sera unique pour chaque utilisateur. Je souhaite remplacer le texte actuel (utilisateur1) par le nom d'utilisateur AD de l'utilisateur (par exemple, johnd, janed, etc.). J'utilise Windows Server 2008 R2 et tous les postes de travail sont Windows 7 Professional SP1 64 bits.

Voici ce que j'ai essayé jusqu'à présent (avec quelques variables dont aucune n'a fonctionné pour une raison ou une autre):

gc c:\Users\%USERNAME%\desktop\VPN.txt' -replace "user1",$env:username | out-file c:\Users\%USERNAME%\desktop\VPN.txt

Je n'ai pas eu d'erreur, mais il n'est pas retourné à la normale "PS C:>" Invite, juste ">>>" et le fichier n'a pas changé comme prévu.

6
Timothy White

Si c'est ainsi que vous avez exactement le code, alors je suppose que c'est parce que vous avez une citation simple d'ouverture sans une citation de fermeture. Vous allez toujours avoir deux autres problèmes et vous avez une réponse dans votre code. Le >>> correspond aux caractères de continuation de la ligne, car l'analyseur sait que le code n'est pas complet et vous offre la possibilité de continuer avec le code. Si vous codez volontairement une seule ligne sur plusieurs lignes, vous considéreriez cela comme une fonctionnalité. 

$path = "c:\Users\$($env:username)\desktop\VPN.txt" 
(Get-Content $path) -replace "user1",$env:username | out-file $path 
  • Ferme le chemin entre guillemets et utilise une variable puisque tu as appelé le chemin deux fois.
  • %name% est utilisé dans l'invite de commande. Les variables d'environnement dans PowerShell utilisent le fournisseur $env: que vous avez déjà indiqué dans votre extrait.
  • -replace est un outil remplacé par une expression régulière qui peut fonctionner sur Get-Content, mais vous devez d'abord capturer le résultat dans une sous-expression.
  • Deuxièmement, avec -replace, c'est pour regex et votre chaîne n'est pas basée sur les regex, vous pouvez simplement utiliser .Replace()
  • Set-Content est généralement préférable à Out-File pour des raisons de performances.

Tout cela étant dit ...

vous pouvez aussi essayer quelque chose comme ça. 

$path = "c:\Users\$($env:username)\desktop\VPN.txt"
(Get-Content $path).Replace("user1",$env:username) | Set-Content $path 

Voulez-vous seulement remplacer la première occurrence?

Vous pouvez utiliser un peu regex ici avec un Tweak dans la façon dont vous obtenez l'utilisation Get-Content 

$path = "c:\Users\$($env:username)\desktop\VPN.txt" 
(Get-Content $path | Out-String) -replace "(.*?)user1(.*)",('$1{0}$2' -f $env:username) | out-file $path 

Regex correspondra au fichier entier. Il capture deux groupes.

  1. (.*?) - Jusqu'au premier "utilisateur1"
  2. (.*) - Tout après 

Nous utilisons ensuite l’opérateur de format pour intercaler le nouveau nom d’utilisateur entre ces groupes de capture. 

16
Matt

Utilisation:

(Get-Content $fileName) | % {
    if ($_.ReadCount -eq 1) {
        $_ -replace "$original", "$content"
    }
    else {
        $_
    }
} | Set-Content $fileName
0
KP Singh