diff --git a/Windows/Chocolatey/InstallConfigureChocolatey.ps1 b/Windows/Chocolatey/InstallConfigureChocolatey.ps1 new file mode 100644 index 0000000000000000000000000000000000000000..fb2bc3c9aecd69be96eca98e52fcd7c0c4966852 --- /dev/null +++ b/Windows/Chocolatey/InstallConfigureChocolatey.ps1 @@ -0,0 +1,255 @@ +<#============================================================================================================================= + Install and configure Chocolatey, also add a scheduled task to run "choco upgrade -y all" at computer startup and nightly +=============================================================================================================================#> + +# Start the Script +Write-Host "Starting script execution..." + +# Determine the name of the currently executing script without the extension +$scriptName = [System.IO.Path]::GetFileNameWithoutExtension($MyInvocation.MyCommand.Name) + +# Set the log file path based on the script name +$transcriptPath = "C:\Install Logs\$scriptName.log" + +# Start Transcript +Start-Transcript -Path $transcriptPath + +# Determine the directory of the currently executing script +$scriptDirectory = Split-Path -Parent $MyInvocation.MyCommand.Path + +# Load configuration +$configPath = Join-Path -Path $scriptDirectory -ChildPath "config.json" +$config = Get-Content -Path $configPath | ConvertFrom-Json + +# Function to check if a cmdlet exists +function Test-Command { + param ( + [string]$CommandName + ) + $command = Get-Command -Name $CommandName -ErrorAction SilentlyContinue + return $null -ne $command +} + +# Function to check if a Chocolatey package is installed +function Test-PackageInstalled { + param ( + [string]$PackageName + ) + $installedPackages = choco list --exact $PackageName + return $installedPackages -match "^$PackageName" +} + +# Function to check if a service exists +function Test-Service { + param ( + [string]$ServiceName + ) + return $null -ne (Get-Service -Name $ServiceName -ErrorAction SilentlyContinue) +} + +# Function to start or restart a service +function Set-ServiceState { + param ( + [string]$ServiceName + ) + $service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue + if ($service) { + if ($service.Status -eq 'Running') { + Write-Output "Restarting service: $ServiceName" + Restart-Service -Name $ServiceName -Force + } else { + Write-Output "Starting service: $ServiceName" + Start-Service -Name $ServiceName + } + } else { + Write-Output "Service $ServiceName not found." + } +} + +# Function to stop a service if it exists +function Stop-ServiceIfExists { + param ( + [string]$ServiceName + ) + if (Test-Service -ServiceName $ServiceName) { + Write-Output "Stopping service: $ServiceName" + Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue + } else { + Write-Output "Service $ServiceName not found. No action taken." + } +} + +# Function to install a Chocolatey package +function Install-ChocoPackageIfNotInstalled { + param ( + [string]$PackageName, + [switch]$ForceInstall, + [scriptblock]$PostInstallAction + ) + if (Test-PackageInstalled -PackageName $PackageName) { + Write-Output "$PackageName is already installed." + } else { + Write-Output "Installing package: $PackageName" + $installCommand = "choco install -y" + if ($ForceInstall) { + $installCommand += " --force" + } + $installCommand += " $PackageName" + Invoke-Expression $installCommand + Write-Output "$PackageName installed successfully." + if ($PostInstallAction) { + & $PostInstallAction + } + } +} + +# Function to format the configuration line +function Format-ConfigLine { + param ( + [string]$key, + [string]$value, + [bool]$commented + ) + if ($commented) { + return "# $key=$value" + } else { + return "$key=$value" + } +} + +# Check if Chocolatey is installed +if (Test-Command -CommandName "choco") { + Write-Host "Chocolatey is already installed." +} else { + # Install Chocolatey + Write-Host "Install Chocolatey." + Set-ExecutionPolicy Bypass -Scope Process -Force + [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072 + Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1')) +} + +# Check if FIPS compliant checksums are enabled +$fipsEnabled = choco feature list | Select-String -Pattern "useFipsCompliantChecksums" | Select-String -Pattern "Enabled" +if (-not $fipsEnabled) { + Write-Host "Enable FIPS compliant checksums." + powershell.exe choco feature enable -n useFipsCompliantChecksums +} else { + Write-Host "FIPS compliant checksums are already enabled." +} + +# Check if Remember Arguments for Upgrades are enabled +$rememberDisabled = choco feature list | Select-String -Pattern "useRememberedArgumentsForUpgrades" | Select-String -Pattern "Disabled" +if (-not $rememberDisabled) { + Write-Host "Disable Remember Arguments for Upgrades." + powershell.exe choco feature disable -n useRememberedArgumentsForUpgrades +} else { + Write-Host "Remember Arguments for Upgrades are already disabled." +} + +# Extract Chocolatey sources from the config file +$chocoSources = $config.ChocolateySources + +# Get the current Chocolatey source names +$currentChocoSourceNames = choco source list | Select-String -Pattern ' - ' | ForEach-Object { + $_.Line.Split(' - ')[0].Trim() +} + +# Remove current Chocolatey sources that are not in the config file +foreach ($currentSourceName in $currentChocoSourceNames) { + if ($chocoSources.name -notcontains $currentSourceName) { + Write-Host "Removing source: Name = $currentSourceName" + choco source remove -n $currentSourceName + } +} + +# Add Chocolatey sources from the config file +foreach ($source in $chocoSources) { + Write-Host "Adding source: Name = $($source.name), Source = $($source.source)" + choco source add --name $source.name --source $source.source --priority $source.priority +} + +Write-Host "Chocolatey sources have been configured." + +# Should PowerShell 7 be installed +if ($config.InstallPowerShell7) { + # Check if PowerShell 7 is installed + $pwshPath = (Get-Command pwsh -ErrorAction SilentlyContinue).Source + + if (-not $pwshPath) { + Write-Host "PowerShell 7 is not installed. Installing PowerShell 7..." + choco install powershell-core -y + # Refresh environment variables + & "$env:ChocolateyInstall\helpers\chocolateyProfile.psm1" + refreshenv + # Re-check for PowerShell 7 path + $pwshPath = (Get-Command pwsh -ErrorAction SilentlyContinue).Source + } +} + +# Should nano be installed +if ($config.InstallNano) { + Install-ChocoPackageIfNotInstalled -PackageName "nano" +} + + #Install Zabbix Agent 2 + Install-ChocoPackageIfNotInstalled -PackageName "zabbix-agent2" -ForceInstall + +if ($config.InstallZabbixAgent2) { + # Create the content for the Zabbix Agent 2 config file + $zabbixConfigPath2 = "C:\Program Files\Zabbix Agent 2\zabbix_agent2.conf" + + # Ensure the directory exists + $zabbixConfigDirectory = Split-Path -Path $zabbixConfigPath2 -Parent + if (-not (Test-Path -Path $zabbixConfigDirectory)) { + New-Item -Path $zabbixConfigDirectory -ItemType Directory -Force + } + + # Create the content for the Zabbix Agent 2 config file + $zabbixConfigContent2 = @( + "# This is a configuration file for Zabbix agent2 (on Windows)" + "# To get more information about Zabbix, visit https://www.zabbix.com" + "# First install" + "" + ) + + # Add Zabbix settings from JSON to the config content + foreach ($setting in $config.ZabbixSettings.PSObject.Properties) { + $zabbixConfigContent2 += Format-ConfigLine -key $setting.Name -value $setting.Value.value -commented $setting.Value.commented + } + + # Add static lines to the config content + $zabbixConfigContent2 += @( + "" + "Include=C:\Program Files\Zabbix Agent 2\zabbix_agent2.d\" + "# Include=c:\zabbix\zabbix_agent2.userparams.conf" + "# Include=c:\zabbix\zabbix_agent2.conf.d\" + "# Include=c:\zabbix\zabbix_agent2.conf.d\*.conf" + "ControlSocket=\\.\pipe\agent.sock" + "Include=.\zabbix_agent2.d\plugins.d\*.conf" + ) + + # Write the content to the Zabbix config files + $zabbixConfigContent2 | Out-File -FilePath $zabbixConfigPath2 -Encoding UTF8 + Write-Host "Zabbix agent2 configuration file have been updated." + + if (Test-Service -ServiceName "Zabbix Agent 2") { + # Ensure Zabbix Agent 2 service is configured to start automatically + Write-Output "Change Zabbix Agent 2 service to start automatic." + Set-Service -Name "Zabbix Agent 2" -StartupType Automatic + # Ensure Zabbix Agent 2 service have these failure actions + Write-Output "Change Zabbix Agent 2 service to restart if failure." + cmd /c 'sc failure "Zabbix Agent 2" reset=86400 actions=restart/60000/restart/60000/restart/60000' + } else { + Write-Output "Zabbix Agent 2 service not found. Error, manual action has to be taken." + } + + # Start or restart the Zabbix Agent 2 service + Start-Sleep -Seconds 5 + Set-ServiceState -ServiceName "Zabbix Agent 2" +} + +# Stop Transcript +Write-Host "Stopping transcript..." +Stop-Transcript + +Write-Host "Script execution completed." \ No newline at end of file