Skip to content

Commit

Permalink
Merge pull request #12 from briantist/xPfxImport
Browse files Browse the repository at this point in the history
Adding xPfxImport DSC Resource
  • Loading branch information
KarolKaczmarek committed Nov 7, 2015
2 parents 1956443 + 66c92b9 commit 502b82d
Show file tree
Hide file tree
Showing 6 changed files with 606 additions and 40 deletions.
298 changes: 298 additions & 0 deletions DSCResources/MSFT_xPfxImport/MSFT_xPfxImport.psm1
Original file line number Diff line number Diff line change
@@ -0,0 +1,298 @@
#Requires -Version 4.0

<#
.SYNOPSIS
Validates the existence of a file at a specific path.
.PARAMETER Path
The location of the file. Supports any path that Test-Path supports.
.PARAMETER Quiet
Returns $false if the file does not exist. By default this function throws an exception if the file is missing.
.EXAMPLE
Validate-PfxPath -Path '\\server\share\Certificates\mycert.pfx'
.EXAMPLE
Validate-PfxPath -Path 'C:\certs\my_missing.pfx' -Quiet
.EXAMPLE
'D:\CertRepo\a_cert.pfx' | Validate-PfxPath
.EXAMPLE
Get-ChildItem D:\CertRepo\*.pfx | Validate-PfxPath
#>
function Validate-PfxPath
{
[CmdletBinding()]
param(
[Parameter(
Mandatory,
ValueFromPipeline
)]
[String[]]
$Path ,

[Parameter()]
[Switch]
$Quiet
)

Process
{
foreach($p in $Path)
{
if ($p | Test-Path -PathType Leaf)
{
$true
}
elseif ($Quiet)
{
$false
}
else
{
throw [System.ArgumentException]"File '$p' not found."
}
}
}
}

<#
.SYNOPSIS
Validates whether a given certificate is valid based on the hash algoritms available on the system.
.PARAMETER Thumbprint
One or more thumbprints to validate.
.PARAMETER Quiet
Returns $false if the thumbprint is not valid. By default this function throws an exception if validation fails.
.EXAMPLE
Validate-Thumbprint fd94e3a5a7991cb6ed3cd5dd01045edf7e2284de
.EXAMPLE
Validate-Thumbprint fd94e3a5a7991cb6ed3cd5dd01045edf7e2284de,0000e3a5a7991cb6ed3cd5dd01045edf7e220000 -Quiet
.EXAMPLE
gci Cert:\LocalMachine -Recurse | ? { $_.Thumbprint } | select -exp Thumbprint | Validate-Thumbprint -Verbose
#>
function Validate-Thumbprint
{
[CmdletBinding()]
param(
[Parameter(
Mandatory,
ValueFromPipeline
)]
[ValidateNotNullOrEmpty()]
[String[]]
$Thumbprint ,

[Parameter()]
[Switch]
$Quiet
)

Begin
{
$validHashes = [System.AppDomain]::CurrentDomain.GetAssemblies().GetTypes() | Where-Object {
$_.BaseType.BaseType -eq [System.Security.Cryptography.HashAlgorithm] -and
$_.Name -cmatch 'Managed$'
} | ForEach-Object {
New-Object PSObject -Property @{
Hash = $_.BaseType.Name
BitSize = (New-Object $_).HashSize
} | Add-Member -MemberType ScriptProperty -Name HexLength -Value {
$this.BitSize / 4
} -PassThru
}
}

Process
{
foreach($hash in $Thumbprint)
{
$isValid = $false

foreach($algorithm in $validHashes)
{
if ($hash -cmatch "^[a-fA-F0-9]{$($algorithm.HexLength)}$")
{
Write-Verbose -Message "'$hash' is a valid $($algorithm.Hash) hash."
$isValid = $true
}
}

if ($Quiet -or $isValid)
{
$isValid
}
else
{
throw [System.ArgumentException]"'$hash' is not a valid hash."
}
}
}
}

function Get-TargetResource
{
[CmdletBinding()]
[OutputType([Hashtable])]
param(
[Parameter(
Mandatory
)]
[ValidateScript( {
$_ | Validate-Thumbprint
} )]
[String]
$Thumbprint ,

[Parameter(
Mandatory
)]
[ValidateScript( {
$_ | Validate-PfxPath
} )]
[String]
$Path ,

[Parameter()]
[ValidateSet(
'LocalMachine'
)]
[String]
$Location = 'LocalMachine' ,

[Parameter()]
[ValidateNotNullOrEmpty()]
[String]
$Store = 'My' ,

[Parameter()]
[PSCredential]
$Credential
)

@{
Thumbprint = $Thumbprint
Path = $Path
}
}

function Test-TargetResource
{
[CmdletBinding()]
[OutputType([Bool])]
param(
[Parameter(
Mandatory
)]
[ValidateScript( {
$_ | Validate-Thumbprint
} )]
[String]
$Thumbprint ,

[Parameter(
Mandatory
)]
[ValidateScript( {
$_ | Validate-PfxPath
} )]
[String]
$Path ,

[Parameter()]
[ValidateSet(
'LocalMachine'
)]
[String]
$Location = 'LocalMachine' ,

[Parameter()]
[ValidateNotNullOrEmpty()]
[String]
$Store = 'My' ,

[Parameter()]
[bool]
$Exportable = $false ,

[Parameter()]
[PSCredential]
$Credential
)

[Bool](
'Cert:' |
Join-Path -ChildPath $Location |
Join-Path -ChildPath $Store |
Get-ChildItem |
Where-Object { $_.Thumbprint -ieq $Thumbprint }
)
}

function Set-TargetResource
{
[CmdletBinding(SupportsShouldProcess)]
param(
[Parameter(
Mandatory
)]
[ValidateScript( {
$_ | Validate-Thumbprint
} )]
[String]
$Thumbprint ,

[Parameter(
Mandatory
)]
[ValidateScript( {
$_ | Validate-PfxPath
} )]
[String]
$Path ,

[Parameter()]
[ValidateSet(
'LocalMachine'
)]
[String]
$Location = 'LocalMachine' ,

[Parameter()]
[ValidateNotNullOrEmpty()]
[String]
$Store = 'My' ,

[Parameter()]
[bool]
$Exportable = $false ,

[Parameter()]
[PSCredential]
$Credential
)

$certPath = 'Cert:' | Join-Path -ChildPath $Location | Join-Path -ChildPath $Store
if ($PSCmdlet.ShouldProcess("Importing PFX '$Path' into '$certPath'"))
{
$param = @{
Exportable = $Exportable
CertStoreLocation = $certPath
FilePath = $Path
Verbose = $VerbosePreference
}
if ($Credential)
{
$param['Password'] = $Credential.Password
}
Import-PfxCertificate @param
}
}

Export-ModuleMember *-TargetResource
10 changes: 10 additions & 0 deletions DSCResources/MSFT_xPfxImport/MSFT_xPfxImport.schema.mof
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[ClassVersion("1.0"), FriendlyName("xPfxImport")]
class MSFT_xPfxImport : OMI_BaseResource
{
[Key] string Thumbprint;
[Key] string Path;
[write,ValueMap{"LocalMachine"},Values{"LocalMachine"}] string Location;
[write] string Store;
[write] boolean Exportable;
[write,EmbeddedInstance("MSFT_Credential")] string Credential;
};
46 changes: 46 additions & 0 deletions Examples/Sample_xPfxImport_IIS_WebSite.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
Configuration MyNode
{
param(
[PSCredential]
$PfxPassword = (Get-Credential -Message 'Enter PFX extraction password.' -UserName 'Ignore')
)

Import-DscResource -ModuleName xCertificate
Import-DscResource -ModuleName xWebAdministration

Node $AllNodes.NodeName
{
WindowsFeature IIS
{
Ensure = 'Present'
Name = 'Web-Server'
}

xPfxImport CompanyCert
{
Thumbprint = 'c81b94933420221a7ac004a90242d8b1d3e5070d'
Path = '\\Server\Share\Certificates\CompanyCert.pfx'
Store = 'WebHosting'
Credential = $PfxPassword
DependsOn = '[WindowsFeature]IIS'
}

xWebsite CompanySite
{
Ensure = 'Present'
Name = 'CompanySite'
State = 'Started'
PhysicalPath = "B:\Web\CompanySite"
ApplicationPool = "CompanyPool"
BindingInfo =
MSFT_xWebBindingInformation {
Protocol = 'HTTPS'
Port = 443
CertificateThumbprint = 'c81b94933420221a7ac004a90242d8b1d3e5070d'
CertificateStoreName = 'WebHosting'
HostName = "www.example.com"
}
DependsOn = '[WindowsFeature]Web-Server','[xPfxImport]CompanyCert'
}
}
}
19 changes: 19 additions & 0 deletions Examples/Sample_xPfxImport_MinimalUsage.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
Configuration MyNode
{
param(
[PSCredential]
$PfxPassword = (Get-Credential -Message 'Enter PFX extraction password.' -UserName 'Ignore')
)

Import-DscResource -ModuleName xCertificate

Node $AllNodes.NodeName
{
xPfxImport CompanyCert
{
Thumbprint = 'c81b94933420221a7ac004a90242d8b1d3e5070d'
Path = '\\Server\Share\Certificates\CompanyCert.pfx'
Credential = $PfxPassword
}
}
}
Loading

0 comments on commit 502b82d

Please sign in to comment.