Files
Backup/_NDGOV_WindowsTeam/ITD.Infra-Servers-PowerShellUniversal.Production/Infra-Certificate-External.Sectigo/New-ITDCertificateRequestSectigo.ps1
T
Zack Meier 1d304511b8 update
2026-04-15 15:45:50 -05:00

489 lines
14 KiB
PowerShell

<#
.SYNOPSIS
Sectigo Certificate Creator
.DESCRIPTION
Creates a Sectigo Certificate for ITD Organization
.NOTES
Requires:
ITD.Infra-Certificate-Internal.Sectigo
.LINK
https://northdakota.service-now.com/kb_view.do?sysparm_article=KB0018128
#>
[CmdletBinding()]
param (
# [Parameter(Mandatory = $true,
# HelpMessage = "CRC TEXT ONLY")]
# [string]
# $CSR,
# [Parameter(Mandatory = $true,
# HelpMessage = "Csr File")]
# [file]
# $CSRfile,
# [Parameter(Mandatory = $true,
# HelpMessage = "Server Type")]
# [ValidateSet('IIS','IIS_OLD','IBM','LINUX','Apache','Tomcat')]
#[string]
#$ServerType="IIS",
[Parameter(Mandatory = $true,
HelpMessage = "Email address for notifications, comma seperated")]
[string]
$RequesterEmail,
[Parameter(Mandatory = $true,
HelpMessage = "Common Name for cert")]
[string]
$CommonName,
[Parameter(Mandatory = $true,
HelpMessage = "Comma separated.")]
[string]
$SubjectAlternative,
[Parameter(Mandatory = $true,
HelpMessage = "Host for Cert Delivery")]
[string]
$DestinationServer
#[Parameter(Mandatory = $true,
#HelpMessage = "Key Type for cert")]
#[string]
#[ValidateSet("RSA")]
#[Parameter(HelpMessage = "Optional Field, will be appended to standard comments")]
#[string]
#$Comments
#[Parameter(Mandatory = $true,
# HelpMessage = "File Format")]
#[ValidateSet('x509','x509CO','base64','bin','x509IOR','pem','pemco','pemia','x509R')]
#[string]
#$Format="pem"
)
#PSU Reassignment per Zacks standards
$RequestedBy = $UAJob.Identity.Name # user that started the job
$PSUJobId = $UAJob.Id
$KeyType="RSA" #reminder this would need to be set on csr.
#Load Updated Modules
#Find-Module -Repository ITD_PwshGallery -Name ITD.Infra-Certificate-Internal.Sectigo | Update-Module
#exit
#Map script vars to ones that can be Changed for Display Only
$subjAltNames=$SubjectAlternative
$dsvEmail = $RequesterEmail
$myhost=$DestinationServer
#Set ad Default to Hide from End user.
$ServerType="IIS"
$Format="x509CO"
#Write-Verbose -Message $Secret:ndgov_svcitdpsuwin.username -Verbose
#Testing Service Now module
#Get-Command Get-ServiceNowRecord
#Block access while testing
#if ($RequestedBy -ne 'prvfjpeterson@nd.gov' -and $RequestedBy -ne 'prvnblowers@nd.gov' )
#{
# Write-Error "Check with freeman script is currenly disabled"
# exit
#}
if ($Csrfile){
$csr= [Text.Encoding]::UTF8.GetString($CSRfile.Content)
}
Write-Verbose -Message "Validate Email Address" -Verbose
$EmailAddressList = $dsvEmail -split ","
foreach ($e in $EmailAddressList) {
$user = Get-ADUser -Filter "Mail -eq '$e'" -Properties Mail
$group=Get-ADGroup -Filter "Mail -eq '$($e)'" -Properties Mail
if ($user -or $group) {
Write-Verbose -Message "$e Passed testing" -Verbose
}
else {
Write-Error "$e is an invalid email address. Terminating Script"
exit
}
}
Write-Verbose -Message "Validate host" -Verbose
$remotehi=Invoke-Command -ComputerName $myhost -ScriptBlock {"hi"} -Credential $Secret:ndgov_svcitdpsuwin
if ($remotehi -eq "hi") {
"Connection to host Succeded"
} else {
"Connection to host failed"
exit
}
Write-Verbose -Message "Retrieve CI from ServiceNow" -Verbose
New-ITDServiceNowSession -Environment Production -Credential $Secret:snow_vmcred
$IP=(Resolve-DnsName -Name $DestinationServer).IPAddress
$Filter= "ip_address=$ip^operational_status=1"
$Fields=("FQDN","ip_address","Location","model_id","Name","dns_domain","os_domain","Schedule","Environment","sys_class_name","u_nd_application_svc","discovery_source","support_group")
$CI= Get-ITDServiceNowRecord -Table "cmdb_ci_win_server" -Filter $Filter -Fields $Fields -First 1
$ApplicationName=$CI.u_nd_application_svc.display_value
if (!$ApplicationName) {
write-Error "CI NOT FOUND"
exit
}
$customFields = @(
[pscustomobject]@{ name = "ApplicationName"; value = $ApplicationName }
)
#done validation
#
# Do the work
#
#>
## Cert REquest
Write-Verbose -Message "Create CSR" -Verbose
$csrScriptBlock={
param ($commonName)
#######################
# Setting the variables
#######################
$UID = [guid]::NewGuid()
$files = @{}
$files['settings'] = "$($env:TEMP)\$($UID)-settings.inf";
$files['csr'] = "$($env:TEMP)\$($UID)-csr.req"
$request = @{}
$request['SAN'] = @{}
Write-Host "Provide the Subject details required for the Certificate Signing Request" -ForegroundColor Yellow
$request['CN'] = $commonName
$request['O'] = "NDIT"
$request['OU'] = "State Of North Dakota"
$request['L'] = "Bismarck"
$request['S'] = "ND"
$request['C'] = "US"
#########################
# Create the settings.inf
#########################
$settingsInf = "
[Version]
Signature=`"`$Windows NT`$
[NewRequest]
KeyLength = 2048
Exportable = TRUE
MachineKeySet = TRUE
SMIME = FALSE
RequestType = PKCS10
ProviderName = `"Microsoft RSA SChannel Cryptographic Provider`"
ProviderType = 12
HashAlgorithm = sha256
;Variables
Subject = `"CN={{CN}},OU={{OU}},O={{O}},L={{L}},S={{S}},C={{C}}`"
[Extensions]
{{SAN}}
;Certreq info
;http://technet.microsoft.com/en-us/library/dn296456.aspx
;CSR Decoder
;https://certlogik.com/decoder/
;https://ssltools.websecurity.symantec.com/checker/views/csrCheck.jsp
"
$request['SAN_string'] = & {
if ($request['SAN'].Count -gt 0) {
$san = "2.5.29.17 = `"{text}`"
"
Foreach ($sanItem In $request['SAN'].Values) {
$san += "_continue_ = `"dns="+$sanItem+"&`"
"
}
return $san
}
}
$settingsInf = $settingsInf.Replace("{{CN}}",$request['CN']).Replace("{{O}}",$request['O']).Replace("{{OU}}",$request['OU']).Replace("{{L}}",$request['L']).Replace("{{S}}",$request['S']).Replace("{{C}}",$request['C']).Replace("{{SAN}}",$request['SAN_string'])
# Save settings to file in temp
$settingsInf > $files['settings']
# Done, we can start with the CSR
#Clear-Host
#################################
# CSR TIME
#################################
# Display summary
Write-Host "Certificate information
Common name: $($request['CN'])
Organisation: $($request['O'])
Organisational unit: $($request['OU'])
City: $($request['L'])
State: $($request['S'])
Country: $($request['C'])
Subject alternative name(s): $($request['SAN'].Values -join ", ")
Signature algorithm: SHA256
Key algorithm: RSA
Key size: 2048
" -ForegroundColor Yellow
certreq -new $files['settings'] $files['csr'] > $null
# Output the CSR
$CSR = Get-Content $files['csr']
$CSR|Out-String
} #end of script block
#myhost is used as cn
$csr=Invoke-Command -ComputerName $myhost -Credential $Secret:ndgov_svcitdpsuwin -ScriptBlock $csrScriptBlock -ArgumentList $commonName
#Write-Verbose -Message "Validate CSR" -Verbose
#$TestResults=Test-SectigoCertificateRequest -csr $csr
#If ($TestResults.Valid -eq $True) {
# Write-Verbose -Message "CSR Passed Testing" -Verbose
#}
#else {
# Write-Error "You don't have a valid csr. Terminating Script"
# "CSR Content " + $csr
# exit
#}
# End of Creating csr
##
$Comments="Enrolled by PSUniversal, Job " + $UAJob.Id + ", User " + $UAJob.Identity.Name + "," + $Comments
$Comments
if ($ApplicationName)
{
$customFields = @(
@{
name = "ApplicationName"
value = $ApplicationName
}
)
}
Write-Verbose -Message "Setting up params for Enroll-SectigoCertificateRequest" -Verbose
$splat = @{
Csr=$csr
dcvEmail=$dsvEmail
Comment=$Comments
KeyType=$KeyType
subjAltNames=$subjAltNames
}
$b1 = @{
customFields = $customFields
}
if ($customFields) {
$splat = $splat+ $b1
}
#$splat2=@{
# subjAltName=$subjAltName
#}
#if ( $subjAltName) {
# $Splat = $splat + $splat2
#}
$cred=$Secret:SectigoClientSecret
$env:Sectigoclientid = $cred.UserName
$env:SectigoclientSecret = $cred.GetNetworkCredential().Password
#get-command -Module ITD.Infra-Certificate-Internal.Sectigo
#remove-module ITD.Infra-Certificate-Internal.Sectigo
Write-Verbose -Message "Enroll-SectigoCertificateRequest" -Verbose
Get-SectigoApiToken
$certRequest = Enroll-SectigoCertificateRequest @Splat
#seems to be issue with this requiring addtional wait time.
Write-Verbose -Message "Waiting for Cert Status" -Verbose
while ($certstatus -ne "Issued") {
$certstatus=(Get-SectigoCertificate -OrderId $certRequest.sslid).status
Sleep 1
$run= $run + 1
if ($run -gt 60) {
Write-Error "Failed to get issue status after 1 minute..exiting"
exit
}
}
$tp=(Get-SectigoCertificate -OrderId $certRequest.sslid).sha1Hash
"tp: $tp"
Write-Verbose -Message "Downloading interm Certificate" -Verbose
$IntermCertRootPath="c:\psautocerts_interm\"
mkdir $IntermCertRootPath 2>$null
$IntermCertPath = (Download-SectigoCertificate -Orderid $certRequest.sslid -Format x509IOR -CertRootPath $IntermCertRootPath).FullName
ls $IntermCertPath |select FullName, LastWriteTime, Length
Write-Verbose -Message "Downloading Certificate" -Verbose
$CertRootPath="c:\psautocerts\"
mkdir $CertRootPath 2>$null
$CertPath = (Download-SectigoCertificate -Orderid $certRequest.sslid -Format $Format -CertRootPath $CertRootPath).FullName
ls $CertPath |select FullName, LastWriteTime, Length
# Define source and destination paths
$remoteCertPath = "C:\Temp\CertificateX.cer" # A temporary location on the remote machine
$IntermremoteCertPath = "C:\Temp\Interm_CertificateX.cer"
# Copy the interm certificate file to the remote machine
Copy-Item -Path $IntermCertPath -Destination $IntermremoteCertPath -ToSession (New-PSSession -ComputerName $myhost -Credential $Secret:ndgov_svcitdpsuwin)
# Copy the certificate file to the remote machine
Copy-Item -Path $CertPath -Destination $remoteCertPath -ToSession (New-PSSession -ComputerName $myhost -Credential $Secret:ndgov_svcitdpsuwin)
# Define parameters for importing the certificate
#$certPassword = "YourCertPassword" | ConvertTo-SecureString -AsPlainText -Force # If it's a PFX with a password
$IntermcertStoreLocation = "Cert:\LocalMachine\Root"
$Intermcertimport=Invoke-Command -ComputerName $myhost -Credential $Secret:ndgov_svcitdpsuwin -ScriptBlock {
param($IntermremoteCertPath, $IntermcertStoreLocation )
"Import-Certificate -FilePath -CertStoreLocation $IntermcertStoreLocation"
Import-Certificate -FilePath $IntermremoteCertPath -CertStoreLocation $IntermcertStoreLocation
if (Test-Path -Path $IntermremoteCertPath -PathType Leaf) {
Remove-Item -Path $IntermremoteCertPath -Force -Confirm:$false 2>$null
}
# Import the certificate
} -ArgumentList $IntermremoteCertPath, $IntermcertStoreLocation
if ($Intermcertimport.Thumbprint ) {
Write-Verbose -verbose "Successful Import."
$IntermThumbprint=$Intermcertimport.Thumbprint
Write-Verbose "Thumbprint: $IntermThumbprint"
if (Test-Path -Path $CertPath -PathType Leaf) {
Remove-Item -Path $IntermCertPath -Force -Confirm:$false
Write-Host "File '$IntermCertPath' deleted successfully."
} else {
Write-Host "Path '$IntermCertPath' does not exist or is not a file."
}
}
##################
$certStoreLocation = "Cert:\LocalMachine\My"
$certimport=Invoke-Command -ComputerName $myhost -Credential $Secret:ndgov_svcitdpsuwin -ScriptBlock {
param($remoteCertPath, $certStoreLocation,$CommonName )
"Import-Certificate -FilePath $remoteCertPath -CertStoreLocation $certStoreLocation"
# Import the certificate
$cert=Import-Certificate -FilePath $remoteCertPath -CertStoreLocation $certStoreLocation
$mydate=Get-Date -Format 'yyyy-MM-dd'|out-string
$FriendlyName = $CommonName + "-" +$myDate
$cert.FriendlyName = $FriendlyName
if (Test-Path -Path $remoteCertPath -PathType Leaf) {
Remove-Item -Path $remoteCertPath -Force -Confirm:$false 2>$null
}
$cert
} -ArgumentList $remoteCertPath, $certStoreLocation,$CommonName
if ($certimport.Thumbprint ) {
Write-Verbose -verbose "Successful Import."
$Thumbprint=$certimport.Thumbprint
Write-Verbose "Thumbprint: $Thumbprint" -Verbose
if (Test-Path -Path $CertPath -PathType Leaf) {
Remove-Item -Path $CertPath -Force -Confirm:$false
Write-Host "File '$CertPath' deleted successfully."
} else {
Write-Host "Path '$CertPath' does not exist or is not a file."
}
}
#
# Request Work
#
# Validate the user
$StartDateTime = (Get-Date)
$EndDateTime = $StartDateTime.AddMinutes(1)
$RequestedBy=$UAJob.Identity.Name
#$ServiceNowEnvironment = "TEST"
#TemplateName = 'NDIT-SPS-Ansible Automation Platform'
if ($certimport.Thumbprint ) {
Write-Verbose -Message "Create CHG request for the work" -Verbose
$ServiceNowEnvironment = "Production" #'Production', 'Test', 'Development'
New-ITDServiceNowSession -Environment $ServiceNowEnvironment -Credential $Secret:snow_vmcred
$NewITDServiceNowChangeRequestParams = @{
TemplateName = 'NDIT-SPS-PSU Cert Automation Platform'
RequestedByUsername = $RequestedBy.split('@')[0] -replace 'prv';
Category = 'Systems Platforms - Systems';
Subcategory = 'Windows';
Impact = 3;
ShortDescription = "New Certificate Created - PSU Job Id $PSUJobId";
Description = "New Certificate Created - PSU Job Id $PSUJobId";
Justification = "Security Standards require an updated certificate";
Implementation = "PSUniversal execution";
RiskImpactAnalysis = "Low";
BackoutPlan = "Revoke Cert"
TestPlan = "n/a"
WhoIsImpacted = "Windows System Administrators";
StartTime = $StartDateTime
EndTime = $StartDateTime.AddMinutes(1);
AssignmentGroup = 'NDIT-Computer Systems Windows';
ChangeManagerUsername = 'khellman';
ChangeCoordinatorUsername = 'gpgolberg';
AssignedToUsername = $RequestedBy.split('@')[0] -replace 'prv';
}
$CHG = New-ITDServiceNowChangeRequest @NewITDServiceNowChangeRequestParams -Verbose
$CHGNum = $CHG.Number.value
Write-Verbose -Message ("Completing Snow " + $CHG.Number.value) -Verbose
$CompleteITDServiceNowChangeRequestParams = @{
Number = $CHG.Number.value
CloseCode = "Successful"
CloseNotes = ("New Certificate" + $obj.ADDomain + "\" + $obj.SamAccountName + " created.")
}
Complete-ITDServiceNowChangeRequest @CompleteITDServiceNowChangeRequestParams -Verbose
Write-Verbose -Message "Status Success" -Verbose
$SQLStatus = "Succcess"
}
Else {
Write-Verbose -Message "Status Failure" -Verbose
$SQLStatus = "Failure"
}