variable batch bat powershell file-io

powershell - batch - Salida("echo") una variable a un archivo de texto



save command result in variable cmd (4)

Estoy ejecutando un script de PowerShell contra muchos servidores, y está registrando la salida en un archivo de texto.

Me gustaría capturar el servidor en el que se está ejecutando actualmente el script. Hasta ahora tengo:

$file = "//server/share/file.txt" $computername = $env:computername $computername | Add-Content -Path $file

Esta última línea agrega signos de interrogación en el archivo de salida. Oops.

¿Cómo puedo exportar una variable a un archivo de texto en PowerShell?


Después de un poco de prueba y error, encontré que

$computername = $env:computername

funciona para obtener un nombre de computadora, pero el envío de $computername a un archivo a través de Add-Content no funciona.

También probé $computername.Value .

En cambio, si uso

$computername = get-content env:computername

Puedo enviarlo a un archivo de texto usando

$computername | Out-File $file


El ejemplo más simple de Hello World ...

$hello = "Hello World" $hello | Out-File c:/debug.txt


Para complementar la respuesta útil de bigtv con una respuesta más concisa e información básica:

# > $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

Al enviar a un archivo de texto , tiene 2 opciones fundamentales que utilizan diferentes representaciones de objetos y emplean diferentes codificaciones de caracteres predeterminadas :

  • Out-File (o > ) / Out-File -Append (o >> ):

    • Adecuado para objetos de salida de cualquier tipo , porque el formato de salida predeterminado de PowerShell se aplica a los objetos de salida.

      • En otras palabras: obtiene el mismo resultado que cuando imprime en la consola .
    • La codificación predeterminada , que se puede cambiar con el parámetro -Encoding , es Unicode , que es UTF-16LE en la que la mayoría de los caracteres están codificados como 2 bytes . La ventaja de una codificación Unicode como UTF-16LE es que es un alfabeto global , capaz de codificar todos los caracteres de todos los idiomas humanos.

      • En PSv5.1 + , puede cambiar la codificación utilizada por > y >> , a través de la variable de preferencia $PSDefaultParameterValues , aprovechando el hecho de que > y >> ahora son efectivamente alias de Out-File y Out-File -Append . Para cambiar a UTF-8, por ejemplo, use:
        $PSDefaultParameterValues[''Out-File:Encoding'']=''UTF8''
  • Set-Content / Add-Content :

    • Para escribir cadenas e instancias de tipos que se sabe que tienen representaciones de cadenas significativas , como los tipos de datos básicos de .NET (Booleanos, enteros, ...).

      • Se llama al método .psobject.ToString() en cada objeto de salida , lo que da como resultado representaciones sin sentido para tipos que no implementan explícitamente una representación significativa; [hashtable] instancias de [hashtable] son un ejemplo:
        @{ one = 1 } | Set-Content t.txt @{ one = 1 } | Set-Content t.txt escribe literal System.Collections.Hashtable to t.txt , que es el resultado de @{ one = 1 }.ToString() .
    • La codificación predeterminada , que se puede cambiar con el parámetro -Encoding , es Default , que es la página de códigos "ANSI" del sistema, una codificación heredada específica de cultivo de un byte para aplicaciones que no son Unicode, más comúnmente Windows-1252 .
      Tenga en cuenta que la documentation actualmente afirma incorrectamente que ASCII es la codificación predeterminada.

    • Tenga en cuenta que el propósito de Add-Content es agregar contenido a un archivo existente , y solo es equivalente a Set-Content si el archivo de destino aún no existe.
      Además, la codificación predeterminada o especificada se aplica ciegamente , independientemente de la codificación del contenido existente del archivo.

Out-File / > / Set-Content / Add-Content actúan todos con sensibilidad cultural, es decir, producen representaciones adecuadas para la cultura actual (configuración regional), si está disponible (aunque los datos de formateo personalizados son libres de definir su propia cultura invariante representación - vea Get-Help about_format.ps1xml ). Esto contrasta con la expansión de cadenas de PowerShell (interpolación de cadenas en cadenas de comillas dobles), que es invariante para la cultura ; vea esta respuesta mía.

En cuanto a rendimiento : dado que Set-Content no tiene que aplicar el formato predeterminado a su entrada, tiene un mejor rendimiento.

En cuanto al síntoma de OP con Add-Content :

Dado que $env:COMPUTERNAME no puede contener caracteres que no sean ASCII, la salida de Add-Content , usando la codificación "ANSI", no debería dar como resultado ? caracteres en la salida, y la explicación más probable es que el ? formaban parte del contenido preexistente en el archivo de salida $file , al que se agregó Add-Content .


Tu código de muestra parece estar bien. Por lo tanto, el problema de raíz debe desenterrarse de alguna manera. Eliminemos la posibilidad de errores tipográficos en el guión. Primero, asegúrese de poner Set-Strictmode -Version 2.0 en el comienzo de su script. Esto lo ayudará a detectar nombres de variables mal escritos. Al igual que,

# 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 siguiente parte sobre signos de interrogación parece que tienes un problema con Unicode. ¿Cuál es la salida cuando escribe el archivo con Powershell como tal,

$file = "//server/share/file.txt" cat $file