functions/_Set-VariableFromEnvVar.ps1
# <copyright file="Set-VariableFromEnvVar.ps1" company="Endjin Limited"> # Copyright (c) Endjin Limited. All rights reserved. # </copyright> <# .SYNOPSIS Updates the value of a variable based on the value of an environment variable. .DESCRIPTION Supports updating typed PowerShell variables using the string value from an environment variable. The PowerShell variable must already be defined for this function to udpate its value. Specific support is included for casting 'boolean' and 'hashtable' types, other types rely on the underlying casting support in PowerShell (e.g. integers). Hashtable variables can be overridden via an environment variable containing a JSON object definition. .EXAMPLE PS C:\> $MyVar = 1 PS C:\> $MyVar.GetType() IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True Int32 System.ValueType PS C:\> $env:SomeEnvVar = "50" PS C:\> $($env:SomeEnvVar).GetType() IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True String System.Object PS C:\> Set-VariableFromEnvVar -VariableName "MyVar" -EnvironmentVariableName "SomeEnvVar" True PS C:\> Write-Host $MyVar 50 PS C:\> $MyVar.GetType() IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True Int32 System.ValueType .PARAMETER VariableName The name of the PowerShell variable that will be updated. .PARAMETER EnvironmentVariableName The name of the environment variable that holds the new value. .PARAMETER UseGlobalScope When true the variable will be updated in the 'global' scope, otherwise the 'script' scope will be used. Ref: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_scopes .OUTPUTS Returns $true if the variable was updated, otherwise returns $false #> function Set-VariableFromEnvVar { [CmdletBinding()] [OutputType([bool])] param ( [Parameter(Mandatory=$true)] [string] $VariableName, [Parameter(Mandatory=$true)] [string] $EnvironmentVariableName, [switch] $UseGlobalScope ) if ( !(Test-Path variable:/$VariableName) ) { Write-Warning "Unable to override the variable '$VariableName' as it is not currently defined - skipping" return $false } $envVar = Get-Item env:/$EnvironmentVariableName # get the type of the existing value of the variable, defaulting to 'string' if null $existingValue = (Get-Variable -Name $VariableName).Value $varType = $existingValue ? $existingValue.GetType() : "".GetType() # Update the value of the variable, ensuring that the existing type is preserved and # the string value from the environment variable is cast/coerced/converted accordingly. switch ($varType.Name) { "Boolean" { # booleans require special handling, due to '-as' not always behaving as required # e.g. "false" -as [boolean] returns 'True' $varValue = [System.Convert]::ToBoolean($envVar.Value) } "Hashtable" { # support deserializing a JSON string into a hashtable try { $varValue = $envVar.Value | ConvertFrom-Json -AsHashtable } catch { Write-Warning "Unable to process environment variable '$($envVar.Name)' - the value was not valid JSON" return $false } } default { $varValue = $envVar.Value -as $varType } } Write-Verbose "Overriding '$VariableName' from environment variable [Type=$($varType.Name)]" Set-Variable -Scope ($UseGlobalScope ? "global" : "script") -Name $VariableName -Value $varValue return $true } |