為什麼在登錄腳本期間環境變數 ClientName 沒有更新?
在 Windows 2012 R2 伺服器上打開 RDS 會話時,我執行了一個 powershell 登錄腳本。我還在啟動文件夾中執行了一個 powershell 腳本。
- 在登錄腳本中詢問
CLIENTNAME
環境變數時,我得到了以前打開的會話客戶端名稱,而不是目前的。如果我在關閉前一個會話之前刪除系統資料庫HKCU\Environment\Clientname
屬性,我只會在登錄期間為 ClientName 獲得一個空值。- 在會話打開後啟動的腳本中詢問 ClientName 變數時,我得到了目前的客戶端名稱(如預期的那樣)。
我有兩個客戶:
TestClient1
帶 IP 地址10.100.20.201
TestClient2
帶 IP 地址10.100.20.202
RDS 伺服器是
SRV-XA01
.我還使用了一個名為
gettscip.exe
獲取客戶端 IP 地址的小實用程序我登錄
TestClient1
然後關閉會話。然後我從TestClient2
(日期為法語格式dd/mm/YYYY
)開始一個會話。登錄腳本:
29/12/2016 10:57:07 : — SRV-XA01 新會話打開 —
29/12/2016 10:57:07 : * 客戶名稱(來自 env:CLIENTNAME):
29/12/2016 10:57:10 : * IP 地址 : 10.100.20.202
29/12/2016 10:57:11 : * ClientName 來自
$$ Environment $$::GetEnvironmentVariables(“user”).ClientName : TestClient1
29/12/2016 10:57:11 : — 登錄腳本成功結束!—
第二個腳本:
29/12/2016 10:57:25 : — 會話打開後執行的腳本 —
29/12/2016 10:57:25 : * 客戶端名稱(來自 env:CLIENTNAME):TestClient2
29/12/2016 10:57:25 : — 腳本結束 —
在登錄腳本中
env:CLIENTNAME
返回一個空值,[Environment]::GetEnvironmentVariables("user").ClientName
返回以前的客戶端名稱。登錄後,一切正常。我得到的 IP 地址是來自目前客戶端的好地址。
那麼為什麼在登錄腳本執行時 ClientName 環境變數沒有更新呢?
編輯:腳本程式碼。
登錄腳本:
$DomainName = "domain.fr" # Nom de l'utilisateur $UserName = $env:USERNAME $ScriptsDir = "\\$DomainName\Scripts" $LogDir = "$ScriptsDir\ScriptsXA7\Logs" $global:LogFile = "$LogDir\$UserName.log" Import-Module "$ScriptsDir\Systeme\Modules\Write-Log" # Serveur Citrix $ComputerName = $env:COMPUTERNAME # Poste client $ClientName = $env:CLIENTNAME Write-Log "--- New Session opening on $ComputerName ---" Write-Log "* Client Name (from env:CLIENTNAME) : $ClientName" $IPExe = "$PSScriptRoot\IP\gettscip.exe" # On lance l'exécutable qui va remonter l'adresse IP et on la stocke dans la variable `$ip` $ip = Invoke-Expression $IPExe $ip = $ip -replace "WTSClientAddress: ","" # On place cette adresse IP dans la variable d'environnement `CLIENTIP` [Environment]::SetEnvironmentVariable("CLIENTIP", $ip, "User") Write-Log "* IP address : $ip" Write-Log "* ClientName from [Environment]::GetEnvironmentVariables("user").ClientName : $([Environment]::GetEnvironmentVariables("user").ClientName)" Write-Log "--- Logon script successfully ended ! ---"
第二個腳本:
$DomainName = "domain.fr" # Nom de l'utilisateur $UserName = $env:USERNAME $ScriptsDir = "\\$DomainName\Scripts" $LogDir = "$ScriptsDir\ScriptsXA7\Logs" $global:LogFile = "$LogDir\$UserName.log" Import-Module "$ScriptsDir\Systeme\Modules\Write-Log" # Serveur Citrix $ComputerName = $env:COMPUTERNAME # Poste client $ClientName = $env:CLIENTNAME Write-Log "--- Script running after session is opened ---" Write-Log "* Client Name (from env:CLIENTNAME) : $ClientName" Write-Log "--- Script ended ---"
正如 Drifter104 所說,為了獲得 的目前值
ClientName
,必須從HKCU:\Volatile Environment\<session id>
如果在http://www.out-web.net/?p=1479找到了兩個小的 PS 功能。
要獲取會話 ID:
<# .SYNOPSIS Returns the RDS session ID of a given user. .DESCRIPTION Leverages query.exe session in order to get the given user's session ID. .EXAMPLE Get-RDSSessionId .EXAMPLE Get-RDSSessionId -UserName johndoe .OUTPUTS System.String #> function Get-RDSSessionId { [CmdletBinding()] Param ( # Identifies a user name (default: current user) [Parameter(ValueFromPipeline = $true)] [System.String] $UserName = $env:USERNAME ) $returnValue = $null try { # $pid is powershell's automatic variable for its own pid return (Get-Process -pid $pid).SessionId } catch { $_.Exception | Write-Error } New-Object psobject $returnValue }
要讀取
ClientName
值:<# .SYNOPSIS Returns the RDS client name .DESCRIPTION Returns the value of HKCU:\Volatile Environment\<SessionID>\CLIENTNAME .EXAMPLE Get-RDSClientName -SessionId 4 .EXAMPLE Get-RDSClientName -SessionId Get-RDSSessionId .OUTPUTS System.String #> function Get-RDSClientName { [CmdletBinding()] Param ( # Identifies a RDS session ID [Parameter(Mandatory = $true, ValueFromPipeline = $true)] [System.String] $SessionId ) $returnValue = $null $regKey = 'HKCU:\Volatile Environment\{0}' -f $SessionId try { $ErrorActionPreference = 'Stop' $regKeyValues = Get-ItemProperty $regKey $sessionName = $regKeyValues | ForEach-Object {$_.SESSIONNAME} if ($sessionName -ne 'Console') { $returnValue = $regKeyValues | ForEach-Object {$_.CLIENTNAME} } else { Write-Warning 'Console session' # $returnValue = $env:COMPUTERNAME } } catch { $_.Exception | Write-Error } New-Object psobject $returnValue }
採用 :
$ClientName = Get-RDSSessionId | Get-RDSClientName