rds-update-certificate/Scripts/rds-certreq.ps1 (155 lines of code) (raw):

<# Copyright 2017 Microsoft Corporation Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. .SYNOPSIS powershell script to create sha256 self-signed single, multiple, or wildcard certificate for testing. .DESCRIPTION powershell script to create a self-signed certificate for a Remote Desktop Services Deployment. script uses builtin exe certreq.exe. upon successful completion, a certificate will be stored in the localmachine\my certificate store upon successful completion, a pfx file will be generated in the working directory that can be imported into RDS to enable script execution, you may need to Set-ExecutionPolicy Bypass -Force this script is a modification of script from here: <https://blog.kloud.com.au/2013/07/30/ssl-san-certificate-request-and-import-from-powershell/> https://github.com/Azure/azure-quickstart-templates/tree/master/rds-update-certificate/scripts/rds-certreq.ps1 .NOTES file name : rds-certreq.ps1 version : 170614 original .EXAMPLE .\rds-certreq.ps1 -subject gateway.contoso.com -password N0tMyP@ssw0rd this will generate a self-signed single domain certificate that will expire in 3 months .EXAMPLE .\rds-certreq.ps1 -subject *.contoso.com -password N0tMyP@ssw0rd this will generate a self-signed wildcard certificate that will expire in 3 months .EXAMPLE .\rds-certreq.ps1 -subject gateway.contoso.com -sans @("gateway.contoso.com","broker.contoso.com") -password N0tMyP@ssw0rd -expirationDate 6/14/2018 this will generate a self-signed san certificate that will expire in 1 year .PARAMETER subject required parameter that is the subject of the certificate. this should be the same as the external name that will be used to connect to RDWeb #> param( [Parameter(Mandatory = $true)] [string]$subject = "", [array]$sans = @(), [dateTime]$expirationDate = (get-date).AddMonths(3).ToShortDateString(), [Parameter(Mandatory = $true)] [string]$password )              function New-CertificateRequest () { param ( [Parameter(Mandatory = $true, HelpMessage = "Please enter the subject beginning with CN=")] [ValidatePattern("CN=")] [string]$subject, [Parameter(Mandatory = $false, HelpMessage = "Please enter the SAN domains as a comma separated list")] [array]$SANs, [Parameter(Mandatory = $false, HelpMessage = "Please enter the Online Certificate Authority")] [string]$OnlineCA, [Parameter(Mandatory = $false, HelpMessage = "Please enter the Online Certificate Authority")] [string]$CATemplate = "WebServer", [Parameter(Mandatory = $false, HelpMessage = "Please enter the expiration Date")] [dateTime]$expirationDate, [Parameter(Mandatory = $false, HelpMessage = "Please enter password for PFX certificate")] [string]$password )          ### Preparation $subjectDomain = $subject.split(',')[0].split('=')[1] if ($subjectDomain -match "\*.") { $subjectDomain = $subjectDomain -replace "\*", "star" } $CertificateINI = "$subjectDomain.ini" $CertificateREQ = "$subjectDomain.req" $CertificateRSP = "$subjectDomain.rsp" $CertificateCER = "$subjectDomain.cer" $CertificatePFX = "$subjectDomain.pfx"          ### INI file generation new-item -type file $CertificateINI -force add-content $CertificateINI '[Version]' add-content $CertificateINI 'Signature="$Windows NT$"' add-content $CertificateINI '' add-content $CertificateINI '[NewRequest]' add-content $CertificateINI ('Subject="' + $subject + '"') add-content $CertificateINI 'Exportable=TRUE' add-content $CertificateINI 'KeyLength=2048' add-content $CertificateINI 'KeySpec=1' add-content $CertificateINI 'KeyUsage=0x30' add-content $CertificateINI 'MachineKeySet=True' add-content $CertificateINI 'ProviderName="Microsoft RSA SChannel Cryptographic Provider"' add-content $CertificateINI 'ProviderType=12' add-content $CertificateINI 'SMIME=FALSE' ### Date Ranges add-content $CertificateINI ('NotBefore="' + (get-date).ToShortDateString() + '"') add-content $CertificateINI ('NotAfter="' + $expirationDate.ToShortDateString() + '"')          add-content $CertificateINI 'RequestType=Cert' add-content $CertificateINI 'HashAlgorithm=sha256' add-content $CertificateINI '[EnhancedKeyUsageExtension]' add-content $CertificateINI 'OID=1.3.6.1.5.5.7.3.1 ; this is for Server Authentication / Token Signing' if ($SANs) { add-content $CertificateINI '[Extensions]' add-content $CertificateINI '2.5.29.17 = "{text}"'          foreach ($SAN in $SANs) { add-content $CertificateINI ('_continue_ = "dns=' + $SAN + '&"') } }          ### Certificate request generation if (test-path $CertificateREQ) { remove-item $CertificateREQ } $ret = certreq -new $CertificateINI $CertificateREQ write-host ($ret | out-string)          ### Online certificate request and import if ($OnlineCA) { if (test-path $CertificateCER) { remove-item $CertificateCER } if (test-path $CertificateRSP) { remove-item $CertificateRSP } certreq -submit -attrib "CertificateTemplate:$CATemplate" -config $OnlineCA $CertificateREQ $CertificateCER certreq -accept $CertificateCER } # export pfx to file if ($ret) { $thumb = ([regex]::Match($ret, "Thumbprint: (.+?) ")).Captures[0].Groups[1].value if ($thumb) { $securePassword = ConvertTo-SecureString -String $password -Force -AsPlainText Export-PfxCertificate -FilePath $CertificatePFX -Password $securePassword -ChainOption BuildChain -Cert "cert:\localmachine\my\$($thumb)" -Force } else { Write-Warning "unable to enumerate thumbprint" } } else { Write-Warning "failure in certreq.exe" } }   New-CertificateRequest -subject "CN=$($subject)" -SANs $sans -expirationDate $expirationDate -password $password write-host "finished" -ForegroundColor Cyan