Powershell экспорт и запись в CSV файл


24 июня 2019


Powershell выгрузка в CSV

Сам CSV подразумевает что это текстовый файл или просто тип записи, где значения разделены запятыми. При этом не всегда значение разделяются запятыми, это могут быть и двоеточия, или точки запятыми и т.д. Сам выгруженный CSV файл выглядит так:

Column1;Column2
Value1;Value2

А в Excel так:

csv

Для того, что бы узнать какие командлеты есть для работы с csv в Powershell нужно выполнить команду:

Get-Command -Noun CSV

Export-CSV тот командлет, который выгрузит все в нужный для нас формат. Для этого получим любые данные с Powershell. Я хочу получить список запущенных процессов:

Get-Process

Для того что бы экспортировать данные мы должны использовать pipeline (конвейер), т.е. | , который к каждому объекту Get-Proccess применит Export-CSV:

Get-Process | Export-Csv "C:\process.csv"

По умолчанию данные экспортируются с разделителем в виде запятой. Сам разделитель называется делиметром и если мы планируем открывать файл в какой-то программе, например экспортируем для Excel, может потребоваться другой делимитер. Например Excel берет делимитер из региональных настроек:

Делимитер Windows

Или мы можем узнать его с помощью командлета:

(Get-Culture).TextInfo.ListSeparator

Изменять системный делимитер я бы не советовал, а вот экспортировать данные в нужном формате можно так:

Get-Process | Export-Csv "process" -Delimiter ";"

Если мы будем запускать такой экспорт на многих удаленных компьютерах, то можно подставить делимитер у каждого свой. Просто объявим переменную:

$delimetr = (Get-Culture).TextInfo.ListSeparator
Get-Process | Export-Csv "process" -Delimiter $delimetr

Или аналогичный командлет для примера:

Get-Process | Export-Csv "process.csv" -UseCulture

Если мы добавим ключ -NoTypeInformation у нас не будет добавляться строчка с информацией типа TYPE:

Get-Process | Export-Csv "process.csv" -UseCulture -NoTypeInformation

Теперь импортируем этот же файл в Powershell. Мы так же можем указать нужный делимитер или использовать ключ -UseCulture:

Import-Csv "C:\process.csv" -UseCulture

Формат вывода csv в powershell, по умолчанию, в виде листа. Для того что бы сделать вывод в формате таблицы добавим pipeline и команду Format-Table (алиас ft ). Пример:

Import-Csv "C:\process.csv" -UseCulture | ft

Теперь рассмотрим вариант, который я буду применять в работе. Я хочу следить за динамикой роста занятого места на диске что бы вовремя его расширить или принять меры что бы освободить место. Для того что бы получить такие данные я использую:

Get-WmiObject -Class Win32_logicaldisk -Filter "DeviceID = 'C:' "

Где:
--Filter "DeviceID = 'C:' "  - фильтруем данные по букве диска. В моем случае это системный диск.

Меня интересует только буква диска, занятое место, и сколько всего места. Добавляем конвейер с выбором нужных колонок:

Get-WmiObject -Class Win32_logicaldisk -Filter "DeviceID = 'C:' " | Select-Object -Property "DeviceID", "FreeSpace", "Size"

Меня не интересуют значения в гигабайтах. Вычисляю эти значения:

Get-WmiObject -Class Win32_logicaldisk -Filter "DeviceID = 'C:' " | Select-Object -Property "DeviceID", @{n="FreeSpace/GB";e={[math]::truncate($_.freespace / 1GB)}}, @{n="Size/GB";e={[math]::truncate($_.size / 1GB)}}

При этом я должен знать дату, когда значения получены:

Get-Date -DisplayHint date -Format dd/MM/yyyy

Объявляем все это в переменные:

$date_today = Get-Date -DisplayHint date -Format dd/MM/yyyy
$disk_data = Get-WmiObject -Class Win32_logicaldisk -Filter "DeviceID = 'C:' "
$data = $disk_data | Select-Object -Property "DeviceID", @{n="FreeSpace/GB";e={[math]::truncate($_.freespace / 1GB)}}, @{n="Size/GB";e={[math]::truncate($_.size / 1GB)}}

Добавляю дату к колонкам информации о дисках:

$data | add-member -membertype NoteProperty -name Date -value $date_today

Проверяю что переменная выводит то, что нужно:

echo $data

И заношу все это в файл:

Export-Csv -InputObject $data -Path C:\diskuse -NoTypeInformation -Delimiter ';' -Append

Где ключ:
-InputObject - мы можем использовать этот ключ или конвейер для передачи объектов
-Append - говорит о том, что мы не перезаписываем файл, а добавляем в него новые значения. При этом если он не был создан, то он создастся.

Среди дополнительных ключей, которые я не использовал, есть:
-Encoding - который дает возможность кодировку для импорта и экспорта. По умолчанию используется UTF8NoBOM.
-Force - перезапишет файл, который был только для чтения. 
-NoClobber - не перезапишет файл, если он уже существует
-Header - добавит заголовок там, где он отсутствует.

У нас осталось еще два похожих командлета. Они, в отличие от предыдущих, не записывают данные в файл, а выводят на экран. Для того что бы преобразовать в формат CSV:

Get-Command -Noun NetIPAddress | ConvertTo-Csv

Или:

ConvertTo-Csv -InputObject $data

 Для того что бы выполнить обратное преобразование:

ConvertTo-Csv -InputObject $data | ConvertFrom-Csv -Delimiter ','

Остальные варианты выполнения этих комманд можно получить через справку:

Get-Help Export-Csv
Get-Help Import-CSV
Get-Help ConvertTo-Csv
Get-Help ConvertFrom-Csv

 

...

Теги: #powershell


Популярные тэги
О блоге
Этот блог представляет собой конспекты выученного материала, преобретенного опыта и лучшие практики в системном администрировании и программировании.