cEprsCertificate.psm1

enum Ensure
{
    Present
    Absent
}

[DSCResource()]
class InstallCertificate
{
    [DscResourceKey()] [String] $PfxFile
    [DscResourceKey()] [String] $CertificateStorePath
    [DscResourceKey()] [String] $Password
    [DscResourceKey()] [String] $Logfile
    [DscResourceKey()] [Ensure] $Ensure


    [InstallCertificate] Get()
    {

        $config=@{}
        


        $mypwd = ConvertTo-SecureString -String $this.Password -Force –AsPlainText
        $pfxsplit = $this.PfxFile.Split("\")
        $certname = $pfxsplit[$pfxsplit.Count-1].Split(".")[0]          
        Write-Verbose "Cerificate name: $certname"
        $cert = (Get-ChildItem $this.CertificateStorePath | Where-Object {$_.Subject -ilike "*$certname*"})
        $certpath = "$this.CertificateStorePath\" + $cert.Thumbprint           
        Write-Verbose "Cerificate path: $certpath"
        $certexists = (Test-Path -path $certpath -PathType Leaf)            
        Write-Verbose "certexists: $certexists"
        $certensure = "Absent"
        switch ($certexists) {
            $true {$certensure = "Present"}
            $false {$certensure = "Absent"}
            }        
    
        $config.Add("PfxFile", $this.PfxFile)
        $config.Add("CertificateStorePath", $certpath)
        $config.Add("Ensure", $certensure)
         return $config           
     
    }

    [bool] Test()
    {
        $pfsfile =  $this.PfxFile
        $certificatepath = $this.CertificateStorePath
        Write-Verbose "$pfsfile Pfxfile"
        
        $mypwd = ConvertTo-SecureString -String $this.Password -Force –AsPlainText
        $pfxsplit = $this.PfxFile.Split("\")
        $certname = $pfxsplit[$pfxsplit.Count-1].Split(".")[0]          
        Write-Verbose "Cerificate name: $certname" -Verbose
        $cert = (Get-ChildItem $this.CertificateStorePath | Where-Object {$_.Subject -ilike "*$certname*"})
        $certpath = "$certificatepath\" + $cert.Thumbprint           
        Write-Verbose "Cerificate path: $certpath" -Verbose
        $certexists = (Test-Path -path $certpath -PathType Leaf)            
        Write-Verbose "certexists: $certexists" 
        $certensure = "Absent"
        switch ($certexists) {
            $true {$certensure = "Present"}
            $false {$certensure = "Absent"}
            }        
    

        if($this.Ensure -eq [Ensure]::Present)
        {
            if($this.Ensure -eq $certensure)
            {
                return $true
            }
            else
            {
                return $false
            }
        }
        else
        {
            if($this.Ensure -eq $certensure)
            {
                return $true
            }
            else
            {
                return $false
            }
        }

    }

    [void] Set()
    {
        $CertStorePath = $this.CertificateStorePath
        if($this.Ensure -eq [Ensure]::Present) 
        {
            $mypwd = ConvertTo-SecureString -String $this.Password -Force –AsPlainText 
            New-Item -Path $this.Logfile -itemtype "file" -Force
            Write-Verbose "Ensuring the cerificate to be Present" -Verbose
            Write-Verbose $this.Ensure
            Import-PfxCertificate –FilePath $this.PfxFile -CertStoreLocation $this.CertificateStorePath -Password $mypwd -Exportable | Out-File -FilePath $this.Logfile
           
        }
        else 
        {
            $pfxsplit = $this.PfxFile.Split("\")
            $certname = $pfxsplit[$pfxsplit.Count-1].Split(".")[0]
            $cert = (Get-ChildItem $this.CertificateStorePath | Where-Object {$_.Subject -ilike "*$certname*"})
            $certthumbprint = (Get-ChildItem $this.CertificateStorePath | Where-Object {$_.Subject -ilike "*$certname*"}).Thumbprint
            $certpath = "$CertStorePath\" + "$certthumbprint"
            Write-Verbose "Ensuring the cerificate is Absent ..." -Verbose
            Remove-Item -Path "$certpath" -Verbose | Out-File -FilePath $this.Logfile
        }
    }


  
}


[DSCResource()]
class MapCerttoUser
{
    [DscResourceKey()] [String] $CertificateName
    [DscResourceKey()] [String] $CertificateStorePath
    [DscResourceKey()] [String] $UserName
    [DscResourceKey()] [Ensure]  $Ensure

    
    [MapCerttoUser] Get()
    {
        $config=@{}
        $certname = $this.CertificateName
        $cert = (Get-ChildItem $this.CertificateStorePath | Where-Object {$_.Subject -ilike "*$certname*"})

        $sslCertPrivKey = $cert.PrivateKey 
        $privKeyCertFile = Get-Item -path "$ENV:ProgramData\Microsoft\Crypto\RSA\MachineKeys\*"  | where {$_.Name -eq $sslCertPrivKey.CspKeyContainerInfo.UniqueKeyContainerName} 
        $certkeypath = $privKeyCertFile.FullName
        Write-Verbose "Cerificate key file path: $certkeypath" -Verbose

        $privKeyAcl = (Get-Item -Path $certkeypath).GetAccessControl("Access") 
        $users = $privKeyAcl.Access | Select-Object -ExpandProperty IdentityReference

        $accessexists = $false
        if($users -contains $this.UserName)
        {
            $accessexists = $true
        }
        Write-Verbose "User mapped?: $accessexists" -Verbose
    
        $access = If ($accessexists -eq $true) {'Present'} Else {'Absent'}
        $config.Add("CertificateName", $this.CertificateName)
            $config.Add("CertificateStorePath", $this.CertificateStorePath)
            $config.Add("UserName", $this.UserName)
            $config.Add("Ensure", $access)
        return $config    
        
    }

    [bool] Test()
    {
        $certname = $this.CertificateName
        $cert = (Get-ChildItem $this.CertificateStorePath | Where-Object {$_.Subject -ilike "*$certname*"})
        if ($cert -eq $null)
        {
            write-error "Certificate $certname does not exist"  -Verbose
            return
        }

        $sslCertPrivKey = $cert.PrivateKey 
        $privKeyCertFile = Get-Item -path "$ENV:ProgramData\Microsoft\Crypto\RSA\MachineKeys\*"  | where {$_.Name -eq $sslCertPrivKey.CspKeyContainerInfo.UniqueKeyContainerName} 
        $certkeypath = $privKeyCertFile.FullName
        Write-Verbose "Cerificate key file path: $certkeypath" -Verbose

        $privKeyAcl = (Get-Item -Path $certkeypath).GetAccessControl("Access") 
        $users = $privKeyAcl.Access | Select-Object -ExpandProperty IdentityReference

        $accessexists = $false
        if($users -contains $this.UserName)
        {
            $accessexists = $true
        }
        Write-Verbose "User mapped?: $accessexists" -Verbose
    
        $access = If ($accessexists -eq $true) {'Present'} Else {'Absent'}

        if($this.Ensure -eq [Ensure]::Present)
        {
            if($this.Ensure -eq "$accessexists")
            {
                return $true
            }
            else
            {
                return $false
            }
        }
        else
        {

            if($this.Ensure -eq "$accessexists")
            {
                Write-Verbose "False"
                return $true
            }
            else
            {
                return $false
            }
        }

        
    }

    [void] Set()
    {
        $certname = $this.CertificateName
        $cert = (Get-ChildItem $this.CertificateStorePath | Where-Object {$_.Subject -ilike "*$certname*"})
        $sslCertPrivKey = $cert.PrivateKey 

        $privKeyCertFile = Get-Item -path "$ENV:ProgramData\Microsoft\Crypto\RSA\MachineKeys\*" | where {$_.Name -eq $sslCertPrivKey.CspKeyContainerInfo.UniqueKeyContainerName} 
        $certkeypath = $privKeyCertFile.FullName
        Write-Verbose "Cerificate key file path: $certkeypath" -Verbose
        $privKeyAcl = (Get-Item -Path $certkeypath).GetAccessControl("Access") 

        $permission = $this.UserName,"Read","Allow" 
        $accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule $permission
     
        if($this.Ensure -eq "Present")
        {
            Write-Verbose "Ensuring the cerificate is Present.." -Verbose
            $privKeyAcl.AddAccessRule($accessRule) 
            Set-Acl $privKeyCertFile.FullName $privKeyAcl
        }
        Else
        {
            Write-Verbose "Ensure: $this.Ensure ..." -Verbose
            if($this.Ensure -eq "Absent")
            {
                Write-Verbose "Ensuring the cerificate is Absent" -Verbose
                $privKeyAcl.RemoveAccessRule($accessRule) 
                Set-Acl $privKeyCertFile.FullName $privKeyAcl
            }
        }


    }

}

[DSCResource()]
class MapCerttoWebsite
{
    [DscResourceKey()] [String] $WebsiteName
    [DscResourceKey()] [String] $CertificateStorePath
    [DscResourceKey()] [String] $CertificateName
    [DscResourceKey()] [String] $SSLPort
    [DscResourceKey()] [string] $IP
    [DscResourceKey()] [Ensure] $Ensure
    
    

    
    [MapCerttoWebsite] Get()
    {
        $config=@{}

        $getTargetResourceResult = $null;
        $Website = Get-Website -Name $this.WebsiteName
        if($Website -ne $null)
        {
            $getTargetResourceResult = @{
                                            WebsiteName = $Website.Name; 
                                            HasFound = $true;
                                        }
  
        }
        else
        {
            $getTargetResourceResult = @{
                                            WebsiteName = "WebSite Not Found";
                                            HasFound = $false;
                                        }
        }

        $getTargetResourceResult;


    
       
        $config.Add("WebsiteName", $this.WebsiteName)
            $config.Add("CertificateStorePath", $this.CertificateStorePath)
            $config.Add("CertificateName", $this.CertificateName)
            $config.Add("SSLPort", $this.SSLPort)
            $config.Add("IP", $this.IP)
            $config.Add("Ensure", $this.Ensure)
        return $config    
        
    }

    [bool] Test()
    {
        $Web = $this.WebsiteName
        $Website = Get-Website -Name $Web

        if($Website -eq $null)
        {
        Write-Error "Website doesnt exist" -Verbose
        return
        }
       
       
        if($this.Ensure -eq [Ensure]::Present)
        {
            if($Website)
            {
                $binding = Get-WebBinding -Name $Web -Protocol "https" -Port $this.SSLPort -IPAddress $this.IP
                if($binding -ne $null)
                {
                    return $true
                }
                else
                {
                    return $false
                }
                
            }
            else
            {
                return $false
            }
        }
        else
        {
            $binding = Get-WebBinding -Name $Web -Protocol "https" -Port $this.SSLPort -IPAddress $this.IP
            if($Website)
            {
                return $false
            }
            else
            {
                return $true
            }
        }
        
    }

    [void] Set()
    {
        $certname = $this.CertificateName
        $Port = $this.SSLPort
        $IPAdd = $this.IP
        $Web = $this.WebsiteName
        if($this.Ensure -eq [Ensure]::Present)
        {
            $cert = (Get-ChildItem $this.CertificateStorePath | Where-Object {$_.Subject -ilike "*$certname*"})
            $binding = Get-WebBinding -Name "$Web" -Protocol https  -Port $this.SSLPort -IPAddress $IPAdd -ErrorAction SilentlyContinue
           if ($binding -eq  $null)
            {
                Remove-WebBinding -Name "$Web" -Port $this.SSLPort -Protocol "https" -ErrorAction SilentlyContinue

                New-WebBinding -Name "$Web" -Port $this.SSLPort -IP $IPAdd -Protocol "https" 
                New-Item -Path IIS:SslBindings\$IPAdd!$Port -value $cert 
                
            }
        }
        else
        {
            $binding = Get-WebBinding -Name "$Web" -Protocol "https" -Port $this.SSLPort -IPAddress $IPAdd
            if ($binding -ne  $null)
            {
                Remove-Item -path "IIS:\SslBindings\$IPAdd!$Port"
                Remove-WebBinding -Name "$Web"  -IPAddress $IPAdd  -Port $this.SSLPort #-Protocol "https" -IPAddress $IPAdd
                
                
            }
        }

    }

}