Private/Export-PluginArgs.ps1
function Export-PluginArgs { [CmdletBinding()] param( [Parameter(Mandatory,Position=0)] [hashtable]$PluginArgs, [Parameter(Mandatory,Position=1)] [string[]]$DnsPlugin, [PSTypeName('PoshACME.PAAccount')]$Account ) # In this function, we're trying to merge the specified plugin args with the existing set # of saved plugin arg data on disk. But some plugins have parameter sets that can # end up causing AmbiguousParameterSet errors if we just naively merge all new args. # So essentially what we're going to do is this for each specified plugin: # - query all supported args # - if any $PluginArgs match # - check for saved plugin args that match and remove them # - add the new args to the saved data # # This should allow you to do something like add names to an existing cert where the new names # utilize a different plugin than the previous ones and only need to specify the new plugin's # parameters in $PluginArgs. # make sure any account passed in is actually associated with the current server # or if no account was specified, that there's a current account. if (-not $Account) { if (-not ($Account = Get-PAAccount)) { throw "No Account parameter specified and no current account selected. Try running Set-PAAccount first." } } else { if ($Account.id -notin (Get-PAAccount -List).id) { throw "Specified account id $($Account.id) was not found in the current server's account list." } } # build the path to the existing plugin data file and import it $pDataFile = Join-Path (Join-Path (Get-DirFolder) $Account.id) 'plugindata.xml' if (Test-Path -Path $pDataFile -PathType Leaf) { # import the existing file Write-Debug "Loading saved plugin data" $pData = Import-CliXml $pDataFile } else { # nothing previously saved, so just use an empty hashtable $pData = @{} } # define the set of parameter names to ignore $ignoreParams = @('RecordName','TxtValue') + [Management.Automation.PSCmdlet]::CommonParameters + [Management.Automation.PSCmdlet]::OptionalCommonParameters # $DnsPlugin will most often come with duplicates after being called from Submit-ChallengeValidation # So grab just the unique set. $uniquePlugins = $DnsPlugin | Sort-Object -Unique # loop through the unique set of plugins foreach ($plugin in $uniquePlugins) { # dot source the plugin file try { . (Join-Path $PSScriptRoot "..\DnsPlugins\$plugin.ps1") } catch { throw } # check for the add command that should exist now $addCmdName = "Add-DnsTxt$Plugin" if (-not ($cmd = Get-Command $addCmdName -ErrorAction SilentlyContinue)) { throw "Expected plugin command $addCmdName not found." } # grab the set of non-common param names $paramNames = $cmd.Parameters.Keys | Where-Object { ($_ -notin $ignoreParams) -and ($true -notin $cmd.Parameters[$_].Attributes.ValueFromRemainingArguments) } $hasNewArgs = $(foreach ($key in $PluginArgs.Keys) { if ($key -in $paramNames) { $true; break; } }) -eq $true if ($hasNewArgs) { Write-Debug "New args for $plugin found." # check for and remove old args foreach ($key in @($pData.Keys)) { if ($key -in $paramNames) { Write-Debug "Removing old value for $key" $pData.Remove($key) } } } else { Write-Debug "No new args for $plugin" } } # merge the new args with old data foreach ($key in $PluginArgs.Keys) { Write-Debug "Adding new value for $key" $pData.$key = $PluginArgs.$key } # export the merged object $pData | Export-Clixml $pDataFile -Force -EA Stop } |