Сам CSV подразумевает что это текстовый файл или просто тип записи, где значения разделены запятыми. При этом не всегда значение разделяются запятыми, это могут быть и двоеточия, или точки запятыми и т.д. Сам выгруженный CSV файл выглядит так:
Column1;Column2
Value1;Value2
А в Excel так:
Для того, что бы узнать какие командлеты есть для работы с 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 берет делимитер из региональных настроек:
Или мы можем узнать его с помощью командлета:
(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
...
Подписывайтесь на наш Telegram канал
Теги: #powershell