# How to create Certrequests with PowerShell

First we need an installed OpenSSL on the WindowsServer.
The CodeSigning Part (Option 5) is not working yet.

```powershell
### Modules
Import-Module ActiveDirectory

### variables
$openSSLDir = "C:\Program Files\OpenSSL-Win64\bin"

### temporary directory path for the cert files during the creation
$tempDir = "C:\temp"

### directory path for the main location of the finished cert files
$share = "\\mystorage.mydomain.local\certs"

### own list of copy machines that are not part of active direcoty
$kopierer = @("Kopierer-EG","Kopierer-OG")

### dito for accesspoints
$accesspoints = @("AP-EG","AP-OG","AP-DG")

### charackter for awesome checkmark symbol :)
$checkmark = [char]8730

### attributes of your certificate
$cert_U = [System.Text.Encoding]::UTF8.GetString([System.Text.Encoding]::UTF8.GetBytes("IT-Abteilung"))
$cert_O = [System.Text.Encoding]::UTF8.GetString([System.Text.Encoding]::UTF8.GetBytes("MyCompanyName"))
$cert_L = [System.Text.Encoding]::UTF8.GetString([System.Text.Encoding]::UTF8.GetBytes("Location"))
$cert_S = [System.Text.Encoding]::UTF8.GetString([System.Text.Encoding]::UTF8.GetBytes("State"))
$cert_C = "DE"
$cert_E = "it@example.com"

### functions
function createCert([string]$Template, [string]$dns1, [string]$dns2) {

    $CSRPath = "$($tempDir)\$($CertName).csr"
    $INFPath = "$($tempDir)\$($CertName).inf"
    $CRTPath = "$($tempDir)\$($CertName)_decrypted.crt"
    $CRPPath = "$($tempDir)\$($CertName)_encrypted.crt"
    $PFXPath = "$($tempDir)\$($CertName).pfx"
    $RSPPath = "$($tempDir)\$($CertName).rsp"
    $KEYPath = "$($tempDir)\$($CertName)_decrypted.key"
    $KEPPath = "$($tempDir)\$($CertName)_encrypted.key"
    $PEMPath = "$($certStorage)\$($CertName).pem"

    $INF =
@"
[NewRequest]
Subject = "CN=$CertName, OU=$cert_U, O=$cert_O, L=$cert_L, S=$cert_S, C=$cert_C, E=$cert_E"
FriendlyName = "$CertName"
KeySpec = 1
KeyLength = 2048
Exportable = TRUE
RequestType = PKCS10
MachineKeySet = TRUE
SMIME = False
PrivateKeyArchive = FALSE
UserProtected = FALSE
UseExistingKeySet = FALSE
ProviderName = "Microsoft RSA SChannel Cryptographic Provider"
ProviderType = 12
KeyUsage = 0xa0
"@

    if ($CertName -like "wildcard*") {
        $INF +=
@"


[EnhancedKeyUsageExtension] 
OID=1.3.6.1.5.5.7.3.1

[Extensions]
2.5.29.17 = "{text}"
_continue_ = "dns=$dns1&"
_continue_ = "dns=$dns2&"
"@
    }

	Write-Host `r`n
    Write-Host 'Create Cert for: ' -NoNewline -ForegroundColor White
    Write-Host $CertName -ForegroundColor Cyan
	Write-Host '==================================================' -ForegroundColor White
    
    $INF | Out-File -filepath $INFPath -Encoding default
    certreq -new $INFPath $CSRPath | Out-Null

    Write-Host 'CSR: ' -NoNewline -ForegroundColor Gray
    Write-Host $checkmark -ForegroundColor Green

    certreq -config "myCA.mydomain.local\mydomain-CA" -attrib "CertificateTemplate:$($Template)" -submit $CSRPath $CRPPath | Out-Null
    certreq -accept $CRPPath | Out-Null

    ### old version
    #$cerFile = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2
    #$cerFile.Import($CRPPath)

    ### new version (https://www.cloudnotes.io/x509certificate-is-immutable-on-this-platform-use-the-equivalent-constructor-instead/)
	$cerFile = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate2($CRPPath)
    
    $thumbprint = $cerFile.Thumbprint
    Get-ChildItem -Path "Cert:\LocalMachine\my\$thumbprint" | Export-PfxCertificate -FilePath $PFXPath -Password $securePass | Out-Null
    Get-ChildItem -Path "Cert:\LocalMachine\my\$thumbprint" | Remove-Item -Confirm:$false
    Write-Host 'PFX: ' -NoNewline -ForegroundColor Gray
    Write-Host $checkmark -ForegroundColor Green
    
    if ($CertName -like "Kopierer*") {
        Move-Item -Path "$PFXPath" -Destination "$($certStorage)\$($CertName).pfx"
    } elseif ($CertName -like "AP-*") {
        Start-Process .\openssl.exe -Argumentlist "pkcs12 -in $PFXPath -clcerts -nokeys -out $CRPPath -passin pass:$plainPass" -wait
        Start-Process .\openssl.exe -Argumentlist "pkcs12 -in $PFXPath -nocerts -out $KEPPath -passout pass:$plainPass -passin pass:$plainPass" -wait
        Start-Process .\openssl.exe -Argumentlist "rsa -in $KEPPath -out $KEYPath -passin pass:$plainPass" -wait

        Write-Host 'KEY: ' -NoNewline -ForegroundColor Gray
        Write-Host $checkmark -ForegroundColor Green

        $pem = Get-Content $CRPPath
        $pem | Out-File -Encoding UTF8 $PEMPath
		
		Move-Item -Path "$KEYPath" -Destination "$($certStorage)\$($CertName)_key.pem"
        
        Write-Host 'PEM: ' -NoNewline -ForegroundColor Gray
        Write-Host $checkmark -ForegroundColor Green
	} elseif ($CertName -like "Telefon*") {
        Start-Process .\openssl.exe -Argumentlist "pkcs12 -in $PFXPath -clcerts -nokeys -out $CRPPath -passin pass:$plainPass" -wait
        Start-Process .\openssl.exe -Argumentlist "pkcs12 -in $PFXPath -nocerts -out $KEPPath -passout pass:$plainPass -passin pass:$plainPass" -wait
        Start-Process .\openssl.exe -Argumentlist "rsa -in $KEPPath -out $KEYPath -passin pass:$plainPass" -wait

        Write-Host 'KEY: ' -NoNewline -ForegroundColor Gray
        Write-Host $checkmark -ForegroundColor Green

        $pem = Get-Content $CRPPath
        $pem += Get-Content $KEYPath
        $pem | Out-File -Encoding UTF8 $PEMPath
        
        Write-Host 'PEM: ' -NoNewline -ForegroundColor Gray
        Write-Host $checkmark -ForegroundColor Green
    } elseif ($CertName -like "wildcard*") {
        Start-Process .\openssl.exe -Argumentlist "pkcs12 -in $PFXPath -clcerts -nokeys -out $CRTPath -passin pass:$plainPass" -wait
        Start-Process .\openssl.exe -Argumentlist "pkcs12 -in $PFXPath -nocerts -out $KEPPath -passin pass:$plainPass -passout pass:$plainPass" -wait
        Start-Process .\openssl.exe -Argumentlist "rsa -in $KEPPath -out $KEYPath -passin pass:$plainPass" -wait
        Move-Item -Path "$PFXPath" -Destination "$($certStorage)\$($CertName).pfx"
        Move-Item -Path "$KEPPath" -Destination "$($certStorage)\$($CertName)_encrypted.key"
        Move-Item -Path "$KEYPath" -Destination "$($certStorage)\$($CertName)_decrypted.key"
        Move-Item -Path "$CRPPath" -Destination "$($certStorage)\$($CertName)_encrypted.crt"
        Move-Item -Path "$CRTPath" -Destination "$($certStorage)\$($CertName)_decrypted.crt"
    }

    Get-ChildItem "$($tempDir)" -recurse -force -include *.csr,*.inf,*.crt,*.rsp,*.key,*.kep,*.pfx | Remove-Item -force
}

function accesspoints([string]$pass) {
    $TEMP = "RadiusZertifikat(keyexport)"
    $certStorage = "$($share)\$($TEMP)\accesspoints\$(Get-Date -UFormat %Y-%m-%d_%H%M%S)\"
    New-Item -Path $certStorage -Type Directory -Force | Out-Null
	Import-Module ActiveDirectory

    foreach($device in $accesspoints) {
        $CertName = "$device.mydomain.local"
        createCert $TEMP $pass
    }
}

function yealinks([string]$pass) {
    $TEMP = "RadiusZertifikat(keyexport)"
    $certStorage = "$($share)\$($TEMP)\yealinks\$(Get-Date -UFormat %Y-%m-%d_%H%M%S)\"
    New-Item -Path $certStorage -Type Directory -Force | Out-Null
    ### adjust the SearchBase
    $users = Get-ADUser -SearchBase "OU=Users,DC=mydomain,DC=local" -Filter * -Properties *
    $ext = @()
    foreach($user in $users){

        ### adjust the format to your environment (stored phone number on user attributs)
        if($user.OfficePhone -like "0123 1111-*"){
            ### example for user that got different number in AD than it should have
            if ($user.Name -eq "max"){
                $ext += 25
            ### example for skipped user
            }elseif ($user.Name -eq "lisa"){
                
            }else{
                $ext += ($user.OfficePhone).split("-")[1]
            }
        }
    }

    ### extra number for phones not belonging to an employee
    $ext += 949

    foreach($e in $ext) {
        $CertName = "Telefon-$e"
        createCert $TEMP $pass
    }
}

function kopierer([string]$pass) {
    $TEMP = "RadiusZertifikat(keyexport)"
    $certStorage = "$($share)\$($TEMP)\kopierer\$(Get-Date -UFormat %Y-%m-%d_%H%M%S)\"
    New-Item -Path $certStorage -Type Directory -Force | Out-Null
    foreach($device in $kopierer){
        $CertName = "$device.mydomain.local"
        createCert $TEMP $pass
    }
}

function webserver($pw) {
    $CertName = "wildcard.mydomain.local"
    $dns1 = "mydomain.local"
    $dns2 = "*.mydomain.local"

    ### Template on your CA that should be used
    $TEMP = "WebServerTemplate"

    $certStorage = "$($share)\$($TEMP)\wildcard\$(Get-Date -UFormat %Y-%m-%d_%H%M%S)\"
    New-Item -Path $certStorage -Type Directory -Force | Out-Null
    createCert $TEMP $dns1 $dns2
}

function menu {
	Do
	{
		### user interaction
        Start-Sleep 1
		clear
		Write-Host `r`n
		Write-Host 'Certcreation' -NoNewline -ForegroundColor Red
        Write-Host ' © ' -NoNewline -ForegroundColor Gray
        Write-Host 'Klüber-IT' -NoNewline -ForegroundColor Cyan
        Write-Host ' & ' -NoNewline -ForegroundColor Gray
        Write-Host 'Gläser-IT' -ForegroundColor Cyan
		Write-Host '========================================'

		#[1] - Webserver Wildcard
		Write-Host '[' -NoNewline
		Write-Host '1' -NoNewline -ForegroundColor Cyan
		Write-Host '] - Webserver: ' -NoNewline
        Write-Host 'wildcard.mydomain.local' -ForegroundColor Green

		#[2] - Yealink
		Write-Host '[' -NoNewline
		Write-Host '2' -NoNewline -ForegroundColor Cyan
		Write-Host '] - Computer: ' -NoNewline
        Write-Host 'Radius Yealink Telefone' -ForegroundColor Green

		#[3] - Kopierer
		Write-Host '[' -NoNewline
		Write-Host '3' -NoNewline -ForegroundColor Cyan
		Write-Host '] - Computer: ' -NoNewline
        Write-Host 'Radius Kopierer' -ForegroundColor Green

		#[4] - Accesspoints
		Write-Host '[' -NoNewline
		Write-Host '4' -NoNewline -ForegroundColor Cyan
		Write-Host '] - Computer: ' -NoNewline
        Write-Host 'Accesspoints' -ForegroundColor Green

		#[5] - CodeSigning
		Write-Host '[' -NoNewline
		Write-Host '5' -NoNewline -ForegroundColor Cyan
		Write-Host '] - Signing: ' -NoNewline
        Write-Host 'Macros/Scripte' -ForegroundColor Green

		#[6] - Beenden
		Write-Host '[' -NoNewline
		Write-Host '6' -NoNewline -ForegroundColor Cyan
		Write-Host '] - Beenden'

		$optionA = Read-Host -Prompt 'Auswahl'
		clear
        Start-Sleep 1
		
        if ($optionA -le 5) {
            $securePass = Read-Host -Prompt 'Encryption Password' -AsSecureString
            $plainPass = [Net.NetworkCredential]::new('',$securePass).password
        }

		if ($optionA -eq 1) {
            webserver
        }elseif ($optionA -eq 2) {
            yealinks
        }elseif ($optionA -eq 3) {
            kopierer
        }elseif ($optionA -eq 4) {
            accesspoints
        }elseif ($optionA -eq 5) {
            signing
        }elseif ($optionA -eq 6) {
            Break Script
        }else{
            Write-Host "Bitte 1-6 wählen" -ForegroundColor Red
            Start-Sleep 2
		}
	} While ( !($optionA -eq 6) )
}

### running commands
Set-Location -Path $openSSLDir

menu
```