web-dev-qa-db-fra.com

Sortie ("echo") d'une variable dans un fichier texte

J'exécute un script PowerShell sur de nombreux serveurs et il enregistre la sortie dans un fichier texte.

J'aimerais capturer le serveur sur lequel le script est en cours d'exécution. Jusqu'à présent j'ai:

$file = "\\server\share\file.txt"
$computername = $env:computername

$computername | Add-Content -Path $file

Cette dernière ligne ajoute des points d'interrogation dans le fichier de sortie. Oops.

Comment exporter une variable dans un fichier texte dans PowerShell?

34
jcarpio

Après quelques essais et erreurs, j'ai trouvé que

$computername = $env:computername

travaille pour obtenir un nom d'ordinateur, mais l'envoi de $computername dans un fichier via Add-Content ne fonctionne pas.

J'ai aussi essayé $computername.Value.

Au lieu de cela, si j'utilise

$computername = get-content env:computername

Je peux l'envoyer dans un fichier texte en utilisant

$computername | Out-File $file
9
jcarpio

Le plus simple exemple de Hello World ...

$hello = "Hello World"
$hello | Out-File c:\debug.txt
55
bigtv

Remarque: La réponse ci-dessous est écrite du point de vue de Windows PowerShell.
Cependant, il s’applique également à la multiplication des plates-formes PowerShell Coreédition), sauf que cette dernière - de manière louable - régulièrementpar défaut à BOM-less UTF-8encodage de caractères) , qui est le plus largement compatible entre plates-formes et cultures.
.


Pour compléter réponse utile de bigtv réponse utile avec une alternative plus concise et des informations de base:

# > $file is effectively the same as | Out-File $file
# Objects are written the same way they display in the console.
# Default character encoding is UTF-16LE (mostly 2 bytes per char.), with BOM.
# Use Out-File -Encoding <name> to change the encoding.
$env:computername > $file

# Set-Content calls .ToString() on each object to output.
# Default character encoding is "ANSI" (culture-specific, single-byte).
# Use Set-Content -Encoding <name> to change the encoding.
# Use Set-Content rather than Add-Content; the latter is for *appending* to a file.
$env:computername | Set-Content $file 

Lorsque sortie dans un fichier texte _, vous avez 2 choix fondamentaux qui utilise différentes représentations d'objets et utilisez différent défautencodages de caractères} _:

  • Out-File (ou >)/Out-File -Append (Ou >>):

    • Convient aux objets de sortie de anytype _, car le formatage de sortie par défaut de PowerShell est appliqué aux objets de sortie.

      • En d'autres termes: vous obtenez le même résultat que lors de l'impression sur la console console.
    • Le codage par défaut}, qui peut être modifié avec le paramètre -Encoding, Est Unicode, ce qui est TF-16LE dans lequel la plupart des caractères sont codés sous la forme 2octets}. L'avantage d'un codage Unicode tel que UTF-16LE est qu'il s'agit d'un globalalphabet, capable de coder tous les caractères à partir de touteslangues humaines.

      • Dans PSv5.1 +, vous pouvez modifier le codage utilisé par > Et >>, Via la variable de préférence $PSDefaultParameterValues, profitant du fait que > et >> sont maintenant effectivement des alias de Out-File et Out-File -Append. Pour passer à UTF-8, par exemple, utilisez:
        $PSDefaultParameterValues['Out-File:Encoding']='UTF8'
  • Set-Content / Add-Content :

    • Pour écrire chaînes et les instances de types connus pour avoir des représentations de chaîne significatives, tels que les types de données de base .NET (booléens, entiers, ...).

      • .psobject.ToString()) est appelée sur chaque objet de sortie, ce qui donne des représentations dénuées de sens pour les types qui n'implémentent pas explicitement une représentation explicite; Les instances [hashtable] En sont un exemple:
        @{ one = 1 } | Set-Content t.txt Écrit littéralement System.Collections.Hashtable Dans t.txt, Qui est le résultat de @{ one = 1 }.ToString().
    • Le codage par défaut}, qui peut être modifié avec le paramètre -Encoding, Est Default, qui est la page de code "ANSI") du système. _, un codage sur un octet codage spécifique à la culturelegacy} pour les applications non Unicode, le plus souvent Windows-1252 .
      Notez que la documentation déclare actuellement à tort que ASCII est le codage par défaut).

    • Notez que le but de Add-Content Est de append contenu dans un fichier existant, et il n’est équivalent à Set-Content Que si le fichier cible n'existe pas encore.
      En outre, le le codage par défaut ou spécifié est aveuglémentappliqué}, quel que soit le codage du contenu existant du fichier.

Out-File/>/Set-Content/Add-ContentTous agissent culture -sensible), c'est-à-dire qu'ils produisent des représentations adaptées à la culture actuelle (paramètres régionaux), si disponible (bien que les données de formatage personnalisées soient libres de définir leur propre représentation invariante de culture - voir Get-Help about_format.ps1xml ). Cette contraste avec la chaîne de PowerShell expansioninterpolation de chaîne dans les chaînes entre guillemets), qui est culture -_ (invariant - voir cette réponse of mine.

En ce qui concerne performance _: Puisque Set-Content N'a pas à appliquer le formatage par défaut à son entrée, il fonctionne mieux.


Quant à le symptôme de l'OP avec Add-Content}:

Puisque $env:COMPUTERNAME Ne peut pas contenir de caractères non-ASCII, la sortie de Add-Content, Utilisant le codage "ANSI", devrait pasdonner les caractères ? Dans la sortie, et l'explication la plus probable est que le ? faisait partie du contenu préexistantdans le fichier de sortie $file, auquel Add-Contentajouté à.

9
mklement0

Votre exemple de code semble être OK. Ainsi, le problème fondamental doit être résolu d’une manière ou d’une autre. Éliminons les risques de fautes de frappe dans le script. Tout d’abord, assurez-vous de mettre Set-Strictmode -Version 2.0 au début de votre script. Cela vous aidera à détecter les noms de variables mal orthographiés. Ainsi,

# Test.ps1
set-strictmode -version 2.0 # Comment this line and no error will be reported.
$foo = "bar"
set-content -path ./test.txt -value $fo # Error! Should be "$foo"

PS C:\temp> .\test.ps1
The variable '$fo' cannot be retrieved because it has not been set.
At C:\temp\test.ps1:3 char:40
+ set-content -path ./test.txt -value $fo <<<<
    + CategoryInfo          : InvalidOperation: (fo:Token) [], RuntimeException
    + FullyQualifiedErrorId : VariableIsUndefined

La partie suivante sur les points d’interrogation ressemble à un problème d’Unicode. Quelle est la sortie lorsque vous tapez le fichier avec Powershell,

$file = "\\server\share\file.txt"
cat $file
2
vonPryz