Статья размещена автором Бетке Сергей Сергеевич

PowerShell: обновим сертификаты компьютеров с сохранением ключей

Опять же, очевидная и простая задача – хочется обновить сертификаты компьютеров, естественно – удалённо. И наткнулся на тот факт, что решается эта задача на PowerShell не очевидно совсем даже.

Приведу сценарий:

Invoke-Command `
    -ComputerName 'ca' `
    -ScriptBlock {
        Import-Module `
            Microsoft.PowerShell.Security `
            , NetworkTransition `
            -WarningAction SilentlyContinue `
        ;

        $cert = `
            Get-ChildItem Cert:\LocalMachine\My `
            | ? { 
                ( $_.Subject -eq "CN=$( $env:COMPUTERNAME ).$( $env:USERDNSDOMAIN )" ) `
                -and (
                    $_.EnhancedKeyUsageList `
                    | ? { $_.ObjectId -eq '1.3.6.1.5.5.7.3.1' }
                )
            } `
            | Select-Object -First 1 `
        ;
        Write-Verbose "Сертификат к обновлению: $( $cert.Thumbprint )";
        $keyContainer = `
        certutil.exe -store -v My $( $cert.SerialNumber ) `
        | Select-String -pattern '(?:Контейнер ключа|Key Container)' `
        | % {
            if ( $_ -match '(?:(?:Контейнер ключа|Key Container)\s*=\s*)(?<KeyContainer>[-\w]+)' ) {
                $Matches['KeyContainer'];
            };
        };
        Write-Verbose "Контейнер: $( $keyContainer )";
        $fileName = [System.IO.Path]::GetTempFileName();
        @"
[NewRequest]
RenewalCert = $( $cert.SerialNumber )
KeyContainer = $keyContainer
UseExistingKeySet = True
MachineKeySet = True
"@ `
        | Out-File "$fileName.inf" -Force `
        ;
        Write-Verbose "Сформирован файл запроса: $( $fileName.inf )";
        Certreq -new -q "$fileName.inf" "$fileName.req"
        Write-Verbose "Сформирован файл запроса: $( $fileName.req )";
        $reqId = `
        Certreq -submit -q -config 'CA.CSM.NOV.RU\NCSM Root CA' -AdminForceMachine -f "$fileName.req" "$fileName.cer" `
        | Select-String -pattern '(?:RequestId)' `
        | % {
            if ( $_ -match '(?:RequestId.*?:\s*)(?<RequestId>\d+)' ) {
                $Matches['RequestId'];
            };
        };
        Write-Verbose "Отправлен запрос: $( $reqId )";
        Certreq -retrieve -q -config 'CA.CSM.NOV.RU\NCSM Root CA' -f $reqId "$fileName.cer";
        Write-Verbose "Получен сертификат";
        Certreq -accept -q -machine "$fileName.cer";
        Write-Verbose "Cертификат установлен.";
    } `
;

Пришлось так вот оборачивать certreq утилиту, иного пути для этой задачи не нашёл, однако! Но этот путь работает… Если найдёте более простые пути – буду безмерно благодарен!

Опубликовать комментарий

XHTML: Вы можете использовать следующие HTML теги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Tags Связь с комментариями статьи:
RSS комментарии
Обратная ссылка