Delete, Install, Bind SSL Cert commands

 .PS1 

----------------------------------------------------------------------------------------------------------------------------

<#

Requests a certificate from a Windows CA


.PARAMETER CN

Specifies the common name for the subject of the certificate(s).

Mostly its the FQDN of a website or service.

e.g. test.jofe.ch


.PARAMETER SAN

Specifies a comma separated list of subject alternate names (FQDNs) for the certificate

The syntax is {tag}={value}.

Valid tags are: email, upn, dns, guid, url, ipaddress, oid

e.g. dns=test.jofe.ch,email=jfeller@jofe.ch


.PARAMETER DNSFile

Specifies a comma separated file that contains a list of subject alternate names (FQDNs) for the certificate

The syntax is {tag}={value}.

Valid tags are: FQDN of server for the SAN.

e.g. dns=test.jofe.ch,email=jfeller@jofe.ch


.PARAMETER Country

Specifies two letter for the optional country value in the subject of the certificate(s).

e.g. CH


.PARAMETER State

Specifies the optional state value in the subject of the certificate(s).

e.g. Berne


.PARAMETER City

Specifies the optional city value in the subject of the certificate(s).

e.g. Berne


.PARAMETER Organisation

Specifies the optional organisation value in the subject of the certificate(s).

e.g. jofe.ch


.PARAMETER Department

Specifies the optional department value in the subject of the certificate(s).

e.g. IT


.PARAMETER Email

Specifies the email address to be associated with the certificate.

e.g. ONM_QNXTandReports@MolinaHealthCare.Com


.PARAMETER Install

Will remotely install the certs into the Personal and Trusted Root Authority Store on the machine specified or the machine in the in the DNSFile

e.g. F:\


.PARAMETER Bind

Will Remove Port 80 and bind the cert specified by the thumbnail with port 443 specified or the machine in the DNSFile

e.g. {Cert to bind Thumbprint)


.PARAMETER DeleteCert

Will remotely delete the speific cert from the personal and trusted root authoririty store on machine specified or the machine in the in the DNSFile

e.g. ABC.ab.com


.PARAMETER CodeSigning

Will remotely delete the specific cert from the personal and trusted root authoririty store on machine specified or the machine in the in the DNSFile


.PARAMETER SetPerm

Will remotely execute the Cert_Permissions.ps1 to set the permissions for cert binding, if necessary. 


.PARAMETER ReqCer

Will install the .cer file in the trusted root authority, if necessary.

e.g. true or false or not supplied. 



.INPUTS

System.String

Common name for the subject, SAN , Country, State etc. of the certificate(s) as a string


.OUTPUTS

None. Request-Certificate.ps1 does not generate any output.


.EXAMPLE

C:\PS> .\Cert-RequestOrInstall.ps1


Description

-----------

This command requests a certificate form the enterprise CA in the local Active Directory.

The user will be asked for the value for the CN of the certificate.


.EXAMPLE

C:\PS> .\Cert-RequestOrInstall.ps1 -CAName "testsrv.test.ch\Test CA"


Description

-----------

This command requests a certificate form the CA testsrv.test.ch\Test CA.

The user will be asked for the value for the CN of the certificate.



.EXAMPLE

C:\PS> .\Cert-RequestOrInstall.ps1 -CN "webserver.test.ch" -SAN "DNS=webserver.test.ch,DNS=srvweb.test.local"


Description

-----------

This command requests a certificate with a CN of webserver.test.ch and subject alternative names (SANs)

The SANs of the certificate are the DNS names webserver.test.ch and srvweb.test.local.


.NOTES



File Name  : Cert-RequestOrInstall.ps1

Requires   : PowerShell V2 or higher


#>


[CmdletBinding()]

Param(

    [Parameter(Mandatory = $False, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)]

    [string]$CN,

    [Parameter(Mandatory = $False, ValueFromPipelineByPropertyName = $True)]

    [string[]]$SAN,

    [Parameter(Mandatory = $False, ValueFromPipelineByPropertyName = $True)]

    [string]$CAName,

    [Parameter(Mandatory = $False, ValueFromPipelineByPropertyName = $True)]

    [String]$TemplateName = "(No template) CNG key",

    [Parameter(Mandatory = $False, ValueFromPipelineByPropertyName = $True)]

    [string]$Country,

    [Parameter(Mandatory = $False, ValueFromPipelineByPropertyName = $True)]

    [string]$State,

    [Parameter(Mandatory = $False, ValueFromPipelineByPropertyName = $True)]

    [string]$City,

    [Parameter(Mandatory = $False, ValueFromPipelineByPropertyName = $True)]

    [string]$Organization,

    [Parameter(Mandatory = $False, ValueFromPipelineByPropertyName = $True)]

    [string]$Department,

    [Parameter(Mandatory = $False, ValueFromPipelineByPropertyName = $True)]

    [string]$Email,

    [Parameter(Mandatory = $False, ValueFromPipelineByPropertyName = $True)]

    [string]$DNSFile,

    [Parameter(Mandatory = $False, ValueFromPipelineByPropertyName = $True)]

    [string]$Install,

    [Parameter(Mandatory = $False, ValueFromPipelineByPropertyName = $True)]

    [string]$Bind,

    [Parameter(Mandatory = $False, ValueFromPipelineByPropertyName = $True)]

    [string]$DeleteCert,

    [Parameter(Mandatory = $False, ValueFromPipelineByPropertyName = $True)]

    [string]$CodeSign,

    [Parameter(Mandatory = $False, ValueFromPipelineByPropertyName = $True)]

    [string]$PFXFile,

    [Parameter(Mandatory = $False, ValueFromPipelineByPropertyName = $True)]

    [string]$PFXPassword,

    [Parameter(Mandatory = $False, ValueFromPipelineByPropertyName = $True)]

    [string]$SetPerm,

    [Parameter(Mandatory = $False, ValueFromPipelineByPropertyName = $True)]

    [string]$PowerShellLoc,

    [Parameter(Mandatory = $False, ValueFromPipelineByPropertyName = $True)]

    [string]$PermPS,

    [Parameter(Mandatory = $False, ValueFromPipelineByPropertyName = $True)]

    [string]$ReqCer

    

)


BEGIN {


    function SAN_Variable() {

        param(

            [String]$CSV_LOC,

            [bool]$bolInstall

        )


        $csv = Import-Csv $CSV_LOC

        $DNS = ''

        $FirstTime=$true


        $csv.DNS | ForEach-Object {


           if ($FirstTime)

           {

              if ($bolInstall -eq $false) {

                 $DNS += "DNS=$_" #`r`n"

                 

              }

              else

              {

                 $DNS += "$_"

              }


              $FirstTime = $false

           }

           Else

           {

              if ($bolInstall -eq $false) {

                 $DNS += ",DNS=$_" #`r`n"

              }

              else

              {

                 $DNS += ",$_"

              }

              

              #$DNS += ",DNS=$_" #`r`n"

           }

        }


        Write-Verbose "Return DNS string"

        return $DNS

    

  }


      function Install_Cert() {

      param(

            [String]$an,

            [String]$CertLoc

            

      )

        try {


              Write-Host "Installing cert on SAN: $an`r`n" -ForegroundColor Green

              Write-Host "Copy pfx file to: $an`r`n" -ForegroundColor Green


              $PFXDir = [IO.Path]::GetDirectoryName($PFXFile)

              $PFXFileName = [IO.Path]::GetFileNameWithoutExtension($PFXFile)

              $Session = New-PSSession -ComputerName $an 


              $File = [System.IO.File]::ReadAllBytes("$PFXDir\$PFXFileName.pfx")

              Invoke-Command -Session $session -ArgumentList $file -ScriptBlock{[System.IO.File]::WriteAllBytes("$CertLoc\$using:PFXFileName.pfx", $args)}

              Write-Host "PFX file copied to: $an`r`n" -ForegroundColor Green


              Write-Host "Installing cert on SAN: $an in CA `r`n)" -ForegroundColor Green

              Invoke-Command -ComputerName "$an" -ScriptBlock  { certutil.exe -f –p "$using:PFXPassword" –importpfx "$CertLoc\$using:PFXFileName.pfx" }


              if ($ReqCer -eq $true) 

              {

                 $File = [System.IO.File]::ReadAllBytes("$PFXDir\$PFXFileName.cer")

                 Invoke-Command -Session $session -ArgumentList $file -ScriptBlock{[System.IO.File]::WriteAllBytes("$CertLoc\$using:PFXFileName.cer", $args)}

           

                  Write-Host "CER file copied to: $an`r`n" -ForegroundColor Green

              

                  Write-Host "Installing cert on SAN: $an in My `r`n)" -ForegroundColor Green

                  $PFXCer = "$PFXFileName.cer"

                  Invoke-Command -ComputerName "$an" -E -ScriptBlock  { certutil.exe -addstore -enterprise -f -v root "$CertLoc\$using:PFXCer" }

              }


              #Remove the files copied:

              Invoke-Command -Computer "$an" -ScriptBlock {Remove-Item -Path $args[0] } -ArgumentList "$CertLoc\$PFXFileName.*"

              

              #Exit-PSSession


        }

        catch {

             #show error message (non terminating error so that the rest of the pipeline input get processed)

             Write-Error $_

        }

        finally {

        }


        Write-Verbose "Completed Install"

        #Exit-PSSession

        return

    

     }


     function Bind_Cert() {

     param(

            [String]$an,

            [String]$ThumbPrint

            

     )

        $strBindExit = ''

        try {


              Write-Host "Binding cert on SAN: $an`r`n" -ForegroundColor Green


              $Session = New-PSSession -ComputerName $an 


              Invoke-Command -Session $Session -ScriptBlock  { 


                   $lastexitcode=999


                   ### Enable if required

                   Import-Module ServerManager

                   ##Add-WindowsFeature Web-Scripting-Tools

                   Import-Module WebAdministration


                   ##the value must be updated if different certificate is desired

                   ###READ ME - This is the DH endpoints on App Gateway or F5. The values need to be changed for DEV,QA, UAT, PROD

                   #$certThumbprint ="‎‎4ba8728fa13395f49a93a878064bd8f630def748"

 

                   #Set the site name

                   $siteName = "Default Web Site"


                   $bhasChanges = $false;


                   ##set ssl binding on default website

                   $bsslExists = $false;

                   #Remove-WebBinding -Name "$($siteName)" -Port 80 -Protocol "http" 

                   #Remove-WebBinding -Name "$($siteName)" -Port 443 -Protocol "https" 

                   $currMachineName = $env:computername


                   $websiteBindings = (Get-Website -Name "$($siteName)").bindings.Collection

                   

                   foreach ($websiteBinding in $websiteBindings)

                   {


                      if($websiteBinding.protocol -eq "http")

                      {

                         

                         Remove-WebBinding -Name "$($siteName)" -Port 80 -Protocol "http"  

                         #$bsslExists= $true

                         $lastexitcode = 30


                      }

                      

                      

                      if($websiteBinding.protocol -match("https"))

                      {

                         

                         Remove-WebBinding -Name "$($siteName)" -Port 443 -Protocol "https"  

                         #$bsslExists= $true

                         $lastexitcode = 40


                      }

   

                   }    

        

                   if(!$bsslExists)

                   {

                     ##QNXT_STG56R5.molina.mhc

                     New-WebBinding -Name "$($siteName)" -Protocol https -Port 443 -SslFlags 0

    

                     $certificate = Get-ChildItem Cert:\LocalMachine\My | Where-Object {$_.Thumbprint -eq "$using:ThumbPrint"}

    

                     (Get-WebBinding -Name "$($siteName)" -Port 443 -Protocol "https" -HostHeader *).AddSslCertificate($certificate.Thumbprint, "my")

    

                     Set-WebConfiguration -Location "$($siteName)" -Filter 'system.webserver/security/access' -Value 'Ssl,None' 

 

                     $lastexitcode = 0  


                     if($currMachineName -contains("DH"))

                     {     

                        #bind certificate for HTTPS operation on QNXT Messaging Hub

                        Add-NetIPHttpsCertBinding -IpPort "0.0.0.0:15500" -CertificateHash $using:ThumbPrint -CertificateStoreName "My" -ApplicationId "{bfad2bb1-858a-4bfb-865b-7cb90b7aa0ab" -NullEncryption $false

                        Stop-Service -Name "QNXT Messaging Hub" 

                        Start-Service -Name "QNXT Messaging Hub"

                        $lastexitcode = 20

                     }     

        

                   }


                   $lastexitcode


              }


              $strBindExit = invoke-command -ScriptBlock { $lastexitcode} -Session $Session


              if ($strBindExit -eq 0 -or $strBindExit -eq 20 -or $strBindExit -eq 30 -or $strBindExit -eq 40) {

                  Write-Host "Bind Successful On: $an`r`n" -ForegroundColor Green

              }

              else

              {

                  Write-Host "Bind UnSuccessful On: $an`r`n" -ForegroundColor Red

              }


        }

        catch {

             #show error message (non terminating error so that the rest of the pipeline input get processed)

             Write-Error $_

        }

        finally {

           if (Get-PSSession) {        

               Remove-PSSession -ComputerName $an

           }

        }


        Write-Verbose "Bind Completed"

        #Exit-PSSession

        return

      }

     


      function SetPerm() {

      param(

            [String]$an,

            [String]$PowerShellLoc,

            [String]$CertName

            

      )

        try {


              Write-Host "Installing Cert_Permissions PowerShell on SAN: $an`r`n" -ForegroundColor Green


              $Cert_LocDir = [IO.Path]::GetDirectoryName($PermPS)

              $Session = New-PSSession -ComputerName $an 


              $UNC_Loc = $PowerShellLoc.Substring(0,1) + "$" 

              Copy-Item -Path "$Cert_LocDir\Cert_Permissions.ps1" -Destination "\\$an\$UNC_Loc\Cert_Permissions.ps1"

              Write-Host "Cert_Permissions Powershell to: $an`r`n" -ForegroundColor Green


              Write-Host "Execution Cert_Permissions file copied to: $an`r`n" -ForegroundColor Green


              Invoke-Command -Session $session -ScriptBlock  { & $using:PowerShellLoc\Cert_Permissions.ps1 -subject "$using:CertName"  }

              

              #Remove the files copied:

              Invoke-Command -Computer "$an" -ScriptBlock {Remove-Item -Path $args[0] } -ArgumentList "$PowerShellLoc\Cert_Permissions.ps1"

              

        }

        catch {

             #show error message (non terminating error so that the rest of the pipeline input get processed)

             Write-Error $_

        }

        finally {

        }


        Write-Verbose "Completed SetPerm on the cert."

        return

    

     }


     function Delete_Cert() {

      param(

            [String]$an,

            [String]$CertName

            

      )

        try {


              Write-Host "Delete $CertName cert on SAN: $an`r`n" -ForegroundColor Green


              #certutil.exe -delstore My $CertName

              Invoke-Command -ComputerName "$an" -ScriptBlock  { certutil.exe -delstore My $using:CertName }

              

              Write-Host "Delete $CertName cert on SAN: $an in My `r`n)" -ForegroundColor Green

              #certutil.exe -delstore -enterprise -v root $CertName

              Invoke-Command -ComputerName "$an" -E -ScriptBlock  { certutil.exe -delstore -enterprise -v root $using:CertName }



        }

        catch {

             #show error message (non terminating error so that the rest of the pipeline input get processed)

             Write-Error $_

        }

        finally {

        }


        Write-Verbose "Completed Install"

        #Exit-PSSession

        return

    

     }

}


PROCESS {

    #disable debug confirmation messages

    if ($PSBoundParameters['Debug']) {$DebugPreference = "Continue"}

    $DNS = ''

    $SANEntries=$true


    if ($PSBoundParameters.ContainsKey('Install')) {


       Write-Host "Installing Certs"


       if (!(Test-Path -Path $Install)) {

          Write-Error "Path does not exist!"

          exit

       }


       #check if a file is provided for SAN loads

       if ($PSBoundParameters.ContainsKey('DNSFile')) {

          $DNS=SAN_Variable -CSV_Loc $DNSFile -bolInstall $true


          if (($SAN).count -eq 0) {

             $SAN = @($DNS -split ',')


             try {

                  foreach ($an in $SAN) {

                     Install_Cert -an $an -CertLoc $Install

                  }

             }

             catch {

                 #show error message (non terminating error so that the rest of the pipeline input get processed)

                 Write-Error $_

             }

             finally {

             }  

          }

       }

       else 

       {

          try {

             Install_Cert($an) #

          }

          catch {

             #show error message (non terminating error so that the rest of the pipeline input get processed)

             Write-Error $_

          }

          finally {

          }  

       }


    }


    if ($PSBoundParameters.ContainsKey('Bind')) {


       Write-Host "Binding Certs"


       #check if a file is provided for SAN loads

       if ($PSBoundParameters.ContainsKey('DNSFile')) {

          $DNS=SAN_Variable -CSV_Loc $DNSFile -bolInstall $true


          if (($SAN).count -eq 0) {

             $SAN = @($DNS -split ',')


             #################################################################################################################

             ###Purposely commented try-catch and part of finally so that it would process through all the servers in teh $SAN

             #################################################################################################################

             #try {

                  foreach ($an in $SAN) {

                     Bind_Cert -an $an -ThumbPrint $Bind

                  }

             #}

             #catch {

                 #show error message (non terminating error so that the rest of the pipeline input get processed)

             #    Write-Error $_

             #}

             #finally {

               if (Get-PSSession) {

                  Remove-PSSession -ComputerName $an

               }

             #}  

          }

       }

       else 

       {

          try {

             Bind_Cert($an) #

          }

          catch {

             #show error message (non terminating error so that the rest of the pipeline input get processed)

             Write-Error $_

          }

          finally {

            if (Get-PSSession) {        

                  Remove-PSSession -ComputerName $an

            }

          }  

       }


    }


    if ($PSBoundParameters.ContainsKey('DeleteCert')) {


       Write-Host "Deleting Certs"



       #check if a file is provided for SAN loads

       if ($PSBoundParameters.ContainsKey('DNSFile')) {

          $DNS=SAN_Variable -CSV_Loc $DNSFile -bolInstall $true


          if (($SAN).count -eq 0) {

             $SAN = @($DNS -split ',')


             try {

                  foreach ($an in $SAN) {

                     Delete_Cert -an $an -CertName $DeleteCert

                  }

             }

             catch {

                 #show error message (non terminating error so that the rest of the pipeline input get processed)

                 Write-Error $_

             }

             finally {

             }  

          }

       }

       else 

       {

          try {

             Delete_Cert($an) #

          }

          catch {

             #show error message (non terminating error so that the rest of the pipeline input get processed)

             Write-Error $_

          }

          finally {

          }  

       }


    }


    if ($PSBoundParameters.ContainsKey('SetPerm')) {


       Write-Host "Setting Permissions on Certs"



       #check if a file is provided for SAN loads

       if ($PSBoundParameters.ContainsKey('DNSFile')) {

          $DNS=SAN_Variable -CSV_Loc $DNSFile -bolInstall $true


          if (($SAN).count -eq 0) {

             $SAN = @($DNS -split ',')


             try {

                  foreach ($an in $SAN) {

                     SetPerm -an $an -PowerShellLoc $PowerShellLoc -CertName $SetPerm

                  }

             }

             catch {

                 #show error message (non terminating error so that the rest of the pipeline input get processed)

                 Write-Error $_

             }

             finally {

             }  

          }

       }

       else 

       {

          try {

             SetPerm($an) #

          }

          catch {

             #show error message (non terminating error so that the rest of the pipeline input get processed)

             Write-Error $_

          }

          finally {

          }  

       }


    }


    if ((!($PSBoundParameters.ContainsKey('Install'))) -and (!($PSBoundParameters.ContainsKey('DeleteCert'))) -and (!($PSBoundParameters.ContainsKey('SetPerm'))) `

         -and (!($PSBoundParameters.ContainsKey('Bind'))) -and (!($PSBoundParameters.ContainsKey('SetPerm')))) {


       Write-Verbose "Generating request inf file"

       $file = @"

[NewRequest]

Subject = "CN=$CN,c=$Country, s=$State, l=$City, o=$Organization, ou=$Department, E=$Email"  

FriendlyName = "$CN"

MachineKeySet = TRUE

SMIME = False

UseExistingKeySet = False

KeyLength = 4096

KeySpec=1

Exportable = TRUE

RequestType = PKCS10

ProviderName = "Microsoft RSA SChannel Cryptographic Provider"

HashAlgorithm = SHA256

[RequestAttributes]

"@

       #CertificateTemplate = "$TemplateName"

    


       #check if a file is provided for SAN loads

       if ($PSBoundParameters.ContainsKey('DNSFile')) {

          $DNS=SAN_Variable -CSV_Loc $DNSFile -bolInstall $false


          if (($SAN).count -eq 0) {

             $SAN = @($DNS -split ',')


             Write-Host "Requesting SAN certificate with subject $CN and SAN: $($SAN -join ",`r`n")" -ForegroundColor Green

             Write-Debug "Parameter values: CN = $CN, TemplateName = $TemplateName, CAName = $CAName, SAN = $($SAN -join ' ')"

             #$SANEntries = $true

          }

       }

   

       #check if SAN certificate is requested

       if ($PSBoundParameters.ContainsKey('SAN')) {

           #each SAN must be a array element

           #if the array has ony one element then split it on the commas.


           if (($SAN).count -eq 1) {

               $SAN = @($SAN -split ',')


               Write-Host "Requesting SAN certificate with subject $CN and SAN: $($SAN -join ',')" -ForegroundColor Green

               Write-Debug "Parameter values: CN = $CN, TemplateName = $TemplateName, CAName = $CAName, SAN = $($SAN -join ' ')"

               #$SANEntries = $true

           }

       }


       if ($PSBoundParameters.ContainsKey('CodeSign')) {

           #If this is a code signing cert then applied the EnhancedKeyUsageExtension

          

           Write-Host "Apply the EnhancedKeyUsageExtension for Code Signing. " -ForegroundColor Green


           $file += @'


[EnhancedKeyUsageExtension]

OID=1.3.6.1.5.5.7.3.3 ; Code signing"


'@

       }


       if ($SANEntries) {

           Write-Verbose "A value for the SAN is specified. Requesting a SAN certificate."

           Write-Debug "Add Extension for SAN to the inf file..."

           $file += @'


[Extensions]

; If your client operating system is Windows Server 2008, Windows Server 2008 R2, Windows Vista, or Windows 7

; SANs can be included in the Extensions section by using the following text format. Note 2.5.29.17 is the OID for a SAN extension.


2.5.29.17 = "{text}"


'@

           $file += "_continue_ = `"DNS=$($CN)&`"`r`n"


           foreach ($an in $SAN) {

               $file += "_continue_ = `"$($an)&`"`r`n"

           }


        

           Write-Debug "SAN: $file"

       }

       else {

           Write-Host "Requesting certificate with subject $CN" -ForegroundColor Green

           Write-Debug "Parameter values: CN = $CN, TemplateName = $TemplateName, CAName = $CAName"

       }

    

       try {

           #create temp files

           $inf = [System.IO.Path]::GetTempFileName()

           $rsp = Join-Path -Path $env:TEMP -ChildPath "$CN.req"


           #Remove-ReqTempfiles -tempfiles $inf, $req, $cer, $rsp

           #create new request inf file

           Set-Content -Path $inf -Value $file


           #show inf file if -verbose is used

           Get-Content -Path $inf | Write-Verbose


           Write-Verbose "generate .req file with certreq.exe"

           Invoke-Expression -Command "certreq -new `"$inf`" `"$rsp`""

           if (!($LastExitCode -eq 0)) {

               throw "certreq -new command failed"

           }


       }

       catch {

           #show error message (non terminating error so that the rest of the pipeline input get processed)

           Write-Error $_

       }

       finally {

       }

    }

}


END {

}


-------------------------------------------------------------------------------------------------------------------------------

Delete SSL cert on servers remotly

.\Cert-RequestOrInstallBind.ps1 -DNSFile "\\servers_names.csv" -DeleteCert "QNXT_STG56R3.molina.mhc" *>&1 | Tee-Object -append -FilePath "\\output_Delete_Cert_20210413.txt"

Install SSL cert on servers remotly

.\Cert-RequestOrInstallBind.ps1 -DNSFile "\\servers_names.csv" -Install F:\ -PFXPassword "*****" -PFXFile "\\cert.pfx" *>&1 | Tee-Object -append -FilePath "\\output_Deploy_Cert_20210413.txt"

Bind SSL cert on IIS remotly

.\Cert-RequestOrInstallBind.ps1 -DNSFile "\\servers_names.csv" -Bind "THUMBPRINT" *>&1 | Tee-Object -append -FilePath "\\output_Bind_Cert_20210413.txt"

Comments

Popular posts from this blog

NetSH collection commands

Script for Host entry in remote servers