Public/Update-cChocoExSourceFile.ps1
<#
.SYNOPSIS Updates or removes a Chocolatey source in a cChocoEx source configuration file. .DESCRIPTION This function allows you to add, update, or remove Chocolatey sources in a cChocoEx source configuration file. It can modify existing sources or add new ones, and it ensures that the resulting file is properly formatted. .PARAMETER Path The path to the cChocoEx source configuration file. .PARAMETER Name The name of the Chocolatey source to update or remove. .PARAMETER Ensure Specifies whether the source should be present or absent. Default is 'Present'. .PARAMETER Source The URL or path of the Chocolatey source. .PARAMETER Priority The priority of the source. Lower numbers have higher priority. .PARAMETER User The username for authenticated sources. .PARAMETER Password The password for authenticated sources. .PARAMETER Keyfile The path to the keyfile for authenticated sources. .PARAMETER VPN Indicates whether a VPN is required to access the source. .PARAMETER Remove Switch to remove the specified source from the configuration file. .EXAMPLE Update-cChocoExSourceFile -Path 'C:\ProgramData\cChocoEx\config\sources.psd1' -Name 'chocolatey' -Source 'https://chocolatey.org/api/v2/' -Priority 0 This example updates or adds the 'chocolatey' source in the specified configuration file. .EXAMPLE Update-cChocoExSourceFile -Path 'C:\ProgramData\cChocoEx\config\sources.psd1' -Name 'internal' -Remove This example removes the 'internal' source from the specified configuration file. .NOTES This function requires the PSScriptAnalyzer module for formatting the output file. .LINK https://github.com/jyonke/cChocoEx #> function Update-cChocoExSourceFile { [CmdletBinding(DefaultParameterSetName = 'Present')] param ( # Path [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [Alias('FullName')] [string[]] $Path, # Name [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [string] $Name, # Ensure [Parameter(ParameterSetName = 'Present')] [Parameter(ParameterSetName = 'Absent')] [ValidateSet('Present', 'Absent')] [string] $Ensure = 'Present', # Source [Parameter(Mandatory = $true, ParameterSetName = 'Present')] [string] $Source, # Priority [Parameter(Mandatory = $false, ParameterSetName = 'Present')] [System.Nullable[int]] $Priority, # User [Parameter(Mandatory = $false, ParameterSetName = 'Present')] [string] $User, # Password [Parameter(Mandatory = $false, ParameterSetName = 'Present')] [string] $Password, # Keyfile [Parameter(Mandatory = $false, ParameterSetName = 'Present')] [string] $Keyfile, # VPN [Parameter(Mandatory = $false, ParameterSetName = 'Present')] [Nullable[boolean]] $VPN = $null, # Remove [Parameter(Mandatory = $false, ParameterSetName = 'Remove')] [switch] $Remove ) begin { } process { #Create Data Object and Ensure it is valid try { Install-PSScriptAnalyzer $FullName = Get-Item $Path | Select-Object -ExpandProperty FullName [array]$Data = Get-cChocoExSource -Path $FullName | Select-Object * -ExcludeProperty Path } catch { Write-Error $_.Exception.Message continue } #Remove Source if ($Remove) { Write-Verbose "Removing Source $Name" $Data = $Data | ForEach-Object { if (-Not($PSItem.Name -eq $Name)) { $PSItem } } } #Add/Update Source if (-not($Remove)) { #Update Object Write-Verbose "Filtering $($Data.Count) sources on source $Name" $SourceObject = $Data | Where-Object { $PSItem.Name -eq $Name } if (($SourceObject | Measure-Object).Count -eq 1) { Write-Verbose "Updating source $Name" $SourceObject.Ensure = $Ensure $SourceObject.Source = $Source $SourceObject.VPN = $VPN $SourceObject.Priority = $Priority $SourceObject.User = $User $SourceObject.Password = $Password $SourceObject.Keyfile = $Keyfile } if (($SourceObject | Measure-Object).Count -gt 1) { throw "Multiple packages found for Name $Name" continue } if (($SourceObject | Measure-Object).Count -lt 1) { Write-Verbose "Adding source $Name" $Data += [PSCustomObject]@{ Name = $Name Ensure = $Ensure Source = $Source VPN = $VPN Priority = $Priority User = $User Password = $Password Keyfile = $Keyfile } } } #Remove NULL Properties $DataF = foreach ($Item in $Data) { $Properties = $Item.PSObject.Properties.Name.Where{ ![string]::IsNullOrWhiteSpace($Item.$_) } $Item | Select-Object -Property $Properties } #Create Temporary File $TMPFile = New-TemporaryFile #Generate File Data Add-Content -Path $TMPFile.FullName -Value '@{' foreach ($Item in ($DataF | Sort-Object -Property Name)) { $Properties = $Item.PSObject.Properties.Name $Description = "$($Item.Name)" Add-Content -Path $TMPFile.FullName -Value "`"$Description`" = @{" #Build properties and account for both single and double quote usage foreach ($Property in $Properties) { Write-Verbose "Formatting Property $Property" #Strings if ($Property -match 'Name|Ensure|Source|User|Password|Keyfile') { Add-Content -Path $TMPFile.FullName -Value "$Property = `'$($Item.$Property)`'" continue } #Boolean if ($Property -match 'VPN') { switch -Wildcard ($Item.$Property) { 'True' { Add-Content -Path $TMPFile.FullName -Value "$Property = `$true" } 'False' { Add-Content -Path $TMPFile.FullName -Value "$Property = `$false" } } continue } #Integer if ($Property -match 'Priority') { Add-Content -Path $TMPFile.FullName -Value "$Property = $($Item.$Property)" continue } } Add-Content -Path $TMPFile.FullName -Value '}' } Add-Content -Path $TMPFile.FullName -Value '}' #Validate File Structure, Format and Update File try { $null = Get-cChocoExSource -Path $TMPFile.FullName Invoke-Formatter -ScriptDefinition (Get-Content $TMPFile.FullName -Raw) | Set-Content $Path -Force } catch { Write-Error $_.Exception.Message } finally { #Remove Temp File Remove-Item $TMPFile.FullName -Force } } end { } } |