DSCResources/MSFT_CertificateExport/MSFT_CertificateExport.psm1
#Requires -Version 4.0 $modulePath = Join-Path -Path (Split-Path -Path (Split-Path -Path $PSScriptRoot -Parent) -Parent) -ChildPath 'Modules' # Import the Certificate Common Modules Import-Module -Name (Join-Path -Path $modulePath ` -ChildPath (Join-Path -Path 'CertificateDsc.Common' ` -ChildPath 'CertificateDsc.Common.psm1')) # Import the Certificate Resource Helper Module Import-Module -Name (Join-Path -Path $modulePath ` -ChildPath (Join-Path -Path 'CertificateDsc.ResourceHelper' ` -ChildPath 'CertificateDsc.ResourceHelper.psm1')) # Import Localization Strings $localizedData = Get-LocalizedData ` -ResourceName 'MSFT_CertificateExport' ` -ResourcePath (Split-Path -Parent $Script:MyInvocation.MyCommand.Path) <# .SYNOPSIS Returns the current state of the exported certificate. .PARAMETER Path The path to the file you that will contain the exported certificate. #> function Get-TargetResource { [CmdletBinding()] [OutputType([Hashtable])] param ( [Parameter(Mandatory = $true)] [System.String] $Path ) Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): ", $($LocalizedData.GettingCertificateExportMessage -f $Path) ) -join '' ) $result = @{ Path = $Path IsExported = (Test-Path -Path $Path) } return $result } # end function Get-TargetResource <# .SYNOPSIS Exports the certificate. .PARAMETER Path The path to the file you that will contain the exported certificate. .PARAMETER Thumbprint The thumbprint of the certificate to export. Certificate selector parameter. .PARAMETER FriendlyName The friendly name of the certificate to export. Certificate selector parameter. .PARAMETER Subject The subject of the certificate to export. Certificate selector parameter. .PARAMETER DNSName The subject alternative name of the certificate to export must contain these values. Certificate selector parameter. .PARAMETER Issuer The issuer of the certificate to export. Certificate selector parameter. .PARAMETER KeyUsage The key usage of the certificate to export must contain these values. Certificate selector parameter. .PARAMETER EnhancedKeyUsage The enhanced key usage of the certificate to export must contain these values. Certificate selector parameter. .PARAMETER Store The Windows Certificate Store Name to search for the certificate to export from. Certificate selector parameter. Defaults to 'My'. .PARAMETER AllowExpired Allow an expired certificate to be exported. Certificate selector parameter. .PARAMETER MatchSource Causes an existing exported certificate to be compared with the certificate identified for export and re-exported if it does not match. .PARAMETER Type Specifies the type of certificate to export. Defaults to 'Cert'. .PARAMETER ChainOption Specifies the options for building a chain when exporting a PFX certificate. Defaults to 'BuildChain'. .PARAMETER Password Specifies the password used to protect an exported PFX file. .PARAMETER ProtectTo Specifies an array of strings for the username or group name that can access the private key of an exported PFX file without any password. #> function Set-TargetResource { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [System.String] $Path, [Parameter()] [System.String] $Thumbprint, [Parameter()] [System.String] $FriendlyName, [Parameter()] [System.String] $Subject, [Parameter()] [System.String[]] $DNSName, [Parameter()] [System.String] $Issuer, [Parameter()] [System.String[]] $KeyUsage, [Parameter()] [System.String[]] $EnhancedKeyUsage, [Parameter()] [System.String] $Store = 'My', [Parameter()] [System.Boolean] $AllowExpired, [Parameter()] [System.Boolean] $MatchSource, [Parameter()] [ValidateSet("Cert", "P7B", "SST", "PFX")] [System.String] $Type = 'Cert', [Parameter()] [ValidateSet("BuildChain", "EndEntityCertOnly")] [System.String] $ChainOption = 'BuildChain', [Parameter()] [System.Management.Automation.PSCredential] [System.Management.Automation.Credential()] $Password, [Parameter()] [System.String[]] $ProtectTo ) Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): ", $($LocalizedData.SettingCertificateExportMessage -f $Path) ) -join '' ) $findCertificateParameters = @{} + $PSBoundParameters $null = $findCertificateParameters.Remove('Path') $null = $findCertificateParameters.Remove('MatchSource') $null = $findCertificateParameters.Remove('Type') $null = $findCertificateParameters.Remove('ChainOption') $null = $findCertificateParameters.Remove('Password') $null = $findCertificateParameters.Remove('ProtectTo') $foundCertificates = @(Find-Certificate @findCertificateParameters) if ($foundCertificates.Count -eq 0) { # A certificate matching the specified certificate selector parameters could not be found Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): ", $($LocalizedData.CertificateToExportNotFound -f $Path, $Type, $Store) ) -join '' ) } else { $certificateToExport = $foundCertificates[0] $certificateThumbprintToExport = $certificateToExport.Thumbprint Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): ", $($LocalizedData.CertificateToExportFound -f $certificateThumbprintToExport, $Path) ) -join '' ) # Export the certificate $exportCertificateParameters = @{ FilePath = $Path Cert = $certificateToExport Force = $true } if ($Type -in @('Cert', 'P7B', 'SST')) { $exportCertificateParameters += @{ Type = $Type } Export-Certificate @exportCertificateParameters } elseif ($Type -eq 'PFX') { $exportCertificateParameters += @{ Password = $Password.Password ChainOption = $ChainOption } if ($PSBoundParameters.ContainsKey('ProtectTo')) { $exportCertificateParameters += @{ ProtectTo = $ProtectTo } } # if Export-PfxCertificate @exportCertificateParameters } # if Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): ", $($LocalizedData.CertificateExported -f $certificateThumbprintToExport, $Path, $Type) ) -join '' ) } # if } # end function Set-TargetResource <# .SYNOPSIS Tests the state of the currently exported certificate. .PARAMETER Path The path to the file you that will contain the exported certificate. .PARAMETER Thumbprint The thumbprint of the certificate to export. Certificate selector parameter. .PARAMETER FriendlyName The friendly name of the certificate to export. Certificate selector parameter. .PARAMETER Subject The subject of the certificate to export. Certificate selector parameter. .PARAMETER DNSName The subject alternative name of the certificate to export must contain these values. Certificate selector parameter. .PARAMETER Issuer The issuer of the certificate to export. Certificate selector parameter. .PARAMETER KeyUsage The key usage of the certificate to export must contain these values. Certificate selector parameter. .PARAMETER EnhancedKeyUsage The enhanced key usage of the certificate to export must contain these values. Certificate selector parameter. .PARAMETER Store The Windows Certificate Store Name to search for the certificate to export from. Certificate selector parameter. Defaults to 'My'. .PARAMETER AllowExpired Allow an expired certificate to be exported. Certificate selector parameter. .PARAMETER MatchSource Causes an existing exported certificate to be compared with the certificate identified for export and re-exported if it does not match. .PARAMETER Type Specifies the type of certificate to export. Defaults to 'Cert'. .PARAMETER ChainOption Specifies the options for building a chain when exporting a PFX certificate. Defaults to 'BuildChain'. .PARAMETER Password Specifies the password used to protect an exported PFX file. .PARAMETER ProtectTo Specifies an array of strings for the username or group name that can access the private key of an exported PFX file without any password. #> function Test-TargetResource { [CmdletBinding()] [OutputType([System.Boolean])] param ( [Parameter(Mandatory = $true)] [System.String] $Path, [Parameter()] [System.String] $Thumbprint, [Parameter()] [System.String] $FriendlyName, [Parameter()] [System.String] $Subject, [Parameter()] [System.String] $Issuer, [Parameter()] [System.String[]] $DNSName, [Parameter()] [System.String[]] $KeyUsage, [Parameter()] [System.String[]] $EnhancedKeyUsage, [Parameter()] [System.String] $Store = 'My', [Parameter()] [System.Boolean] $AllowExpired, [Parameter()] [System.Boolean] $MatchSource, [Parameter()] [ValidateSet("Cert", "P7B", "SST", "PFX")] [System.String] $Type = 'Cert', [Parameter()] [ValidateSet("BuildChain", "EndEntityCertOnly")] [System.String] $ChainOption = 'BuildChain', [Parameter()] [System.Management.Automation.PSCredential] [System.Management.Automation.Credential()] $Password, [Parameter()] [System.String[]] $ProtectTo ) Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): ", $($LocalizedData.TestingCertificateExportMessage -f $Path) ) -join '' ) $findCertificateParameters = @{} + $PSBoundParameters $null = $findCertificateParameters.Remove('Path') $null = $findCertificateParameters.Remove('MatchSource') $null = $findCertificateParameters.Remove('Type') $null = $findCertificateParameters.Remove('ChainOption') $null = $findCertificateParameters.Remove('Password') $null = $findCertificateParameters.Remove('ProtectTo') $foundCertificates = @(Find-Certificate @findCertificateParameters) if ($foundCertificates.Count -eq 0) { # A certificate matching the specified certificate selector parameters could not be found Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): ", $($LocalizedData.CertificateToExportNotFound -f $Path, $Type, $Store) ) -join '' ) return $true } else { $certificateToExport = $foundCertificates[0] $certificateThumbprintToExport = $certificateToExport.Thumbprint Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): ", $($LocalizedData.CertificateToExportFound -f $certificateThumbprintToExport, $Path) ) -join '' ) if (Test-Path -Path $Path) { if ($MatchSource) { # The certificate has already been exported, but we need to make sure it matches Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): ", $($LocalizedData.CertificateAlreadyExportedMatchSource -f $certificateThumbprintToExport, $Path) ) -join '' ) # Need to now compare the existing exported cert content with the found cert $exportedCertificate = New-Object -TypeName 'System.Security.Cryptography.X509Certificates.X509Certificate2Collection' if ($Type -in @('Cert', 'P7B', 'SST')) { $exportedCertificate.Import($Path) } elseif ($Type -eq 'PFX') { $exportedCertificate.Import($Path, $Password.GetNetworkCredential().Password, [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::PersistKeySet) } # if if ($certificateThumbprintToExport -notin $exportedCertificate.Thumbprint) { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): ", $($LocalizedData.CertificateAlreadyExportedNotMatchSource -f $certificateThumbprintToExport, $Path) ) -join '' ) return $false } # if } else { # This certificate is already exported and we don't want to check it is # the right certificate. Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): ", $($LocalizedData.CertificateAlreadyExported -f $certificateThumbprintToExport, $Path) ) -join '' ) } # if return $true } else { # The found certificate has not been exported yet Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): ", $($LocalizedData.CertificateNotExported -f $certificateThumbprintToExport, $Path) ) -join '' ) return $false } # if } # if } # end function Test-TargetResource Export-ModuleMember -Function *-TargetResource |