Generate-CertificateRequest.ps1
<#PSScriptInfo
.VERSION 1.0 .GUID 7f18e5ff-6da6-4e3a-940e-7f6f5524f4c5 .AUTHOR markreno@microsoft.com .COMPANYNAME .COPYRIGHT .TAGS .LICENSEURI .PROJECTURI .ICONURI .EXTERNALMODULEDEPENDENCIES .REQUIREDSCRIPTS .EXTERNALSCRIPTDEPENDENCIES .RELEASENOTES .PRIVATEDATA #> <# .SYNOPSIS Generates a certificate request .inf file as well as a certificate request .req file for a client authentication certificate whose private key is protected by the Windows Hello for Business gesture. .DESCRIPTION Generates a certificate request .inf file as well as a certificate request .req file for a client authentication certificate whose private key is protected by the Windows Hello for Business gesture. The private key is stored in the "Microsoft Passport Key Storage Provider" .PARAMETER INFPath Specifies the file path where the certificate request .inf file will be written e.g. C:\Temp\CertReq.inf .PARAMETER CSRPath Specifies the file path where the certificate request .req file will be written e.g. C:\Temp\CertReq.req .PARAMETER WindowsCA If specified, indicates the certificate request will be to a Windows Enterprise Certificate Authority .PARAMETER CertificateTemplate Only required when WindowsCA is provided. Specifies the certificate template used for the certificate request e.g. SCEPCertificate .INPUTS System.String Path name for Generates a certificate request .inf file as well as a certificate request .req file whose private key is protected by the Windows Hello for Business gesture. Optionally the certificate template name that will be used for the request against a Windows Enterprise Certificate Authority. .OUTPUTS None. Request-Certificate.ps1 does not generate any output. .EXAMPLE C:\PS> .\Generate-CertificateRequest.ps1 -INFPath .\CertReq.inf -CSRPath .\CertReq.req Description ----------- This command generates the certificate request .inf and .req (CSR) files for a client authentication certificate whose private key is protected with the Windows Hello for Business gesture. .EXAMPLE C:\PS> .\Generate-CertificateRequest.ps1 -INFPath .\CertReq.inf -CSRPath .\CertReq.req -WindowsCA -CertificateTemplate SCEPCertificate Description ----------- This command generates the certificate request .inf and .req (CSR) files for a client authentication certificate whose private key is protected with the Windows Hello for Business gesture. Here the WindowsCA switch indicates that a Windows Enterprise Certificate Authority will be used and that the certificate template for the request is called "SCEPCertificate". #> [CmdletBinding(DefaultParametersetName='None')] param( [Parameter(Position=0,Mandatory=$false)] [string]$INFPath = "$env:USERDNSDOMAIN\Desktop\WHfBCertificate.inf", [Parameter(Position=1,Mandatory=$false)] [string]$CSRPath = "$env:USERDNSDOMAIN\Desktop\WHfBCertificate.req", [Parameter(ParameterSetName='Extra',Mandatory=$false)][switch]$WindowsCA, [Parameter(ParameterSetName='Extra',Mandatory=$true)][string]$CertificateTemplate ) # Initialize variables $UPN = $null $keyContainer = $null $Signature = '$Windows NT$' $template = @" [RequestAttributes] CertificateTemplate = $certificateTemplate "@ if ($WindowsCA -eq $false) { $template = $null } # Check whether this version of Windows will allow use of DSRegCmd.exe $OSVersoin = ([environment]::OSVersion.Version).major $OSBuild = ([environment]::OSVersion.Version).Build if (($OSVersoin -ge 10) -and ($OSBuild -ge 1511)){ $dsReg = dsregcmd /status # Retrieve DSRegCmd.exe /status data } else{ # DSRegCmd.exe will not work. Write-Output "The device has a Windows down-level OS version." -ForegroundColor Red '' Write-Output "Recommended action: Run this test on current OS versions e.g. Windows 10, Server 2016 and above." -ForegroundColor Yellow '' '' Write-Output "Script completed successfully." -ForegroundColor Green -BackgroundColor Black '' '' exit } # Retrieve the current user's UPN from $dsReg $exAccName = $dsReg | Select-String "Executing Account Name" $exAccAliases = (($exAccName.ToString() -split ":")[1].Trim() -split ",") foreach ($exAccAlias in $exAccAliases) { if ($exAccAlias -like "*@*") { $UPN = $exAccAlias.Trim() } } if ($UPN -eq $null) { Write-Output "The UPN for the current user could not be retrieved." -ForegroundColor Red '' '' Write-Output "Script completed successfully." -ForegroundColor Green -BackgroundColor Black '' '' exit } # Build the Subject string $subject = '"' + "CN=$UPN" + '"' # Build the SAN string $san = '"' + "UPN=$UPN&" + '"' # Retrieve the current user's WHfB Key Container from certutil.exe $certUtl = certutil -user -csp "Microsoft Passport Key Storage Provider" -key foreach ($certRow in $certUtl) { if ($certRow -like "*$UPN") { $keyContainer = $certRow.Trim() } } if ($keyContainer -eq $null) { Write-Output "Windows Hello for Business is not deployed to this device." -ForegroundColor Red '' '' Write-Output "Script completed successfully." -ForegroundColor Green -BackgroundColor Black '' '' exit } # Build certificate request .inf file $INF = @" [Version] Signature = $Signature [NewRequest] Subject = $subject ProviderName = "Microsoft Passport Key Storage Provider" KeyContainer = $keyContainer UseExistingKeySet = TRUE RequestType = PKCS10 [EnhancedKeyUsageExtension] OID = 1.3.6.1.4.1.311.20.2.2 ; Smart Card Logon OID = 1.3.6.1.5.5.7.3.2 ; Client auth $template [Extensions] 2.5.29.17 = {text} _continue_ = $san "@ Write-Output "Certificate Request is being generated" '' $INF | out-file -filepath $INFPath -force certreq -new $INFPath $CSRPath '' Write-Output "Certificate Request has been generated" '' |