Master Your Environment Part 3
Note: I am aware that code samples are not respecting HTML tags and rendering some characters with their HTML codes. Buttondown is working on this issue. I apologize for the annoyance.
Let's wrap up our exploration of [System.Environment]
. Even though I would encourage you to use the $ENV:
PSDrive, not all environment variables are accessible through it nor are they available on all platforms. If you are creating cross-platform scripts that incorporate environment variables, you may need to use [System.Environment]
.
Homework
But before we get to the last bit of content on this topic, let's review the homework assignment I gave you. I hope you at least started to devise a solution.
Write a PowerShell function that writes a an object to the pipeline that shows unique environment variables for each target. The output should also include the computer and user names. Feel free to enhance the function as you wish.
The targets are User, Machine, and Process. Here's a function that I came up with:
Function Get-EnvironmentVariableTarget {
[cmdletbinding()]
[Alias('gevt')]
Param()
Write-Information -MessageData "Running under PowerShell version: $($PSVersionTable.PSVersion)" -Tags meta
Write-Information -MessageData "Using host: $($host.name)" -Tags meta
Write-Information -MessageData ".NET version: $([System.Environment]::Version)" -Tags meta
# nested helper function
Function HashToOrderedObject {
# A helper function to convert a hashtable to a PSObject
# with ordered property names
Param([Hashtable]$Hash)
$hash.GetEnumerator() |
Sort-Object Key |
foreach -Begin {
$tmp = [ordered]@{}
} -Process {
$tmp.Add($_.key, $_.value)
} -End { [PSCustomObject]$tmp }
}
#Get variables from the different scopes or targets
$u = [System.Environment]::GetEnvironmentVariables('user')
$m = [System.Environment]::GetEnvironmentVariables('machine')
$p = [System.Environment]::GetEnvironmentVariables('process')
Write-Information -MessageData "User variables: $($u.Count)" -Tags data
Write-Information -MessageData ($u | Out-String) -Tags data
Write-Information -MessageData "Machine variables: $($m.Count)" -Tags data
Write-Information -MessageData ($m | Out-String) -Tags data
Write-Information -MessageData "Process variables: $($p.Count)" -Tags data
Write-Information -MessageData ($p | Out-String) -Tags data
#I need to create a new Hashtable to store the unique process variables
$p.GetEnumerator() |
Where-Object { ($m.keys -notContains $_.name) -AND ($u.keys -notContains $_.name) } |
ForEach-Object -Begin { $Unique = @{} } -Process { $Unique[$_.Name] = $_.Value }
Write-Information -MessageData "Unique process variables: $($Unique.Count)" -Tags data
Write-Information -MessageData ($Unique | Out-String) -Tags data
#create a composite, custom object
[PSCustomObject]@{
Computername = [System.Environment]::MachineName
UserName = [System.Environment]::UserName
Host = $host.Name
PSVersion = $PSVersionTable.PSVersion
User = HashToOrderedObject -Hash $u
Machine = HashToOrderedObject -Hash $m
Process = HashToOrderedObject -Hash $Unique
}
}
The function gets variables from each of the scopes. I then create a hashtable to store the unique process variables that aren't defined in the user or machine targets. The custom object's Process
property might be slightly misleading because it isn't the actual Process
target but rather the unique variables in the Process
target. The output also includes additional information which I thought might be useful. I have also included information data that you can get when you use the -InformationActionVariable
parameter.
$r = Get-EnvironmentVariableTarget -InformationVariable iv
Here's the output.
The individual properties will show the different target variables.