Why is the Environment variable ClientName not updated during logon script?

9,612

As Drifter104 says, in order to get the current value of ClientName, it must be read from HKCU:\Volatile Environment\<session id>

If found two little PS functions that do the job at http://www.out-web.net/?p=1479.

To get the session 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
}

To read the ClientName Value :

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

Use :

$ClientName = Get-RDSSessionId | Get-RDSClientName
Share:
9,612

Related videos on Youtube

Dric
Author by

Dric

I'm working in a french psychiatric hospital as Windows and VMWare sysadmin. I like putting fingers in my nose, doing ugly php code, crashing systems on friday afternoon, and asking stupid questions.

Updated on September 18, 2022

Comments

  • Dric
    Dric over 1 year

    I run a powershell logon script when opening RDS session on Windows 2012 R2 Server. I also run a powershell script in startup folder.

    • When asking for CLIENTNAME environment variable in the logon script, I get the previously opened session client name, not the current one. If I delete the registry HKCU\Environment\Clientname property before closing the previous session, I just get a null value for ClientName during logon.
    • When asking the ClientName variable in the script launched after session is opend, I get the current client name (as expected).

    I have two clients :

    • TestClient1 with IP address 10.100.20.201
    • TestClient2 with IP address 10.100.20.202

    The RDS server is SRV-XA01.

    I also use a small utility named gettscip.exe to get the client IP address

    I log on TestClient1 then I close the session. Then I start a session from TestClient2 (dates are in french format dd/mm/YYYY).

    Logon script :

    29/12/2016 10:57:07 : --- New Session opening on SRV-XA01 ---
    29/12/2016 10:57:07 : * Client Name (from env:CLIENTNAME) :
    29/12/2016 10:57:10 : * IP address : 10.100.20.202
    29/12/2016 10:57:11 : * ClientName from [Environment]::GetEnvironmentVariables("user").ClientName : TestClient1
    29/12/2016 10:57:11 : --- Logon script successfully ended ! ---

    Second script :

    29/12/2016 10:57:25 : --- Script running after session is opened ---
    29/12/2016 10:57:25 : * Client Name (from env:CLIENTNAME) : TestClient2
    29/12/2016 10:57:25 : --- Script ended ---

    In logon script the env:CLIENTNAME returns a null value, [Environment]::GetEnvironmentVariables("user").ClientName returns the previous client name. After login, everything is OK.

    The IP Address I get is the good one from the current Client.

    So why is the ClientName environment variable not updated at the time the logon script is running ?

    Edit : scripts code.

    Logon script :

    $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 ! ---"
    

    Second Script :

    $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 ---"
    
  • Colyn1337
    Colyn1337 over 7 years
    FYI for next time since you're new, you should have given Drifter104 an opportunity to turn his suggestion into an answer since it led to the solution.
  • Dric
    Dric over 7 years
    How can I do that ? Is there a button for accepting a comment as an answer ?
  • Colyn1337
    Colyn1337 over 7 years
    You reply to his comment advising him the suggestion worked and ask him to submit it as an answer.
  • fjf2002
    fjf2002 over 5 years
    To get the SessionID, you can just do (Get-Process -pid $pid).SessionId, where $pid is powershell's automatic variable for its own pid.