<# .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" }