Skip to content

Instantly share code, notes, and snippets.

@steviecoaster
Last active August 10, 2024 18:58
Show Gist options
  • Save steviecoaster/0a2c0d4b09988dedf8e1df1844ec6b8a to your computer and use it in GitHub Desktop.
Save steviecoaster/0a2c0d4b09988dedf8e1df1844ec6b8a to your computer and use it in GitHub Desktop.
Configure Inedo ProGet for HTTPS
function Set-ProGetSslConfig {
<#
.SYNOPSIS
Updates the ProGet configuration file and restarts the ProGet services.
.DESCRIPTION
This script updates the ProGet configuration file with specified parameters, handles SSL certificate settings, and restarts the ProGet services. It processes parameters, updates the XML configuration file, and ensures the correct attributes are set.
.PARAMETER ConfigFile
Specifies the path to the ProGet configuration file. Default is 'C:\ProgramData\Inedo\SharedConfig\ProGet.config'.
.PARAMETER Location
Specifies the location of the certificate store. Valid values are 'User' and 'LocalMachine'.
.PARAMETER Store
Specifies the certificate store. Valid values are 'My', and 'Root'.
.PARAMETER Subject
Specifies the subject name of the certificate.
.PARAMETER AllowInvalid
A switch parameter that allows invalid certificates if specified.
.PARAMETER CertPassword
Specifies the password for the certificate.
.PARAMETER Urls
Specifies the URLs for the web server to bind too.
.EXAMPLE
Set-ProGetSslConfig -Location 'Machine' -Store 'My' -Subject 'example.com' -AllowInvalid -CertPassword 'password' -Urls http://*:8624/,https://*:8443/
This command updates the ProGet configuration to use a certificate with the subject 'example.com' from the specified Windows certificate store.
.EXAMPLE
Set-ProGetSslConfig -CertFile "C:\proget_cert\cert.pfx" -CertPassword ('poshacme' | ConvertTo-SecureString -AsPlainText -Force) -Urls http://*:8624/,https://*:8443/
Updates ProGet configuration to use the provided pfx file and pfx password to secure the ProGet instance. Also allows for non-http binding to port 8624
.EXAMPLE
Set-ProGetSslConfig -CertFile "C:\proget_cert\cert.pem" -KeyFile "C:\proget_cert\cert.key" -Urls http://*:8624/,https://*:8443/
Updates ProGet configuration to use the provided pem and key file to secure the ProGet instance with SSL
.NOTES
#>
[CmdletBinding()]
Param(
[Parameter(ParameterSetName = 'WindowsStore')]
[Parameter(ParameterSetName = 'CertFile')]
[Parameter(ParameterSetName = 'Pfx')]
[String]
$ConfigFile = 'C:\ProgramData\Inedo\SharedConfig\ProGet.config',
[Parameter(Mandatory, ParameterSetName = 'WindowsStore')]
[ValidateSet('User', 'LocalMachine')]
[String]
$Location,
[Parameter(Mandatory, ParameterSetName = 'WindowsStore')]
[ValidateSet('My', 'Root')]
[String]
$Store,
[Parameter(Mandatory, ParameterSetName = 'WindowsStore')]
[String]
$Subject,
[Parameter(ParameterSetName = 'WindowsStore')]
[Switch]
$AllowInvalid,
[Parameter(Mandatory, ParameterSetName = 'CertFile')]
[Parameter(Mandatory, ParameterSetName = 'Pfx')]
[ValidateScript({ Test-Path $_ })]
[String]
$CertFile,
[Parameter(ParameterSetName = 'Pfx')]
[SecureString]
$CertPassword,
[Parameter(ParameterSetName = 'CertFile')]
[ValidateScript({ Test-Path $_ })]
[String]
$KeyFile,
[Parameter(ParameterSetName = 'CertFile')]
[Parameter(ParameterSetName = 'Pfx')]
[Parameter(ParameterSetName = 'WindowsStore')]
[ValidateScript({
$_ | Foreach-object {
if ($psitem.EndsWith('/')) {
$true
}
else {
throw "Url must end with a trailing '/'!"
}
}
})]
[String[]]
$Urls = 'http://*:8624/'
)
begin {
function Set-CertAcl {
[CmdletBinding()]
Param(
[Parameter(Mandatory)]
[String]
$Subject
)
end {
$cert = Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object { $_.Subject -like "*$Subject*" }
$keyPath = "C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys\"
$unique = $cert.privatekey.CspKeyContainerInfo.UniqueKeyContainerName
$keyFile = Get-ChildItem -Path $keyPath -Recurse -Filter "*$unique*"
$acl = Get-Acl -Path $keyFile.FullName
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule("NETWORK SERVICE", "Read", "Allow")
$acl.SetAccessRule($accessRule)
Set-Acl -Path $keyFile.FullName -AclObject $acl
}
}
}
end {
#Update the configuration file
[xml]$xml = Get-Content $ConfigFile
$webServerNode = $xml.InedoAppConfig.WebServer
#Set some defaults
$webServerNode.attributes.RemoveAll()
$webServerNode.SetAttribute('Enabled', $true)
switch ($PSCmdlet.ParameterSetName) {
'WindowsStore' {
$PSBoundParameters.GetEnumerator() | ForEach-Object {
if ($_.Key -eq 'AllowInvalid') {
$webServerNode.SetAttribute($($_.Key), $([bool]$_.Value))
}
else {
$webServerNode.SetAttribute($_.Key, $_.Value)
}
}
if (-not $PSBoundParameters.ContainsKey('AllowInvalid')) {
$webServerNode.SetAttribute('AllowInvalid', $false)
}
else {
$webServerNode.SetAttribute('AllowInvalid', $AllowInvalid)
}
#Give Inedo service account permissions to cert private key
Set-CertAcl -Subject $Subject
}
'CertFile' {
$PSBoundParameters.GetEnumerator() | ForEach-Object {
if (-not ($_.Key -eq 'ConfigFile')) {
$webServerNode.SetAttribute($_.Key, $_.Value)
}
}
}
'Pfx' {
$PSBoundParameters.GetEnumerator() | ForEach-Object {
if (-not ($_.Key -eq 'ConfigFile')) {
if ($_.Key -eq 'CertPassword') {
$tempCred = [System.Management.Automation.PSCredential]::new('toss', $CertPassword)
$CleartextPassword = $tempCred.GetNetworkCredential().Password
$webServerNode.SetAttribute('Password', $CleartextPassword)
}
else {
$webServerNode.SetAttribute($_.Key, $_.Value)
}
}
}
if ($webServerNode.HasAttribute('KeyFile')) {
$webServerNode.RemoveAttribute('KeyFile')
}
}
}
#Handle port bindings
if ($urls) {
if ($Urls.Count -gt 1) {
$webServerNode.SetAttribute('Urls', $($Urls -join ';'))
}
else {
$webServerNode.SetAttribute('Urls', $Urls)
}
}
#Write the config file
$xml.Save($ConfigFile)
#Restart the ProGet services
Get-Service inedoproget* | Restart-Service
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment