Подтвердить что ты не робот

Вывод ( "echo" ) переменной в текстовый файл

Я запускаю PowerShell script для многих серверов и записываю вывод в текстовый файл.

Я хотел бы захватить сервер, на котором работает script. До сих пор я:

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

$computername | Add-Content -Path $file

В этой последней строке добавляются вопросительные знаки в выходном файле. К сожалению.

Как вывести переменную в текстовый файл в PowerShell?

4b9b3361

Ответ 1

После некоторых проб и ошибок я обнаружил, что

$computername = $env:computername

работает, чтобы получить имя компьютера, но отправка $computername в файл с помощью Add-Content не работает.

Я также пробовал $computername.Value.

Вместо этого, если я использую

$computername = get-content env:computername

Я могу отправить его в текстовый файл, используя

$computername | Out-File $file

Ответ 2

Самый простой пример Hello World...

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

Ответ 3

Ваш пример кода выглядит нормально. Таким образом, корневую проблему нужно как-то откопать. Позвольте исключить вероятность опечаток в script. Во-первых, убедитесь, что вы положили Set-Strictmode -Version 2.0 в начало вашего script. Это поможет вам распознать имена переменных с ошибками. Таким образом,

# 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

Следующая часть вопросительных знаков звучит так, как будто у вас проблема с Unicode. Какой вывод при вводе файла с помощью Powershell, например,

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

Ответ 4

Чтобы дополнить полезный ответ bigtv полезный ответ с более краткими альтернативными и справочными данными:

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

Когда выводится в текстовый файл, у вас есть 2 фундаментальных варианта, которые используют различные представления объектов и используют различные кодировки символов по умолчанию

  • Out-File (или >)/Out-File -Append (или >>):

    • Подходит для выходных объектов любого типа, поскольку форматирование вывода по умолчанию PowerShell применяется к выходным объектам.

      • Другими словами: вы получаете тот же результат, что и при печати на консоли.
    • кодировка по умолчанию, которую можно изменить с помощью параметра -Encoding, Unicode, которая UTF-16LE, в котором большинство символов кодируются как 2 байта. Преимуществом кодировки Unicode, такой как UTF-16LE, является то, что это глобальный алфавит, способный кодировать все символы со всех человеческих языков.

      • В PSv5.1 + вы можете изменить кодировку, используемую > и >>, с помощью переменной предпочтения $PSDefaultParameterValues, воспользовавшись преимуществами факт, что > и >> теперь фактически являются алиасами Out-File и Out-File -Append. Чтобы, например, перейти на UTF-8, используйте:
        $PSDefaultParameterValues['Out-File:Encoding']='UTF8'
  • Set-Content/Add-Content:

    • Для записи строк и экземпляров типов, которые, как известно, имеют содержательные представления строк, такие как базовые типы данных .NET(Booleans, integers,...).

      • .psobject.ToString() метод вызывается для каждого выходного объекта, что приводит к бессмысленным представлениям для типов, которые явно не реализуют значимое представление; Примеры [hashtable] - пример:
        @{ one = 1 } | Set-Content t.txt записывает литерал System.Collections.Hashtable в t.txt, что является результатом @{ one = 1 }.ToString().
    • кодировка по умолчанию, которая может быть изменена с помощью параметра -Encoding, Default, которая представляет собой систему "ANSI" кодовая страница, однобайтовая кодировка, специфичная для культуры, для приложений, отличных от Юникода, чаще всего Windows-1252.
      Обратите внимание, что документация в настоящее время неправильно утверждает, что ASCII является кодировкой по умолчанию.

    • Обратите внимание, что Add-Content предназначено для добавления содержимого в существующий файл, и он эквивалентен только Set-Content, если целевой файл еще не существует.
      Кроме того, по умолчанию или указанная кодировка вслепую применяется, независимо от кодирования существующего содержимого файла.

Out-File/>/Set-Content/Add-Content все действуют на культуру чутко, т.е. производят представления, подходящие для текущей культуры (локали), если они доступны (хотя пользовательские данные форматирования могут определять собственное, культурно-инвариантное представление - см. Get-Help about_format.ps1xml). Этот контрастирует с расширением строки PowerShell (строковая интерполяция в строках с двойными кавычками), которая культура-инвариантная - см. этот ответ.

Что касается производительности: поскольку Set-Content не нужно применять форматирование по умолчанию к его вводу, он работает лучше.


Что касается симптома OP с Add-Content:

Так как $env:COMPUTERNAME не может содержать символы, отличные от ASCII, вывод Add-Content, используя кодировку ANSI, не должен приводить к символам ? на выходе, и наиболее вероятным объяснением является то, что ? были частью существующий контент в выходном файле $file, к которому добавлен Add-Content.