Назад | Перейти на главную страницу

Почему переменная среды ClientName не обновляется во время сценария входа в систему?

Я запускаю сценарий входа в систему PowerShell при открытии сеанса RDS на сервере Windows 2012 R2. Я также запускаю сценарий PowerShell в папке автозагрузки.

У меня два клиента:

Сервер 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 ("пользователь"). 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>

Если вы обнаружите две маленькие функции PS, которые работают с http://www.out-web.net/?p=1479.

Чтобы получить идентификатор сеанса:

<#
.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