bin/DSCHelperCerts.ps1

Function Test-DSCCert {
    Param(
        [Parameter(Mandatory = $true)][string]$commonName,
        [Parameter(Mandatory = $false)][System.String]$PFXPath,
        [Parameter(Mandatory = $false)][System.String]$CERPath,
        [Parameter(Mandatory = $false)][System.String]$ThumbprintPath);
    Write-Verbose "Looking for S2S Certificate in Computer Personal Store";
    Set-Location Cert:\LocalMachine\My;
    $myCert = Get-ChildItem | Where-Object { $_.Subject -ieq $commonName; }
    $result = ($null -ne $myCert);
    if ($result) {
        Write-Verbose "Looking for $($commonName) in Computer Trusted Root Store";
        Set-Location Cert:\LocalMachine\Root;
        $myCertRoot = Get-ChildItem | Where-Object { $_.Subject -ieq $commonName; }
        $result = ($null -ne $myCertRoot);
        if ($result) {
            if (![string]::IsNullOrEmpty($PFXPath) -and ![System.IO.File]::Exists($PFXPath)) {
                $result = $false;
            }
            elseif (![string]::IsNullOrEmpty($PFXPath) -and ![System.IO.File]::Exists($PFXPath)) {
                $result = $false;
            }
            elseif (![string]::IsNullOrEmpty($ThumbprintPath) -and ![System.IO.File]::Exists($ThumbprintPath)) {
                $result = $false;
            }
        }
    }
    return $result;
}

Function Remove-DSCCert {
    Param(
        [Parameter(Mandatory = $true)][string]$commonName,
        [Parameter(Mandatory = $false)][System.String]$PFXPath,
        [Parameter(Mandatory = $false)][System.String]$CERPath);
    Set-Location Cert:\LocalMachine\My;
    Get-ChildItem | Where-Object { $_.Subject -ieq $commonName; } | Remove-Item;
    Set-Location Cert:\LocalMachine\Root;
    Get-ChildItem | Where-Object { $_.Subject -ieq $commonName; } | Remove-Item;
    if (![string]::IsNullOrEmpty($PFXPath) -and ![string]::IsNullOrEmpty($CERPath)) {
        $pwdFile = $PFXPath -ireplace ".pfx", "-pwd.txt";
        if ([System.IO.File]::Exists($pwdFile)) { Remove-Item $pwdFile -Force; }
        if ([System.IO.File]::Exists($PFXPath)) { Remove-Item $PFXPath -Force; }
        if ([System.IO.File]::Exists($CERPath)) { Remove-Item $CERPath -Force; }
    }
    elseif (![string]::IsNullOrEmpty($PFXPath)) {
        $pwdFile = $PFXPath -ireplace ".pfx", "-pwd.txt";
        if ([System.IO.File]::Exists($pwdFile)) { Remove-Item $pwdFile -Force; }
        if ([System.IO.File]::Exists($PFXPath)) { Remove-Item $PFXPath -Force; }
    }
    elseif (![string]::IsNullOrEmpty($CERPath)) {
        if ([System.IO.File]::Exists($CERPath)) { Remove-Item $CERPath -Force; }
    }
}

Function New-DSCCert {
    Param(
        [Parameter(Mandatory = $true)][string]$commonName, 
        [Parameter(Mandatory = $true)][string]$friendlyName);
    Write-Verbose "Looking for S2S Certificate in Computer Personal Store";
    Set-Location Cert:\LocalMachine\My;
    $myCert = Get-ChildItem | Where-Object { $_.Subject -ieq $commonName; }
    if ($null -eq $myCert) {
        Write-Verbose "Did not find $($commonName) in the computer personal store";
        Write-Verbose "Creating self signed certificate $($commonName)";
        $privateKey = New-Object -ComObject X509Enrollment.CX509PrivateKey;
        $privateKey.ProviderName = "Microsoft Enhanced Cryptographic Provider v1.0";
        $algName = "RSA";
        $algID = New-Object -ComObject X509Enrollment.CObjectId;
        $algID.InitializeFromValue(([Security.Cryptography.Oid]$algName).Value);
        $privateKey.Algorithm = $algID;
        $privateKey.KeySpec = 1 # Exchange;
        $privateKey.Length = 2048;
        $privateKey.MachineContext = $true;
        $privateKey.ExportPolicy = 1;
        $privateKey.Create();
        $cert = New-Object -ComObject X509Enrollment.CX509CertificateRequestCertificate;
        $cert.InitializeFromPrivateKey(0x2, $privateKey, "");
        $subjectDN = New-Object -ComObject X509Enrollment.CX500DistinguishedName;
        $subjectDN.Encode($commonName, 0x0);
        $cert.Subject = $subjectDN;
        $cert.Issuer = $cert.Subject;
        $cert.NotBefore = [DateTime]::Now.AddDays(-1);
        $cert.NotAfter = [DateTime]::Now.AddYears(20);
        $sigOID = New-Object -ComObject X509Enrollment.CObjectId;
        $sigAldName = "SHA1";
        $sigOID.InitializeFromValue(([Security.Cryptography.Oid]$sigAldName).Value);
        $cert.SignatureInformation.HashAlgorithm = $sigOID;
        $cert.Encode();
        $request = New-Object -ComObject X509Enrollment.CX509Enrollment;
        $request.InitializeFromRequest($cert);
        $request.CertificateFriendlyName = $friendlyName;
        $endCert = $request.CreateRequest(0x1); # Base 64
        $request.InstallResponse($true, $endCert, 0x1, "");
    }
    else {
        Write-Verbose "Found $($commonName) in the computer personal store";
    }
    Write-Verbose "Looking for $($commonName) in Computer Trusted Root Store";
    Set-Location Cert:\LocalMachine\Root;
    $myCertRoot = Get-ChildItem | Where-Object { $_.Subject -ieq $commonName; }
    if ($null -eq $myCertRoot) {
        Write-Verbose "Did not find $($certCommonName) in the computer trusted root store";
        Write-Verbose "Copying $($commonName) cert from personal store to trusted root store";
        $srcStore = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Store -ArgumentList 'My', 'LocalMachine';
        $srcStore.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadOnly);
        $srcCert = $srcStore.Certificates | Where-Object { $_.Subject -ieq $commonName };
        $destStore = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Store -ArgumentList 'root', 'LocalMachine';
        $destStore.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite);
        $destStore.Add($srcCert);
        $srcStore.Close();
        $destStore.Close();
    }
    else {
        Write-Verbose "Found $($commonName) in the computer trusted root store";
    }
}

Function Export-DSCCertPrivateKey {
    Param(
        [Parameter(Mandatory = $true)][string]$commonName, 
        [Parameter(Mandatory = $true)][string]$filename);
    Set-Location Cert:\LocalMachine\My;
    $myCert = Get-ChildItem | Where-Object { $_.Subject -ieq $commonName; }
    $genPwd = _NewSWRandomPassword;
    $pwdFile = $filename -ireplace ".pfx", "-pwd.txt";
    $genPwd | Out-File -FilePath $pwdFile;
    $pwd = ConvertTo-SecureString -String $genPwd -Force -AsPlainText;
    $myCert | Export-PfxCertificate -FilePath $filename -Password $pwd | Out-Null;
}

Function Export-DSCCertPublicKey {
    Param(
        [Parameter(Mandatory = $true)][string]$commonName, 
        [Parameter(Mandatory = $true)][string]$filename,
        [Parameter(Mandatory = $false)][string]$thumbprintPath);
    Set-Location Cert:\LocalMachine\My;
    $myCert = Get-ChildItem | Where-Object { $_.Subject -ieq $commonName; }
    $myCert | Export-Certificate -FilePath $filename | Out-Null;
    if (![string]::IsNullOrEmpty($thumbprintPath)) {
        $myCert.Thumbprint | Out-File $thumbprintPath -Force;
    }
}

Function _NewSWRandomPassword { 
    Begin {
        Function Get-Seed {
            # Generate a seed for randomization
            $RandomBytes = New-Object -TypeName 'System.Byte[]' 4;
            $Random = New-Object -TypeName 'System.Security.Cryptography.RNGCryptoServiceProvider';
            $Random.GetBytes($RandomBytes);
            [BitConverter]::ToUInt32($RandomBytes, 0);
        }
    }
    Process {
        [String[]]$InputStrings = @('abcdefghijkmnpqrstuvwxyz', 'ABCEFGHJKLMNPQRSTUVWXYZ', '23456789');
        For ($iteration = 1; $iteration -le 1; $iteration++) {
            $Password = @{ };
            # Create char arrays containing groups of possible chars
            [char[][]]$CharGroups = $InputStrings;

            # Create char array containing all chars
            $AllChars = $CharGroups | ForEach-Object { [Char[]]$_ };

            # Randomize one char from each group
            Foreach ($Group in $CharGroups) {
                if ($Password.Count -lt 16) {
                    $Index = Get-Seed;
                    While ($Password.ContainsKey($Index)) {
                        $Index = Get-Seed;       
                    }
                    $Password.Add($Index, $Group[((Get-Seed) % $Group.Count)]);
                }
            }

            # Fill out with chars from $AllChars
            for ($i = $Password.Count; $i -lt 16; $i++) {
                $Index = Get-Seed;
                While ($Password.ContainsKey($Index)) {
                    $Index = Get-Seed;
                }
                $Password.Add($Index, $AllChars[((Get-Seed) % $AllChars.Count)]);
            }
            Write-Output -InputObject $( -join ($Password.GetEnumerator() | Sort-Object -Property Name | Select-Object -ExpandProperty Value));
        }
    }
}