Public/Set-AtwsModuleConfiguration.ps1
<# .COPYRIGHT Copyright (c) ECIT Solutions AS. All rights reserved. Licensed under the MIT license. See https://github.com/ecitsolutions/Autotask/blob/master/LICENSE.md for license information. #> Function Set-AtwsModuleConfiguration { <# .SYNOPSIS This function updates the runtime configuration of the module. .DESCRIPTION This function updates the runtime configuration of the module. Values that can be changed while the module is loaded are: - Credentials (both username and password may be changed separately) - API key - Whether parameters with picklist values should show labels in place of numbers (ConvertPicklistIdsToLabel) - Debug preference - Verbose preference - Errorlimit - how many errors should Set-Atws* or New-Atws* functions accept before the operation is aborted The parameters Prefix and RefreshCache does not have any effect on the current connection. They must be saved and loaded as part of a later connection to have any effect. .INPUTS Nothing. .OUTPUTS Nothing. .EXAMPLE Set-AtwsModuleConfiguration -Credential $Credential -ApiTrackingIdentifier $string .NOTES NAME: Set-AtwsModuleConfiguration .LINK Get-AtwsModuleConfiguration New-AtwsModuleConfiguration Remove-AtwsModuleConfiguration Save-AtwsModuleConfiguration #> [cmdletbinding( SupportsShouldProcess = $true, ConfirmImpact = 'Medium', DefaultParameterSetName = 'Username_and_password' )] Param ( [Parameter( ParameterSetName = 'Credentials' )] [ValidateNotNullOrEmpty()] [pscredential] $Credential, [Parameter( ValueFromPipelineByPropertyName = $true, ParameterSetName = 'Username_and_password' )] [ValidateNotNullOrEmpty()] [string] $Username, [Parameter( ValueFromPipelineByPropertyName = $true, ParameterSetName = 'Username_and_password' )] [ValidateNotNullOrEmpty()] [securestring] $SecurePassword, [Parameter( ValueFromPipelineByPropertyName = $true, ParameterSetName = 'Username_and_password' )] [Parameter( ParameterSetName = 'Credentials' )] [ValidateNotNullOrEmpty()] [securestring] $SecureTrackingIdentifier, [Parameter( ValueFromPipelineByPropertyName = $true, ParameterSetName = 'Username_and_password' )] [Parameter( ParameterSetName = 'Credentials' )] [switch] $ConvertPicklistIdToLabel, [Parameter( ValueFromPipelineByPropertyName = $true, ParameterSetName = 'Username_and_password' )] [Parameter( ParameterSetName = 'Credentials' )] [ValidateScript( { # It can be empty, but if it isn't it should be max 8 characters and only letters and numbers if ($_.length -eq 0 -or ($_ -match '[a-zA-Z0-9]' -and $_.length -gt 0 -and $_.length -le 8)) { $true } else { $false } })] [string] $Prefix, [Parameter( ValueFromPipelineByPropertyName = $true, ParameterSetName = 'Username_and_password' )] [Parameter( ParameterSetName = 'Credentials' )] [switch] $RefreshCache, [Parameter( ValueFromPipelineByPropertyName = $true, ParameterSetName = 'Username_and_password' )] [Parameter( ParameterSetName = 'Credentials' )] [ValidateSet('Stop', 'Inquire', 'Continue', 'SilentlyContinue')] [string] $DebugPref, [Parameter( ValueFromPipelineByPropertyName = $true, ParameterSetName = 'Username_and_password' )] [Parameter( ParameterSetName = 'Credentials' )] [ValidateSet('Stop', 'Inquire', 'Continue', 'SilentlyContinue')] [string] $VerbosePref, [Parameter( ValueFromPipelineByPropertyName = $true, ParameterSetName = 'Username_and_password' )] [Parameter( ParameterSetName = 'Credentials' )] [ValidateRange(0, 100)] [int] $ErrorLimit, [Parameter( ValueFromPipelineByPropertyName = $true, ParameterSetName = 'Username_and_password' )] [Parameter( ParameterSetName = 'Credentials' )] [ArgumentCompleter( { param($Cmd, $Param, $Word, $Ast, $FakeBound) $(Get-ChildItem -Path $(Split-Path -Parent $profile) -Filter "*.clixml").FullName })] [ValidateScript( { Test-Path $_ })] [IO.FileInfo] $Path = $(Join-Path -Path $(Split-Path -Parent $profile) -ChildPath AtwsConfig.clixml), # Use this paramter to save to another configuration name. [Parameter( ValueFromPipelineByPropertyName = $true, ParameterSetName = 'Username_and_password' )] [Parameter( ParameterSetName = 'Credentials' )] [ArgumentCompleter( { param($Cmd, $Param, $Word, $Ast, $FakeBound) if (Test-Path $FakeBound.Path) { [IO.FileInfo]$filepath = $FakeBound.Path } else { [IO.FileInfo]$filepath = $(Join-Path -Path $(Split-Path -Parent $profile) -ChildPath AtwsConfig.clixml) } $tempsettings = Import-Clixml -Path $filepath.Fullname if ($tempsettings -is [hashtable]) { $tempsettings.keys } })] [ValidateNotNullOrEmpty()] [String] $Name = 'Default' ) begin { # Enable modern -Debug behavior if ($PSCmdlet.MyInvocation.BoundParameters['Debug'].IsPresent) { $DebugPreference = 'Continue' } else { # Respect configured preference $DebugPreference = $Script:Atws.Configuration.DebugPref } Write-Debug ('{0}: Begin of function' -F $MyInvocation.MyCommand.Name) if (!($PSCmdlet.MyInvocation.BoundParameters['Verbose'].IsPresent)) { # No local override of central preference. Load central preference $VerbosePreference = $Script:Atws.Configuration.VerbosePref } } process { # Read existing configuration from disk if (Test-Path $Path) { Try { # Try to save to the path $settings = Import-Clixml -Path $Path.Fullname } catch { $message = "{0}`nStacktrace:`n{1}" -f $_, $_.ScriptStackTrace throw (New-Object System.Configuration.Provider.ProviderException $message) return } } # Create an empty setting table if (-not ($settings -is [hashtable])) { $settings = @{} } # Get current configuration if ($Script:Atws.integrationsValue) { # We are connected. Use active configuration. $configuration = $Script:Atws.Configuration } # Not connected. Do we have an existing configuration from disk with this name? elseIf ($settings.containskey($Name)) { # Use saved configuration $configuration = $settings[$Name] } else { $message = "Not connected and no configuration by name '{0}' exists. Create a new configuration with New-AtwsModuleConfiguration. You may save it using Save-AtwsModuleConfiuguration." -f $Name throw (New-Object System.Configuration.Provider.ProviderException $message) return } foreach ($parameter in $PSBoundParameters.GetEnumerator()) { $caption = $MyInvocation.MyCommand.Name $verboseDescription = '{0}: Setting {1} to {2} as requested.' -F $caption, $parameter.key, $parameter.value $verboseWarning = '{0}: About to set {1} to {2}. Do you want to continue?' -F $caption, $parameter.key, $parameter.value if ($PSCmdlet.ShouldProcess($verboseDescription, $verboseWarning, $caption)) { # Only run code if parameter has been used switch ($parameter.key) { 'Credential' { $configuration.Username = $Credential.UserName $configuration.SecurePassword = $Credential.Password } 'Username' { $configuration.Username = $UserName } 'SecurePassword' { $configuration.SecurePassword = $SecurePassword } 'ApiTrackingIdentifier' { $configuration.SecureTrackingIdentifier = $SecureTrackingIdentifier } 'ConvertPicklistIdToLabel' { $configuration.ConvertPicklistIdToLabel = $ConvertPicklistIdToLabel.IsPresent } 'Prefix' { if ($Prefix -ne $Script:Atws.Configuration.Prefix) { Write-Warning "The module prefix cannot be changed while the module is loaded. A module reload is necessary." $Script:configuration.Prefix = $Prefix } } 'RefreshCache' { if ($Script:Atws.configuration) { $Script:Atws.configuration.RefreshCache = $RefreshCache.IsPresent } } 'DebugPref' { $DebugPreference = $DebugPref if ($Script:Atws.configuration) { $Script:Atws.configuration.DebugPref = $DebugPref } } 'VerbosePref' { $VerbosePreference = $VerbosePref if ($Script:Atws.configuration) { $Script:Atws.configuration.VerbosePref = $VerbosePref } } 'ErrorLimit' { $configuration.ErrorLimit = $ErrorLimit } } } } # Are we connected? Update current settings if ($Script:Atws.integrationsValue) { $Script:Atws.Configuration = $configuration # Prepare securestring password to be converted to plaintext $SecurePasswordString = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($configuration.SecurePassword) $Script:Atws.ClientCredentials.UserName | Add-Member -Force -NotePropertyName UserName -NotePropertyValue $configuration.Username $BSTRstring = [System.Runtime.InteropServices.Marshal]::PtrToStringBSTR($SecurePasswordString) $Script:Atws.ClientCredentials.UserName | Add-Member -Force -NotePropertyName Password -NotePropertyValue $BSTRstring # Set the integrationcode property to the API tracking identifier provided by the user $BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($Configuration.SecureTrackingIdentifier) $Script:Atws.IntegrationsValue.IntegrationCode = [System.Runtime.InteropServices.Marshal]::PtrToStringBSTR($BSTR) } else { # We loaded these settings from disk. Save to disk again. Save-AtwsModuleConfiguration -Name $Name -Configuration $configuration } } end { Write-Debug ('{0}: End of function' -F $MyInvocation.MyCommand.Name) #TODO: Introduce PipelineSupport from Get-, -Set, -New, and Save-AtwsModuleConfiguration. Not doing this for now as it works as it is, jsut requires a few more lines. # #Returning object so it can be passed to Save-AtwsModuleConfiguration # Write-Verbose ("You may use Save-AtwsModuleConfiguration to seve this configuration to disk.") # return $configuration } } |