Public/system/Set-EnvironmentVariable.ps1
|
#Requires -Version 5.1 function Set-EnvironmentVariable { <# .SYNOPSIS Sets or deletes a Machine- or User-scoped environment variable on local or remote computers .DESCRIPTION Sets a Machine- or User-scoped environment variable using [Environment]::SetEnvironmentVariable, the symmetric writer for Get-EnvironmentVariable. Supports -WhatIf/-Confirm (ConfirmImpact Medium). An empty Value deletes the variable. User scope targets the executing account profile when run remotely (the WinRM logon identity), not the console user; already-running processes will not see the change until restarted regardless of scope. .PARAMETER Name Environment variable name to set or delete. .PARAMETER Value New value. An EMPTY string deletes the variable via [Environment]::SetEnvironmentVariable($Name, $null, $Scope). .PARAMETER Scope Machine (default) or User scope. Writing Machine scope requires Administrator privileges. User scope on a remote computer applies to the executing account's profile (the WinRM logon identity), not the interactive console user. .PARAMETER ComputerName One or more computer names to target. Defaults to the local computer. Accepts pipeline input by value and by property name. .PARAMETER Credential Optional PSCredential for authenticating to remote computers. Not used for local operations. .EXAMPLE Set-EnvironmentVariable -Name 'FOO' -Value 'bar' -Scope Machine Sets the Machine-scoped 'FOO' variable to 'bar' on the local computer. .EXAMPLE Set-EnvironmentVariable -Name 'FOO' -Value 'bar' -ComputerName 'SRV01' -Credential (Get-Credential) Sets the Machine-scoped 'FOO' variable to 'bar' on SRV01 using explicit credentials. .EXAMPLE 'SRV01', 'SRV02' | Set-EnvironmentVariable -Name 'FOO' -Value '' Deletes the 'FOO' variable on both SRV01 and SRV02 via pipeline (empty Value = delete). .OUTPUTS PSWinOps.EnvironmentVariable Returns one object per computer with the read-back Name/Value/Scope after the operation. Value is an empty string when the variable was deleted. .NOTES Author: Franck SALLET Version: 1.0.0 Last Modified: 2026-07-06 Requires: PowerShell 5.1+ / Windows only Requires: Administrator privileges for Machine scope .LINK https://github.com/k9fr4n/PSWinOps .LINK https://learn.microsoft.com/en-us/windows/win32/procthread/environment-variables #> [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')] [OutputType('PSWinOps.EnvironmentVariable')] param( [Parameter(Mandatory = $true, Position = 0, ValueFromPipelineByPropertyName = $true)] [ValidateNotNullOrEmpty()] [string]$Name, [Parameter(Mandatory = $true, Position = 1)] [AllowEmptyString()] [string]$Value, [Parameter(Mandatory = $false)] [ValidateSet('Machine', 'User')] [string]$Scope = 'Machine', [Parameter(Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Position = 2)] [ValidateNotNullOrEmpty()] [Alias('CN', 'DNSHostName')] [string[]]$ComputerName = $env:COMPUTERNAME, [Parameter(Mandatory = $false)] [ValidateNotNull()] [System.Management.Automation.PSCredential] [System.Management.Automation.Credential()] $Credential ) begin { Write-Verbose -Message "[$($MyInvocation.MyCommand)] Starting with Name='$Name', Scope=$Scope" $isDelete = [string]::IsNullOrEmpty($Value) $scriptBlock = { param( [string]$VariableName, [string]$VariableValue, [string]$VariableScope, [bool]$DeleteRequested ) $valueToSet = if ($DeleteRequested) { $null } else { $VariableValue } [Environment]::SetEnvironmentVariable($VariableName, $valueToSet, $VariableScope) $readBack = [Environment]::GetEnvironmentVariable($VariableName, $VariableScope) if ($null -eq $readBack) { $readBack = '' } [PSCustomObject]@{ Name = $VariableName Value = $readBack Scope = $VariableScope } } } process { foreach ($targetComputer in $ComputerName) { Write-Verbose -Message "[$($MyInvocation.MyCommand)] Processing '$targetComputer'" try { $actionDescription = if ($isDelete) { "Delete $Scope environment variable '$Name'" } else { "Set $Scope environment variable '$Name' = '$Value'" } if ($PSCmdlet.ShouldProcess($targetComputer, $actionDescription)) { $result = Invoke-RemoteOrLocal -ComputerName $targetComputer -ScriptBlock $scriptBlock -ArgumentList @($Name, $Value, $Scope, $isDelete) -Credential $Credential [PSCustomObject]@{ PSTypeName = 'PSWinOps.EnvironmentVariable' ComputerName = $targetComputer Name = $result.Name Value = $result.Value Scope = $result.Scope Timestamp = Get-Date -Format 'yyyy-MM-dd HH:mm:ss' } } } catch { Write-Error -Message "[$($MyInvocation.MyCommand)] Failed on '${targetComputer}': $_" continue } } } end { Write-Verbose -Message "[$($MyInvocation.MyCommand)] Completed" } } |