From 6e96ba8908706770fe7e4eee125ea24fdfdc8bed Mon Sep 17 00:00:00 2001 From: daniel-merchant Date: Thu, 7 Mar 2024 14:23:24 +0000 Subject: [PATCH] New-DbaComputerCertificate, options for Algorithm and Period validity (#9264) Co-authored-by: Daniel Merchant --- public/New-DbaComputerCertificate.ps1 | 20 +++++++++++++-- tests/New-DbaComputerCertificate.Tests.ps1 | 30 +++++++++++++++++++++- 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/public/New-DbaComputerCertificate.ps1 b/public/New-DbaComputerCertificate.ps1 index 2df62deff5..a03dff9fe4 100644 --- a/public/New-DbaComputerCertificate.ps1 +++ b/public/New-DbaComputerCertificate.ps1 @@ -78,6 +78,12 @@ function New-DbaComputerCertificate { .PARAMETER SelfSigned Creates a self-signed certificate. All other parameters can still apply except CaServer and CaName because the command does not go and get the certificate signed. + .PARAMETER HashAlgorithm + Specifies hashing algorithm for self-signed certificate. Must be one of the values Sha256, sha384, sha512, sha1, md5, md4, md2. + + .PARAMETER MonthsValid + Allows you to specify the number of months a self-signed certificate will be valid for. e.g a value of 60 will generate a certificate vaild until 5 years (60 months) time. + .PARAMETER EnableException By default, when something goes wrong we try to catch it, interpret it and give you a friendly warning message. This avoids overwhelming you with "sea of red" exceptions, but is inconvenient because it basically disables advanced scripting. @@ -129,6 +135,11 @@ function New-DbaComputerCertificate { Creates a self-signed certificate + .EXAMPLE + PS C:\> New-DbaComputerCertificate -SelfSigned -HashAlgorithm Sha256 -MonthsValid 60 + + Creates a self-signed certificate using the SHA256 hashing algorithm that does not expire for 5 years + #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = "Low")] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseOutputTypeCorrectly", "", Justification = "PSSA Rule Ignored by BOH")] @@ -150,7 +161,10 @@ function New-DbaComputerCertificate { [string[]]$Flag = @("Exportable", "PersistKeySet"), [string[]]$Dns, [switch]$SelfSigned, - [switch]$EnableException + [switch]$EnableException, + [ValidateSet("Sha256", "sha384", "sha512", "sha1", "md5", "md4", "md2")] + [string]$HashAlgorithm = "sha1", + [int]$MonthsValid = 12 ) begin { if ("NonExportable" -in $Flag) { @@ -338,6 +352,9 @@ function New-DbaComputerCertificate { } else { Add-Content $certCfg "RequestType = PKCS10" } + Add-Content $certCfg "NotBefore = $((get-date).ToShortDateString())" + Add-Content $certCfg "NotAfter = $((get-date).AddMonths($MonthsValid).ToShortDateString())" + Add-Content $certCfg "HashAlgorithm = $HashAlgorithm" Add-Content $certCfg "KeyUsage = 0xa0" Add-Content $certCfg "[EnhancedKeyUsageExtension]" Add-Content $certCfg "OID=1.3.6.1.5.5.7.3.1" @@ -345,7 +362,6 @@ function New-DbaComputerCertificate { Add-Content $certCfg $san Add-Content $certCfg "Critical=2.5.29.17" - if ($PScmdlet.ShouldProcess("local", "Creating certificate for $computer")) { Write-ProgressHelper -StepNumber ($stepCounter++) -Message "Running: certreq -new $certCfg $certCsr" $create = certreq -new $certCfg $certCsr diff --git a/tests/New-DbaComputerCertificate.Tests.ps1 b/tests/New-DbaComputerCertificate.Tests.ps1 index 6f86ec5fdc..b687688818 100644 --- a/tests/New-DbaComputerCertificate.Tests.ps1 +++ b/tests/New-DbaComputerCertificate.Tests.ps1 @@ -5,7 +5,7 @@ Write-Host -Object "Running $PSCommandPath" -ForegroundColor Cyan Describe "$CommandName Unit Tests" -Tag 'UnitTests' { Context "Validate parameters" { [object[]]$params = (Get-Command $CommandName).Parameters.Keys | Where-Object { $_ -notin ('whatif', 'confirm') } - [object[]]$knownParameters = 'ComputerName', 'Credential', 'CaServer', 'CaName', 'ClusterInstanceName', 'SecurePassword', 'FriendlyName', 'CertificateTemplate', 'KeyLength', 'Store', 'Folder', 'Flag', 'Dns', 'SelfSigned', 'EnableException' + [object[]]$knownParameters = 'ComputerName', 'Credential', 'CaServer', 'CaName', 'ClusterInstanceName', 'SecurePassword', 'FriendlyName', 'CertificateTemplate', 'KeyLength', 'Store', 'Folder', 'Flag', 'Dns', 'SelfSigned', 'EnableException', "HashAlgorithm", "MonthsValid" $knownParameters += [System.Management.Automation.PSCmdlet]::CommonParameters It "Should only contain our specific parameters" { (@(Compare-Object -ReferenceObject ($knownParameters | Where-Object { $_ }) -DifferenceObject $params).Count ) | Should Be 0 @@ -13,6 +13,7 @@ Describe "$CommandName Unit Tests" -Tag 'UnitTests' { } } +#Tests do not run in appveyor if (-not $env:appveyor) { Describe "$CommandName Integration Tests" -Tags "IntegrationTests" { Context "Can generate a new certificate" { @@ -28,6 +29,33 @@ if (-not $env:appveyor) { It "returns the right FriendlyName" { "$($cert.FriendlyName)" -match 'SQL Server' | Should Be $true } + It "Returns the right default encryption algorithm" { + "$(($cert | select-object @{n="SignatureAlgorithm";e={$_.SignatureAlgorithm.FriendlyName}})).SignatureAlgorithm)" -match 'sha1RSA' | Should Be $true + } + It "Returns the right default one year expiry date" { + $cert.NotAfter -match ((Get-Date).Date).AddMonths(12) | Should Be $true + } + } + } +} + + +#Tests do not run in appveyor +if (-not $env:appveyor) { + Describe "$CommandName Integration Tests" -Tags "IntegrationTests" { + Context "Can generate a new certificate with correct settings" { + BeforeAll { + $cert = New-DbaComputerCertificate -SelfSigned -HashAlgorithm "Sha256" -MonthsValid 60 -EnableException + } + AfterAll { + Remove-DbaComputerCertificate -Thumbprint $cert.Thumbprint -Confirm:$false + } + It "Returns the right encryption algorithm" { + "$(($cert | select-object @{n="SignatureAlgorithm";e={$_.SignatureAlgorithm.FriendlyName}})).SignatureAlgorithm)" -match 'sha256RSA' | Should Be $true + } + It "Returns the right five year (60 month) expiry date" { + $cert.NotAfter -match ((Get-Date).Date).AddMonths(60) | Should Be $true + } } } } \ No newline at end of file