Powershell - информация об экспортном сертификате - PullRequest
1 голос
/ 13 января 2020

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

gci C:\test1 -Recurse -Filter *.cer | 
%{
    $cert = New-Object Security.Cryptography.X509Certificates.X509Certificate2 $_.FullName
    if ($cert.NotBefore -lt (Get-Date)) 
   {
        Write-Output $cert.FriendlyName
        Write-Output $cert.SubjectName
        Write-Output $cert.notbefore
        Write-Output $cert.NotAfter
    } 
}|export-csv c:\test2\test.csv -Append

Если я удаляю последний раздел, то я получаю информацию, отображаемую на screen, но когда он экспортируется в CSV, я просто получаю # type.system.string, за которым следует столбец '0'. У кого-нибудь есть здесь идеи? Я знаю, что приведенное выше даст только файлы .cer, и мне нужно будет найти также файлы .der, но я попытаюсь пересечь этот мост, когда приду к нему: D

1 Ответ

0 голосов
/ 14 января 2020

Вместо Write-Output создайте PSCustomObject и затем экспортируйте в CSV. Обратите внимание на изменение вашего if блока ниже:

gci C:\test1 -Recurse -Filter *.cer | 
%{
    $cert = New-Object Security.Cryptography.X509Certificates.X509Certificate2 $_.FullName
    if ($cert.NotBefore -lt (Get-Date)) 
    {
        [PSCustomObject]@{
          FriendlyName = $cert.FriendlyName
          SubjectName = $cert.SubjectName
          NotBefore = $cert.notbefore
          NotAfter = $cert.NotAfter
        }
    } 
}|export-csv c:\test2\test.csv -NoTypeInformation -Append -Encoding UTF8

Это работает, потому что PSCustomObject имеет только те свойства NoteProperty, которые вы добавили в него. Если бы вы попробовали это с простым HashTable, ваш CSV был бы полон свойств, которые существуют на HashTable объекте, и это не то, что вам нужно.

Теперь у вас есть общий набор имен столбцов и каждый возвращенный PSCustomObject через конвейер является строкой в ​​вашем CSV. Я добавил -NoTypeInformation к Export-Csv, чтобы он не добавлял комментарий поверх типа PowerShell, из которого он был преобразован. В большинстве случаев вам это не нужно, и это может запутать некоторые парсеры. Указание кодировки UTF8 немного помогает совместимости с некоторыми сторонними парсерами (дополнительную информацию см. В конце этого ответа), но не является строго обязательным.

Не хотите заголовки? Нет проблем!

Если вам не нужны заголовки, это немного сложнее, но все же довольно просто. Export-Csv не поддерживает экспорт без заголовков. Сначала необходимо преобразовать объект в формат CSV, пропустить первую строку, а затем самостоятельно записать оставшиеся выходные данные в файл. Таким образом, в этом случае вы должны сделать следующее после Where-Object блока:

} | ConvertTo-Csv -NoTypeInformation | Select -Skip 1 | Set-Content -Encoding UTF8 c:\test2\test.csv

До PowerShell 6 запись файлов из PowerShell с помощью оператора перенаправления или Set-Content с любой кодировкой включите метку порядка байтов (BOM) в начале файла. Я считаю, что Export-Csv также делает это. Вы не увидите этого в большинстве редакторов, и обычно это не вызывает проблем с программным обеспечением Windows, но есть некоторые анализаторы CSV, которые могут быть сбиты с толку спецификацией.

Использование кодировки UTF8 несколько помогает, поскольку UTF8 имеет более широкую поддержку, чем UTF16 по умолчанию в PowerShell, но если вы используете PowerShell 5.1 или более раннюю версию, рассмотрите возможность записи файла с помощью System.IO.File.WriteAllText, чтобы указать кодировку без спецификации. Где $csvString - строка в формате CSV, которую вы хотите записать в файл:

$utf8NoBOM = New-Object System.Text.UTF8Encoding( $False )
[System.IO.File]::WriteAllText( $csvString, "C:\path\to\file.csv", $utf8NoBOM )
...