Skip to content

Commit

Permalink
(chocolatey#240) Parameterize setup
Browse files Browse the repository at this point in the history
This script adds parameterization to the ClientSetup.ps1 script that is
hosted within the Nexus repository. It also adds parameterization to the
registration script that is executed on a client so you can customize the
installation.
  • Loading branch information
steviecoaster committed Dec 4, 2024
1 parent 7865b78 commit 8ceddd5
Show file tree
Hide file tree
Showing 2 changed files with 255 additions and 22 deletions.
167 changes: 154 additions & 13 deletions scripts/ClientSetup.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ param(
# The credential necessary to access the internal Nexus repository. This can
# be ignored if Anonymous authentication is enabled.
# This parameter will be necessary if your C4B server is web-enabled.
[Parameter()]
[Parameter(Mandatory)]
[pscredential]
$Credential,

Expand All @@ -41,19 +41,38 @@ param(

# Client salt value used to populate the centralManagementClientCommunicationSaltAdditivePassword
# value in the Chocolatey config file
[Parameter()]
[Parameter(Mandatory)]
[string]
$ClientSalt,

# Server salt value used to populate the centralManagementServiceCommunicationSaltAdditivePassword
# value in the Chocolatey config file
[Parameter()]
[Parameter(Mandatory)]
[string]
$ServiceSalt,

# Allows for the application of user-defined configuration that is applied after the base configuration.
# Can override base configuration with this parameter
[Parameter()]
[Hashtable[]]
$AdditionalConfiguration,

# Allows for the toggling of additonal features that is applied after the base configuration.
# Can override base configuration with this parameter
[Parameter()]
[Hashtable[]]
$AdditionalFeatures,

# Allows for the installation of additional packages after the system base packages have been installed.
[Parameter()]
[Switch]
$InternetEnabled
[Hashtable[]]
$AdditionalPackages,

# Allows for the addition of alternative sources after the base conifguration has been applied.
# Can override base configuration with this parameter
[Parameter()]
[Hashtable[]]
$AdditionalSources
)

Set-ExecutionPolicy Bypass -Scope Process -Force
Expand All @@ -69,11 +88,14 @@ $params = @{

if (-not $IgnoreProxy) {
if ($ProxyUrl) {
$proxy = [System.Net.WebProxy]::new($ProxyUrl, $true <#bypass on local#>)
$params.Add('ProxyUrl', $ProxyUrl)
}

if ($ProxyCredential) {
$params.Add('ProxyCredential', $ProxyCredential)
$proxy.Credentials = $ProxyCredential

}
}

Expand All @@ -87,7 +109,8 @@ $NupkgUrl = if (-not $ChocolateyVersion) {
$QueryUrl = ($RepositoryUrl.TrimEnd('/index.json'), "v3/registration/Chocolatey/index.json") -join '/'
$Result = $webClient.DownloadString($QueryUrl) | ConvertFrom-Json
$Result.items.items[-1].packageContent
} else {
}
else {
# Otherwise, assume the URL
"$($RepositoryUrl.TrimEnd('/index.json'))/v3/content/chocolatey/$($ChocolateyVersion)/chocolatey.$($ChocolateyVersion).nupkg"
}
Expand Down Expand Up @@ -118,13 +141,8 @@ choco config set commandExecutionTimeoutSeconds 14400
# Nexus NuGet V3 Compatibility
choco feature disable --name="'usePackageRepositoryOptimizations'"

if ($InternetEnabled) {
choco source add --name="'ChocolateyInternal'" --source="'$RepositoryUrl'" --allow-self-service --user="'$($Credential.UserName)'" --password="'$($Credential.GetNetworkCredential().Password)'" --priority=1
}
else {
choco source add --name="'ChocolateyInternal'" --source="'$RepositoryUrl'" --allow-self-service --priority=1
}

#Environment base Source configuration
choco source add --name="'ChocolateyInternal'" --source="'$RepositoryUrl'" --allow-self-service --user="'$($Credential.UserName)'" --password="'$($Credential.GetNetworkCredential().Password)'" --priority=1
choco source disable --name="'Chocolatey'"
choco source disable --name="'chocolatey.licensed'"

Expand Down Expand Up @@ -158,3 +176,126 @@ if ($ServiceSalt) {
}
choco feature enable --name="'useChocolateyCentralManagement'"
choco feature enable --name="'useChocolateyCentralManagementDeployments'"


Write-Host "Applying user supplied configuration" -ForegroundColor Cyan
#How we call choco from here changes as we need to be more dynamic with thingsii .
if ($AdditionalConfiguration) {
<#
We expect to pass in a hashtable with configuration information with the following shape:
@{
Name = BackgroundServiceAllowedCommands
Value = 'install,upgrade,uninstall'
}
#>
foreach ($conf in $AdditionalConfiguration) {
$c = [System.Collections.Generic.list[string]]::new()
$c.Add('config')
$c.Add('set')
$c.Add("--name='$($conf.Name)'")
$c.Add("--value='$($conf.Value)'")

& choco @c

}
}

if ($AdditionalFeatures) {
<#
We expect to pass in feature information as a hashtable with the following shape:
@{
Name = useBackgroundservice
State = 'Enabled'
}
#>
foreach ($feature in $AdditionalFeatures) {

$c = [System.Collections.Generic.list[string]]::new()
$c.Add('feature')

$state = switch ($feature['State']) {
'Enabled' { 'enable' }
'Disabled' { 'disable' }
default { Write-Error 'State must be either Enabled or Disabled' }
}

$c.Add($state)
$c.add("--name='$($feature.Name)'")
& choco @c
}
}

if ($AdditionalSources) {

<#
We expect a user to pass in a hashtable with source information with the folllowing shape:
@{
Name = 'MySource'
Source = 'https://nexus.fabrikam.com/repository/MyChocolateySource'
#Optional items
Credentials = $MySourceCredential
AllowSelfService = $true
AdminOnly = $true
BypassProxy = $true
Priority = 10
Certificate = 'C:\cert.pfx'
CertificatePassword = 's0mepa$$'
}
#>
Foreach ($a in $AdditionalSources) {
$c = [System.Collections.Generic.List[string]]::new()
#Required items
$c.Add('source')
$c.Add('add')
$c.Add("--name='$($a.Name)'")
$c.Add("--source='$($a.Source)'")

#Add credentials if source has them
if ($a.ContainsKey('Credentials')) {
$c.Add("--user='$($a.Credentials.Username)'")
$c.Add("--password='$($a.Credentials.GetNetworkCredential().Password)'")
}

switch ($true) {
$a['AllowSelfService'] { $c.add('--allow-self-service') }
$a['AdminOnly'] { $c.Add('--admin-only') }
$a['BypassProxy'] { $c.Add('--bypass-proxy') }
$a.ContainsKey('Priority') { $c.Add("--priority='$($a.Priority)'") }
$a.ContainsKey('Certificate') { $c.Add("--cert='$($a.Certificate)'") }
$a.ContainsKey('CerfificatePassword') { $c.Add("--certpassword='$($a.CertificatePassword)'") }
}


}


}

if ($AdditionalPackages) {

<#
We expect to pass in a hashtable with package information with the following shape:
@{
Id = 'firefox'
#Optional
Version = 123.4.56
Pin = $true
}
#>
foreach ($package in $AdditionalPackages.GetEnumerator()) {

$c = [System.Collections.Generic.list[string]]::new()
$c.add('install')
$c.add($package['Id'])

switch ($true) {
$package.ContainsKey('Version') { $c.Add("--version='$($package.version)'") }
$package.ContainsKey('Pin') { $c.Add('--pin') }
}

& choco @c
}
}
110 changes: 101 additions & 9 deletions scripts/Register-C4bEndpoint.ps1
Original file line number Diff line number Diff line change
@@ -1,12 +1,104 @@
# Here is a script you can run to setup your endpoints to connect to the C4B Server.
# This includes:
# - Installing Chocolatey
# - Installing your chocolatey-license
# - Running the Client Setup, which sets up Nexus repo and CCM acccess
[CmdletBinding()]
Param(
# The DNS name of the server that hosts your repository, Jenkins, and Chocolatey Central Management
[Parameter()]
[String]
$Fqdn = '{{ FQDN }}',

$HostName = {{hostname}} #This needs to be the same hostname as the CN/Subject of your SSL cert
# Client salt value used to populate the centralManagementClientCommunicationSaltAdditivePassword
# value in the Chocolatey config file
[Parameter()]
[String]
$ClientCommunicationSalt = '{{ ClientSaltValue }}',

# placeholder if using a self-signed cert
# Server salt value used to populate the centralManagementServiceCommunicationSaltAdditivePassword
# value in the Chocolatey config file
[Parameter()]
[String]
$ServiceCommunicationSalt = '{{ ServiceSaltValue }}',

$downloader = New-Object -TypeName System.Net.WebClient
Invoke-Expression ($downloader.DownloadString("https://$($HostName):8443/repository/choco-install/ClientSetup.ps1"))
[Parameter(Mandatory)]
[PSCredential]
$RepositoryCredential,

# The URL of a proxy server to use for connecting to the repository.
[Parameter()]
[String]
$ProxyUrl,
# The credentials, if required, to connect to the proxy server.
[Parameter()]
[PSCredential]
$ProxyCredential,

# Allows for the application of user-defined configuration that is applied after the base configuration.
# Can override base configuration with this parameter
[Parameter()]
[Hashtable[]]
$AdditionalConfiguration,

# Allows for the toggling of additonal features that is applied after the base configuration.
# Can override base configuration with this parameter
[Parameter()]
[Hashtable[]]
$AdditionalFeatures,

# Allows for the installation of additional packages after the system base packages have been installed.
[Parameter()]
[Hashtable[]]
$AdditionalPackages,

# Allows for the addition of alternative sources after the base conifguration has been applied.
# Can override base configuration with this parameter
[Parameter()]
[Hashtable[]]
$AdditionalSources
)

# Touch NOTHING below this line
$RepositoryUrl = "https://$($fqdn):8443/repository/ChocolateyInternal/index.json"

#Initialize params hashtable so we can add to it if needed later
$params = @{
Credential = $RepositoryCredential
ClientSalt = $ClientCommunicationSalt
ServiceSalt = $ServiceCommunicationSalt
RepositoryUrl = $RepositoryUrl
}

switch ($true) {
$PSBoundParameters.ContainsKey('AdditionalConfiguration') {
$params.Add('AdditionalConfiguration', $AdditionalConfiguration)
}
$PSBoundParameters.ContainsKey('AdditionalFeatures') {
$params.add('AdditionalFeatures', $AdditionalFeatures)
}

$PSBoundParameters.ContainsKey('AdditionalPackages') {
$params.Add('AdditionalPackages', $AdditionalPackages)
}

$PSBoundParameters.ContainsKey('AdditionalSources') {
$params.Add('AdditionalSources', $AdditionalSources)
}
}

$downloader = [System.Net.WebClient]::new()

#setup proxy if required
if ($ProxyUrl) {
$params.add('ProxyUrl', $ProxyUrl)
$proxy = [System.Net.WebProxy]::new($ProxyUrl, $true <#bypass on local#>)

if ($ProxyCredential) {
$params.Add('ProxyCredential', $ProxyCredential)
$proxy.Credentials = $ProxyCredential
}

$downloader.Proxy = $proxy
}

$downloader.Credentials = $RepositoryCredential

$script = $downloader.DownloadString("https://$($FQDN):8443/repository/choco-install/ClientSetup.ps1")

& ([scriptblock]::Create($script)) @params

0 comments on commit 8ceddd5

Please sign in to comment.