PowerShell 環境變數:深入挖掘

使用PowerShell設置Windows環境變量,讀取環境變量並創建新的環境變量一旦你知道訣竅就很容易。本文介紹的訣竅適用於Windows 10環境變量以及Windows 7 SP1 / Windows Server 2008之後的任何Windows客戶端/服務器。

PowerShell提供了許多不同的方法來與Windows環境變量進行交互,包括從$env: PSDrive,註冊表和[System.Environment] .NET類。在這個逐步演練中,您將了解每種方法,包括了解環境變量的作用域。

假設

在本文中,我將使用Windows 10上的Windows PowerShell 5.1。但如果您在Windows 7 SP1或更高版本上使用的是Windows PowerShell v3之後的任何版本,我即將展示給您的技巧應該也能正常工作。

什麼是環境變量?

環境變量,如其名所示,存儲有關Windows和應用程序使用的環境的信息。環境變量可以由圖形應用程序(如Windows Explorer和純文本編輯器(如記事本))以及cmd.exe和PowerShell訪問。

使用環境變量可以幫助您在PowerShell腳本或模塊中避免硬編碼文件路徑,用戶名或計算機名等信息。

常見的環境變量

當您開始學習如何在PowerShell中使用環境變數時,您會遇到許多不同的變數。其中一些比其他的更有用。以下是一些常見環境變數及其用法的參考列表。

Variable Usage
ClientName The name of the remote computer connected via a Remote Desktop session.
SessionName This helps to identify if the current Windows session is regarded by the operating system as running at the console. For console sessions SessionName will be ‘Console’. Enhanced Session connections to Hyper-V Virtual Machines do not report SessionName as ‘Console’, whereas Standard Sessions do.
ComputerName The name of the computer.
SystemRoot and Windir The path to the current Windows installation.
ProgramFiles and ProgramFiles(x86) The default locations for x64 and x86 programs.
ProgramW6432 The default location for programs, avoiding 32/64 bit redirection. This variable only applies for 32 bit processes running on a 64 bit platform. This means that you can use it to identify when a 32 bit instance of PowerShell is running on a 64 bit system.
UserDNSDomain The Fully Qualified Domain Name of the Active Directory domain that the current user logged on to. Only present for domain logons.
UserDomain The NETBIOS-style name of the domain that the current user logged on to. Can be a computer name if there’s no domain.
UserDomainRoamingProfile The location of the central copy of the roaming profile for the user, if any. Only present for domain logons.
UserName The name of the currently logged on user.
UserProfile The location of the profile of the current user on the local computer.

環境變數範圍

環境變數有三個範圍。將範圍視為形成完整圖像的變量層。這些“層”結合在一起,為Windows中運行的任何進程提供許多不同的環境變數。

環境變數範圍的“層次結構”

這些“層”中的每一個都是相互組合或覆蓋的。它們按照層次結構定義,如:計算機 –> 用戶 –> 進程,每個範圍的變量在父範圍中存在時覆蓋父範圍的變量。

例如,一個常見的環境變量是TEMP。此變量存儲了Windows本地臨時文件夾的文件夾路徑。此環境變量被設置為:

  • C:\WINDOWS\TEMP in the machine scope
  • C:\Users\<username>\AppData\Local\Temp in the user scope
  • C:\Users\<username>\AppData\Local\Temp in the process scope.

如果在用戶範圍中沒有設置TEMP環境變量,則最終結果將為C:\WINDOWS\TEMP

環境變量範圍類型

Windows中有三種不同的環境變量範圍。

計算機

計算機範圍內的環境變量與正在運行的Windows實例相關聯。任何使用者帳戶都可以讀取這些變量,但需要使用提升的權限進行設置、更改或刪除。

用戶

使用者範圍的環境變數與執行目前處理的使用者相關聯。使用者變數會覆蓋具有相同名稱的機器-範圍變數。

注意:Microsoft建議機器和使用者範圍的環境變數值不超過2048個字符。

處理程序

範圍的環境變數是機器範圍和使用者範圍的組合,還包括Windows動態創建的一些變數。

以下是運行中處理程序可用的環境變數列表。所有這些變數都是動態創建的。

  • ALLUSERSPROFILE
  • APPDATA
  • COMPUTERNAME
  • HOMEDRIVE
  • HOMEPATH
  • LOCALAPPDATA
  • LOGONSERVER
  • PROMPT
  • PUBLIC
  • SESSION
  • SystemDrive
  • SystemRoot
  • USERDNSDOMAIN
  • USERDOMAIN
  • USERDOMAIN_ROAMINGPROFILE
  • USERNAME
  • USERPROFILE

註冊表中的環境變數

環境變數存儲在兩個註冊表位置,一個用於使用者範圍,另一個用於機器範圍。

不要使用註冊表管理環境變量

在對註冊表中的變量進行更改時有一個注意事項。任何正在運行的進程將無法看到註冊表中的變量更改。進程只能看到在啟動進程時存在的註冊表變量和值,除非Windows通知它們發生了變化。

您可以使用.NET類來直接修改註冊表。.NET [System.Environment]類可以修改機器和用戶範圍的環境變量,並為您處理註冊表管理。

直接修改註冊表中的環境變量,雖然可能,但沒有道理。.NET類提供了一種更簡單、由Microsoft支持的方法。您將在本文後面學習如何使用[System.Environment] .NET類。

環境變量的註冊表位置和查詢

I hope you’ve been convinced to not modify the registry directly but if you’d like to take a peek at what’s in there, you can find all user environment variables in the HKEY_CURRENT_USER\Environment key. Machine-scoped environment variables are stored at HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment.

這兩個鍵中包含REG_SZREG_EXPAND_SZ類型的註冊表值。 REG_EXPAND_SZ值包含作為其值的一部分嵌入的環境變量。當檢索值時,這些環境變量將被展開。

為了演示這一點,可以使用REG實用程序。這是Windows附帶的一個小型命令行實用程序。

查詢如下所示的TEMP環境變數。使用REG命令並使用QUERY參數檢索TEMP變數的值。

> REG QUERY HKCU\Environment /V TEMP

HKEY_CURRENT_USER\Environment     
    TEMP    REG_EXPAND_SZ    %USERPROFILE%\AppData\Local\Temp

您有時會注意到環境變數被百分比符號(%COMPUTERNAME%)包圍,就像上面一樣。這是通過cmd.exe和批處理文件顯示環境變數的老方法。請知道PowerShell不認識這種格式。

REG實用程序允許我們查看註冊表值的原始值。值類型為REG_EXPAND_SZ,值包含%USERPROFILE%環境變數。

如果您想使用PowerShell檢索註冊表值,可以使用如下所示的Get-Item命令。

PS51> Get-ItemProperty -Path HKCU:\Environment -Name TEMP

TEMP         : C:\Users\<your username>\AppData\Local\Temp
PSPath       : Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Environment
PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER
PSChildName  : Environment
PSDrive      : HKCU
PSProvider   : Microsoft.PowerShell.Core\Registry

通過GUI查看和設置Windows環境變數

要查看用戶和系統環境變數的GUI視圖,從PowerShell、命令提示符或按下Windows鍵+R運行SystemPropertiesAdvanced.exe ,以顯示系統內容高級選項卡。單擊下圖中突出顯示的EnvironmentVariables按鈕。

The System Properties dialog, Advanced tab

下面顯示的環境變數對話框允許您查看、創建和修改用戶和機器範圍的環境變數。請注意,該對話框將機器範圍的變量稱為系統變量

The Environment Variables dialog

現在您已經了解了環境變數,讓我們開始您所需的,使用PowerShell管理它們

有幾種不同的方式可以使用 PowerShell 與環境變數進行互動。

  • 使用 Env: PSDrive 和 Provider – 基於會話。只會設定當前 PowerShell 會話中的環境變數值。
  • $env: 變數 – 基於會話。只會設定當前 PowerShell 會話中的環境變數值。
  • 使用 [System.Environment] .NET 類別 – 允許您在會話和重新啟動之間持續存在使用者和系統範圍的環境變數。

使用 Env: PSDrive 和 Provider

讀取環境變數的最佳方式之一是 PowerShell 的概念,稱為 PowerShell drives (PS drives)。PS drive 允許您將環境變數視為檔案系統,通過 Env: drive 進行操作。

切換到 Env: Drive

像所有的 PS drives 一樣,您可以通過路徑引用它,例如 Env:\TEMPEnv:\COMPUTERNAME 等。但為了省去一些按鍵,可以像下面一樣切換到 Env: drive。

PS51> cd Env:
PS51 Env:\>

## 或者

PS51> Set-Location Env:
PS Env:\>

使用 Env: Drive 進行 Tab-Completion

您可以使用与访问文件系统相同的命令,例如 `Get-Item` 和 `Get-ChildItem` 来访问环境变量。但是,您读取的是 `Env:` 驱动器中的环境变量,而不是文件系统。

由于环境变量存储在 PowerShell 驱动器中,您可以使用 PowerShell 的标签补全功能来循环遍历可用的变量,如下所示。

Env: tab completion – finding environment variables starting with the letter C

现在,让我们来看一些使用 `Env:` PS 驱动器处理环境变量的示例。

使用 `Env:` 列出环境变量

PS51> Get-Item -Path Env:
PS51> Get-Item -Path Env:USERNAME

使用通配符和 `Env:` 列出环境变量

PS51> Get-Item -Path Env:user*

使用 `Env:` 查找环境变量的值

这些命令的结果是键/值对 `[System.Collections.DictionaryEntry]` 的 .NET 对象。这些对象将环境变量的名称存储在 `Name` 属性中,将值存储在 `Value` 属性中。

您可以通过将 `Get-Item` 命令的引用放在括号中,并引用 `Value` 属性来访问特定环境变量的值,如下所示:

PS51> (Get-Item -Path Env:computername).Value
MYCOMPUTERHOSTNAME

在只返回特定环境变量的情况下,使用标准的PowerShell cmdlet,如Select-ObjectWhere-Object来选择和过滤由Env:提供程序返回的对象。

在下面的示例中,只返回环境变量COMPUTERNAME

PS51> Get-ChildItem -Path Env: | Where-Object -Property Name -eq 'COMPUTERNAME'

作为替代方法,可以使用Get-Content cmdlet。该cmdlet返回一个包含环境变量值的[String]对象。该对象更简单,因为它只返回值,而不是带有NameValue属性的对象。

PS51> Get-Content -Path Env:\COMPUTERNAME

演示:在字符串中插入环境值

使用Get-Content,可以找到环境变量的值,并将环境变量(例如COMPUTERNAME)插入到文本字符串中。

PS51> 'Computer Name is: {0}' -f (Get-Content -Path Env:COMPUTERNAME)
Computer Name is: MYCOMPUTER

使用Env:设置环境变量(并创建)

使用New-Item cmdlet在PowerShell中创建新的环境变量。在Name值中以Env:\<EnvVarName>的形式提供环境变量的名称,并将环境变量的值提供给Value参数,如下所示。

PS51> New-Item -Path Env:\MYCOMPUTER -Value MY-WIN10-PC
Name                           Value
----                           -----
MYCOMPUTER                     MY-WIN10-PC

使用Set-Item cmdlet設定環境變數,如果不存在則創建新的。您可以看到使用Set-Item cmdlet,您可以創建或修改環境變數。

PS51> Set-Item -Path Env:testvariable -Value "Alpha"

使用Env:複製環境變數

有時候,您需要複製環境變數的值。您可以使用Copy-Item cmdlet來實現這一點。

如下所示,將COMPUTERNAME變數的值復制到MYCOMPUTER,覆蓋其現有值。

PS51> Get-Item -Path Env:\MYCOMPUTER

Name                           Value
----                           -----
MYCOMPUTER                     MY-WIN10-PC

PS51> Copy-Item -Path Env:\COMPUTERNAME -Destination Env:\MYCOMPUTER
PS51> Get-Item -Path Env:\MYCOMPUTER

Name                           Value
----                           -----
MYCOMPUTER                     WIN10-1903

使用Env:刪除環境變數

當不再需要環境變數時,可以使用三種方法之一來刪除環境變數:

  • 使用Set-Item cmdlet將環境變數設置為空值
PS51> Set-Item -Path Env:\MYCOMPUTER -Value ''
PS51> Remove-Item -Path Env:\MYCOMPUTER
  • 使用Clear-Item cmdlet
PS51> Clear-Item -Path Env:\MYCOMPUTER

使用Env:重命名環境變數

在需要更改環境變數名稱的情況下,您可以選擇重命名,而不是刪除並重新創建使用Env:提供程序的變數。

使用Rename-Item cmdlet來更改環境變量的名稱,同時保留其值。下面可以看到將MYCOMPUTER變量更名為OLDCOMPUTER,並保留其值。

PS51> Rename-Item -Path Env:\MYCOMPUTER -NewName OLDCOMPUTER
PS51> Get-Item -Path OLDCOMPUTER
Name                           Value
----                           -----
OLDCOMPUTER                    WIN10-1903

$Env:變量

掌握了將環境變量視為文件的Env:驅動器後,本節將向您展示如何將其視為變量。您還可以使用PowerShell 表達式解析器來管理會話中的環境變量。此功能允許您使用$Env:作用域來訪問環境變量。

使用$Env:獲取環境變量

使用$Env作用域,您可以直接引用環境變量,而無需使用Get-Item命令,如下所示。

PS51> $env:computername

此方法使得將環境變量插入字符串變得容易,如下所示:

PS51> "The Computer Name is {0}" -f $env:computername
The Computer Name is WIN10-1809
PS51> "The Computer Name is $env:computername"
The Computer Name is WIN10-1809

使用$Env:設置或創建環境變量

使用此方法設置環境變量很簡單。如果環境變量不存在,它還會創建一個新的環境變量,如下所示。

PS51> $env:testvariable = "Alpha"

使用+=語法將值添加到現有值,而不是覆蓋它。

PS51> $env:testvariable = "Alpha"
PS51> $env:testvariable += ",Beta"

PS51> $env:testvariable
Alpha,Beta

使用$Env:刪除環境變量

使用此方法刪除環境變量,只需將其值設置為空字符串即可。

PS51> $env:testvariable = ''

使用 [System.Environment] .NET 类

.NET 类 [System.Environment] 提供了获取和设置环境变量的方法。这是直接访问各种环境范围并设置在 PowerShell 会话之间保留的环境变量的唯一方法。

在以下所有示例中,如果未提供范围,则默认为进程范围。

使用 [System.Environment] 时,您将使用几个不同的 .NET 静态类 方法。您不需要理解静态方法是什么。您只需要理解要使用即将学习的任何技术,首先需要引用类 ([System.Environment]),然后是两个冒号 (::),然后是方法。

使用 [System.Environment] 列出环境变量

如果您想查看特定范围内的所有环境变量,可以使用 GetEnvironmentVariables 方法。该方法返回由方法参数 (括号内) 指定的范围的所有环境变量。

Listing environment variables with GetEnvironmentVariable in each scope
PS51> [System.Environment]::GetEnvironmentVariables('User') PS51> [System.Environment]::GetEnvironmentVariables('Machine') PS51> [System.Environment]::GetEnvironmentVariables('Process') # 与进程相同 PS51> [System.Environment]::GetEnvironmentVariables()

使用 [System.Environment] 获取单个环境变量

如果您需要查找特定的环境变量,可以有两种不同的方法。

  • GetEnvironmentVariables().<var name> – 不推荐
  • GetEnvironmentVariable('<變數名稱>','<範圍>')

GetEnvironmentVariables()

使用GetEnvironmentVariables()方法,使用點記法來引用值。將[System.Environment]類和靜態方法引用括在括號內,然後加上一個點,接著是環境變數的名稱,如下所示:

PS51> ([System.Environment]::GetEnvironmentVariables()).APPDATA

請注意,當以這種方式引用環境變數時,必須確保大小寫匹配!在上面的示例中,嘗試使用appdata來引用APPDATA變數。使用GetEnvironmentVariable()代替。

GetEnvironmentVariable()

不要使用GetEnvironmentVariables()方法,而是使用GetEnvironmentVariable()來查找單個環境變數。這可以避免大小寫問題,並且還允許您指定範圍。

要使用此方法,請指定環境變數名稱和您想要在其中查找該變數的範圍,用逗號分隔。

PS51> [System.Environment]::GetEnvironmentVariable('ComputerName','User')
# 空白

PS51> [System.Environment]::GetEnvironmentVariable('ComputerName','Machine')
# 空白

PS51> [System.Environment]::GetEnvironmentVariable('ComputerName','Process')  WIN10-1903

# 與進程相同
PS51> [System.Environment]::GetEnvironmentVariable('ComputerName')
WIN10-1903

使用[System.Environment]設置環境變數

使用SetEnvironmentVariable()方法來設置給定範圍的環境變數的值,如果該變數尚不存在,則創建新的環境變數。

在設定變數時,你會發現處理範圍是易變的,而對用戶和機器範圍的更改是永久的。

PS51> [System.Environment]::SetEnvironmentVariable('TestVariable','Alpha','User')

PS51> [System.Environment]::SetEnvironmentVariable('TestVariable','Alpha','Process')

PS51> [System.Environment]::SetEnvironmentVariable('TestVariable','Alpha','Machine')

 # 與處理範圍相同
PS51> [System.Environment]::SetEnvironmentVariable('TestVariable','Alpha')

注意:調用具有變量名或值為32767個字符或更多的SetEnvironmentVariable方法將引發異常。

使用[System.Environment]來刪除環境變量

通過將其值設置為空字符串,使用SetEnvironmentVariable()方法來刪除給定範圍的環境變量。

PS51> [System.Environment]::SetEnvironmentVariable('TestVariable', '', 'User')

PS51> [System.Environment]::SetEnvironmentVariable('TestVariable', '', 'Process')

PS51> [System.Environment]::SetEnvironmentVariable('TestVariable', '', 'Machine')

# 與處理範圍相同
PS51> [System.Environment]::SetEnvironmentVariable('TestVariable', '')

有用的PowerShell環境變量

就像其他Windows應用程序一樣,PowerShell也有一些自己的環境變量。了解兩個有用的環境變量是PSExecutionPolicyPreference和PSModulePath。

PSExecutionPolicyPreference

PSExecutionPolicyPreference環境變量存儲當前的PowerShell執行策略。如果使用以下方式設置會話特定的PowerShell執行策略時,它會被創建:

  • 運行具有Process範圍參數的Set-ExecutionPolicy cmdlet
  • 運行powershell.exe可執行文件以啟動新會話,使用ExecutionPolicy命令行參數來設置會話的策略。

PSModulePath

PSModulePath 環境變數包含 PowerShell 在未指定完整路徑時搜索模組的路徑。它的形式類似於標準的 PATH 環境變數,每個目錄路徑之間用分號分隔。

PS51> $env:PSModulePath
C:\Program Files\WindowsPowerShell\Modules;C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules

快速提示:將每個文件夾拆分為字符串陣列,使用 $env:PSModulePath.split(‘;’) 可以分別處理每個路徑。

摘要

環境變數是獲取正在運行的系統信息或在會話和重新啟動之間存儲信息的有用方法。無論您只是讀取默認的 Windows 操作系統環境變數,還是創建自己的變量,現在都可以使用各種方式使用 PowerShell 進行管理!

進一步閱讀

Source:
https://adamtheautomator.com/powershell-environment-variables/