EnvVar.psm1
$Win32 = Add-Type -Namespace "EnvVar.Import" -Name "Win32" -PassThru -MemberDefinition @"
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] public static extern IntPtr SendMessageTimeout( IntPtr hWnd, uint Msg, UIntPtr wParam, string lParam, uint fuFlags, uint uTimeout, out UIntPtr lpdwResult ); [DllImport("kernel32.dll")] public static extern uint GetLastError(); "@ function Get-EnvPath { param ( [Parameter(Mandatory)] [System.EnvironmentVariableTarget] $Scope ) switch ($Scope) { "Process" { return "Env:" } "User" { return "HKCU:\Environment" } "Machine" { return "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" } Default { return } } } function New-EnvVar-Object { param ( [Parameter(Mandatory)] [ValidatePattern("[^=]+")] $Name, [Parameter()] [AllowNull()] [String] $Value, [Parameter(Mandatory)] [System.EnvironmentVariableTarget] $Scope, [Parameter()] [AllowNull()] [ValidateSet("String", "ExpandString", $null)] [String] $ValueType, [Parameter()] [AllowNull()] [String] $BeforeExpansion ) begin { } process { $obj = [PSCustomObject]@{ Name = $Name Value = $Value Scope = $Scope ValueType = $ValueType BeforeExpansion = $BeforeExpansion } $obj | Add-Member ScriptMethod ToString { $this.Value } -Force return $obj } end { } } function Update-EnvVarSetting { param ( ) begin { } process { $HWND_BROADCAST = [IntPtr] 0xffff $WM_SETTINGCHANGE = 0x1a $result = [UIntPtr]::Zero $ret = $Win32::SendMessageTimeout( $HWND_BROADCAST, $WM_SETTINGCHANGE, [UIntPtr]::Zero, "Environment", 2, 5000, [ref] $result ) if ($ret -eq 0) { $errorcode = $Win32::GetLastError($ret) Write-Error "failed to update environment setting (error code: $errorcode)" } } end { } } <# .SYNOPSIS Gets the environment variable for given name and scope. .EXAMPLE Get-EnvironmentVariable -Name SOME_ENVVAR -Scope Process #> function Get-EnvironmentVariable { [CmdletBinding()] param ( # Name of the environment variable [Parameter(Position = 0, Mandatory)] [ValidatePattern("[^=]+")] [String] $Name, # Scope of the environment variable [Parameter()] [System.EnvironmentVariableTarget] $Scope = [System.EnvironmentVariableTarget]::Process ) begin { } process { $value = [System.Environment]::GetEnvironmentVariable($Name, $Scope) if ($null -eq $value) { $rawvalue = $null $valuetype = $null } else { if ($Scope -ne "Process") { $allenv = Get-Item -Path (Get-EnvPath -Scope $Scope) $valuetype = $allenv.GetValueKind($Name) if ($valuetype -eq "ExpandString") { $rawvalue = $allenv.GetValue( $Name, $null, 'DoNotExpandEnvironmentNames' ) } elseif ($valuetype -eq "String") { # $value -eq $rawvalue $rawvalue = $null } else { # inappropriate kind (dword, bytes, ...) $rawvalue = $null $valuetype = $null } } else { # $Scope -eq "Process" $rawvalue = $null $valuetype = "String" } } $params = @{ Name = $Name Value = $value Scope = $Scope ValueType = $valuetype BeforeExpansion = $rawvalue } New-EnvVar-Object @params } end { } } <# .SYNOPSIS Sets the environment variable for given name and scope. .EXAMPLE Set-EnvironmentVariable -Name NEW_ENVVAR -Value new_value -Scope User -ValueType String -Inherit Auto #> function Set-EnvironmentVariable { [CmdletBinding()] param ( # Name of the environment variable [Parameter(Position = 0, Mandatory)] [ValidatePattern("[^=]+")] [String] $Name, # Value of the environment variable [Parameter(Position = 1, Mandatory)] [String] $Value, # Scope of the environment variable [Parameter()] [System.EnvironmentVariableTarget] $Scope = [System.EnvironmentVariableTarget]::Process, # Type of the environment variable [Parameter()] [ValidateSet("String", "ExpandString")] [String] $ValueType = "String", # Inheritance method for the environment variable [Parameter()] [ValidateSet("Always", "Auto", "Never")] [String] $Inherit = "Auto" ) begin { } process { # inheritance condition if ($Scope -eq "Process") { $inheritance = $false } else { switch ($Inherit) { "Never" { $inheritance = $false } "Always" { $inheritance = $true } "Auto" { $cur_val_proc = [System.Environment]::GetEnvironmentVariable($Name) if ($Name -eq "Path") { $cur_val_m = [System.Environment]::GetEnvironmentVariable($Name, "Machine") $cur_val_u = [System.Environment]::GetEnvironmentVariable($Name, "User") $cur_val = $cur_val_m + $cur_val_u } else { $cur_val = [System.Environment]::GetEnvironmentVariable($Name, $Scope) } if ($cur_val -eq $cur_val_proc) { $inheritance = $true } else { $inheritance = $false } } Default { } } } # set value if (($ValueType -eq "String") -or ($Scope -eq "Process")) { if ($ValueType -eq "ExpandString") { # $Scope -eq "Process" $val = [System.Environment]::ExpandEnvironmentVariables($Value) } else { $val = $Value } [System.Environment]::SetEnvironmentVariable($Name, $val, $Scope) } else { Set-ItemProperty -Path (Get-EnvPath $Scope) -Name $Name -Value $Value -Type $ValueType Update-EnvVarSetting } # inherit if ($inheritance) { if ($Name -eq "Path") { $cur_val_m = [System.Environment]::GetEnvironmentVariable($Name, "Machine") $cur_val_u = [System.Environment]::GetEnvironmentVariable($Name, "User") $cur_val = $cur_val_m + $cur_val_u } else { $cur_val = [System.Environment]::GetEnvironmentVariable($Name, $Scope) } [System.Environment]::SetEnvironmentVariable($Name, $cur_val, "Process") } Get-EnvironmentVariable -Name $Name -Scope $Scope } end { } } Export-ModuleMember -Function Get-EnvironmentVariable, Set-EnvironmentVariable |