Public/New-SelfSignedCert.ps1


#Requires -RunAsAdministrator

function New-SelfSignedCert {
    [CmdletBinding(SupportsShouldProcess = $true)]
    param(
        [Parameter(Mandatory = $true)]
        [string] $Name,
        [Parameter(Mandatory = $true)]
        [string] $FriendlyName = $Name,
        [Parameter(Mandatory = $true)]
        [string] $DnsName = $FriendlyName,
        [Parameter(Mandatory = $true)]
        [string] $CertStoreLocation
    )

    function Set-ReadPermissionsForCert {
        param (
            [System.Security.Cryptography.X509Certificates.X509Certificate] $Cert,
            [string]$Username = $env:USERNAME
        )

        $keyPath = Join-Path $env:ProgramData 'Microsoft\Crypto\RSA\MachineKeys'
        $certUniqueKeyContainerName = $Cert.PrivateKey.CspKeyContainerInfo.UniqueKeyContainerName
        Write-Host $certUniqueKeyContainerName
        $fullPath = Join-Path $keyPath $certUniqueKeyContainerName
        Write-Host $fullPath
        $acl = Get-Acl -Path $fullPath
        $acl | fl
        # Set the permissions that you want to apply to the folder
        $permission = $env:username, 'Read,Modify', 'ContainerInherit,ObjectInherit', 'None', 'Allow'

        #$permission = $Username,"Read","Allow", 'ContainerInherit,ObjectInherit', 'None', 'Allow'
        $accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule $permission
        $acl.AddAccessRule($accessRule)
        Set-Acl $fullPath $acl
    }

# Generate a cert
    # https://docs.microsoft.com/en-us/powershell/module/pkiclient/new-selfsignedcertificate?view=win10-ps
    $cert = New-SelfSignedCertificate `
        -FriendlyName $FriendlyName -DnsName $DnsName -CertStoreLocation $CertStoreLocation `
        -NotAfter (Get-Date).AddYears(10) -KeyAlgorithm Sha256 -KeyLength 2048 `
        -KeyExportPolicy Exportable -KeyProtection None `
        -Provider 'Microsoft Enhanced RSA and AES Cryptographic Provider' -Verbose

    $certStoreParent = Split-Path -Path $CertStoreLocation -Parent
    $certStoreName = Split-Path $certStoreParent -Leaf

    $pfxCertPath = (Join-Path $env:TEMP "$($FriendlyName).pfx")
    $pfxCertPassword = ConvertTo-SecureString 'test' -AsPlainText -Force
    $cert | Export-PfxCertificate -FilePath $pfxCertPath -Password $pfxCertPassword | Out-Null

    try
    {
        # Create the certificate
        $pfxcert = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate2 -ErrorAction Stop;
        $KeyStorageFlags = [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable -bxor [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::MachineKeySet -bxor [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::PersistKeySet;

        Write-Verbose ('Key storage flags is: {0}' -f $KeyStorageFlags);

        $pfxcert.Import($pfxCertPath, $pfxCertPassword, $KeyStorageFlags);

        # Create the X509 store and import the certificate
        $store = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Store -ArgumentList My, LocalMachine -ErrorAction Stop;
        $store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite);
        $store.Add($pfxcert);
        $store.Close();

        Write-Output -InputObject $pfxcert;
    }
    catch
    {
        throw $_;
    }
    # Trust the cert
    # https://stackoverflow.com/questions/8815145/how-to-trust-a-certificate-in-windows-powershell
    $store = New-Object System.Security.Cryptography.X509Certificates.X509Store 'Root',$certStoreName
    $store.Open("ReadWrite")
    $store.Add($cert)
    $store.Close()

    Export-Certificate -Cert $cert -FilePath (Join-Path $env:TEMP "$($FriendlyName).cer")
    #Set-ReadPermissionsForCert $cert
    # remove the untrusted copy of the cert
    #$cert | Remove-Item

    Write-Verbose "Created certificate $FriendlyName with thumbprint $($cert.Thumbprint)"

    return $cert
}