为什么环境变量 ClientName 在登录脚本期间没有更新?

为什么环境变量 ClientName 在登录脚本期间没有更新?

在 Windows 2012 R2 Server 上打开 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)。

登录脚本:

2016 年 12 月 29 日 10:57:07: --- 在 SRV-XA01 上开启新会话 ---
2016 年 12 月 29 日 10:57:07:* 客户端名称(来自 env:CLIENTNAME):
2016 年 12 月 29 日 10:57:10:* IP 地址:10.100.20.202
2016 年 12 月 29 日 10:57:11:* 客户端名称来自 [环境]::GetEnvironmentVariables("user").ClientName:TestClient1
2016 年 12 月 29 日 10:57:11: --- 登录脚本成功结束! ---

第二个脚本:

2016 年 12 月 29 日 10:57:25 : --- 会话打开后运行脚本 ---
2016 年 12 月 29 日 10:57:25 :* 客户端名称(来自环境:CLIENTNAME):TestClient2
2016 年 12 月 29 日 10:57:25 : --- 脚本结束 ---

在登录脚本中env:CLIENTNAME返回一个空值,[Environment]::GetEnvironmentVariables("user").ClientName返回前一个客户端名称。登录后,一切正常。

我获得的 IP 地址是来自当前客户端的良好 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 ---"

答案1

正如 Drifter104 所说,为了获取的当前值ClientName,必须从中读取HKCU:\Volatile Environment\<session id>

如果发现两个小 PS 函数可以完成以下工作http://www.out-web.net/?p=1479

获取会话 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

相关内容