Make specific tray icon always show for all profiles in Windows 7

In a nut-shell, currently, you can't do this.

There is no Group Policy or Preference to set this, and the way it keeps track makes it specific to the current user and the system, making the 'settings' vary greatly from instance to instance.

They are stored here (in the registry) if you want to check it out: HKEY_CURRENT_USER\Software\Classes\Local Settings\Software\Microsoft\Windows\CurrentVersion\TrayNotify.

From here:

There is no way for applications to programmatically always show themselves top level on the system tray either on first install or at any time during runtime. This is one of several changes we’ve made in Windows 7 in an effort to produce a cleaner, quieter desktop that is in the user’s control to customize the top level with their favorite applications and icons.

We keep the user in control of the notification area by not allowing programmatic promotion (other than temporarily or to show a notification). Assuming the machine is sufficiently quiet, when you first add your icon with Shell_NotifyIcon(NIM_ADD, ...) it will be shown on the taskbar for 45 seconds, then move into the overflow thereafter. If the user promotes an icon, it will always live on the taskbar. If the user demotes it, the icon will never be seen on the taskbar. Any promotion needs to be user initiated. We’ve made this much easier in Windows 7 via drag/drop & through the Notification Area Icons control panel, and what we’ve seen in usability studies and based on beta feedback, is that users have no difficulties discovering how to customize notification behavior and will promote the icons they want quick access to.

About your easiest bet is to show ALL Notification Area icons for all users. This can be done by adding a (simple) registry entry:

In HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer create a new DWORD value named EnableAutoTray and set it to 0 to turn off the Notification Area's 'auto hide' features.

With some OU configuration and scripting you can use it in a HKCU context as well, if you only want it to happen for certain users/groups.

See here for more info on that.


I was searching online and actually found this randomly.

Long story short, a combination of PowerShell (script provided) and GPO.

http://4sysops.com/archives/forcing-notification-area-icons-to-always-show-in-windows-7-or-windows-8/

Long story, create a PowerShell script containing the following:

param(
    [Parameter(Mandatory=$true,HelpMessage='The name of the program')][string]$ProgramName,
    [Parameter(Mandatory=$true,HelpMessage='The setting (2 = show icon and notifications 1 = hide icon and notifications, 0 = only show notifications')]
        [ValidateScript({if ($_ -lt 0 -or $_ -gt 2) { throw 'Invalid setting' } return $true})]
        [Int16]$Setting
    )

$encText = New-Object System.Text.UTF8Encoding
[byte[]] $bytRegKey = @()
$strRegKey = ""
$bytRegKey = $(Get-ItemProperty $(Get-Item 'HKCU:\Software\Classes\Local Settings\Software\Microsoft\Windows\CurrentVersion\TrayNotify').PSPath).IconStreams
for($x=0; $x -le $bytRegKey.Count; $x++)
{
    $tempString = [Convert]::ToString($bytRegKey[$x], 16)
    switch($tempString.Length)
    {
        0 {$strRegKey += "00"}
        1 {$strRegKey += "0" + $tempString}
        2 {$strRegKey += $tempString}
    }
}
[byte[]] $bytTempAppPath = @()
$bytTempAppPath = $encText.GetBytes($ProgramName)
[byte[]] $bytAppPath = @()
$strAppPath = ""

Function Rot13($byteToRot)
{
    if($byteToRot -gt 64 -and $byteToRot -lt 91)
    {
        $bytRot = $($($byteToRot - 64 + 13) % 26 + 64)
        return $bytRot
    }
    elseif($byteToRot -gt 96 -and $byteToRot -lt 123)
    {
        $bytRot = $($($byteToRot - 96 + 13) % 26 + 96)
        return $bytRot
    }
    else
    {
        return $byteToRot
    }
}

for($x = 0; $x -lt $bytTempAppPath.Count * 2; $x++)
{
    If($x % 2 -eq 0)
    {
        $curbyte = $bytTempAppPath[$([Int]($x / 2))]
            $bytAppPath += Rot13($curbyte)

    }
    Else
    {
        $bytAppPath += 0
    }
}

for($x=0; $x -lt $bytAppPath.Count; $x++)
{
    $tempString = [Convert]::ToString($bytAppPath[$x], 16)
    switch($tempString.Length)
    {
        0 {$strAppPath += "00"}
        1 {$strAppPath += "0" + $tempString}
        2 {$strAppPath += $tempString}
    }
}
if(-not $strRegKey.Contains($strAppPath))
{
    Write-Host Program not found. Programs are case sensitive.
    break
}

[byte[]] $header = @()
$items = @{}
for($x=0; $x -lt 20; $x++)
{
    $header += $bytRegKey[$x]
}

for($x=0; $x -lt $(($bytRegKey.Count-20)/1640); $x++)
{
    [byte[]] $item=@()
    $startingByte = 20 + ($x*1640)
    $item += $bytRegKey[$($startingByte)..$($startingByte+1639)]
    $items.Add($startingByte.ToString(), $item)
}

foreach($key in $items.Keys)
{
$item = $items[$key]
    $strItem = ""
    $tempString = ""

    for($x=0; $x -le $item.Count; $x++)
    {
        $tempString = [Convert]::ToString($item[$x], 16)
        switch($tempString.Length)
        {
            0 {$strItem += "00"}
            1 {$strItem += "0" + $tempString}
            2 {$strItem += $tempString}
        }
    }
    if($strItem.Contains($strAppPath))
    {
        Write-Host Item Found with $ProgramName in item starting with byte $key
            $bytRegKey[$([Convert]::ToInt32($key)+528)] = $setting
            Set-ItemProperty $($(Get-Item 'HKCU:\Software\Classes\Local Settings\Software\Microsoft\Windows\CurrentVersion\TrayNotify').PSPath) -name IconStreams -value $bytRegKey
    }
}

Save it as a ps1 file using the name of your choice.

Open up the Group Policy Management MMC. Select your chosen Group Policy Object, right click and select Edit. In the editor, navigate to User Configuration > Windows Settings > Scripts > Logon and click "Display Properties". Go to the PowerShell tab and click View Files.

Copy the script you just made into the Explorer window that just opened and then close out of the window.

In the login script properties window, add a new PowerShell script, in the script name, enter the name of the script you used (example: NotifyIcon.ps1), and then in the parameters, enter the program name (case sensitive!) followed by the setting to use:

0 = only show notifications 1 = hide icon and notifications 2 = show icon and notifications <--- The one you need

Example, if you need the RealVNC server to always appear, you would enter:

winvnc4.exe 2

as the paramenters

You can find out the name of the executable in a couple different ways, such as opening a Run dialogue box and typing msconfig and looking at the startup programs, manually navigating to the installation directory C:\Program Files\{your program}, or trying to match the desired program by looking at the running processes in Task Manager. 9 times out of 10 this will result in success.

In order for this to work, the user must have previously run the application, and then properly logged out, so that explorer.exe gets a chance to write the updated notification area history to the Registry. On a subsequent login, the script should successfully locate the program in the history, and update its setting to always show.

You can also try running the script manually from a PowerShell prompt to debug, but you MUST kill explorer.exe (‘taskkill /f /im explorer.exe’) before running it, otherwise explorer won’t see your update, and will overwrite it when it does quit.

I take no credit for this process. I didn't write it, I just found it. Credit for the script goes to Micah Rowland. Credit for the GPO process goes to Geoff Kendal


I don't know if you can set the cache order for icons considering it could constantly be changing if new programs were added, but you can set the notification to "Always show all icon and notifications on the taskbar".

To set this to be the default, go to this registry key:

HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Explorer

Add the DWORD value "EnableAutoTray", double-click it, and set the hexadecimal value to "0".

I tested this and it worked.

Interesting note: I first tried to add it to this key:

HKEY_USERS\.DEFAULT\Software\Microsoft\Windows\CurrentVersion\Explorer

I have always thought that was the default registry for new users, but it did not work. So I went looking and found this interesting article busting my long-held thoughts about that .DEFAULT key.

http://blogs.msdn.com/b/oldnewthing/archive/2007/03/02/1786493.aspx

Addition: The best I can tell is that the registry entries are here If you were going to try and set one icon the way you would if you opened up "Control Panel\All Control Panel Items\Notification Area Icons":

HKEY_CURRENT_USER\Software\Classes\Local Settings\Software\Microsoft\Windows\CurrentVersion\TrayNotify

If you look at them, they are not very understandable, so I am not sure how well you would do editing them.

I suggest that you consider making a new user and its profile, set the "Control Panel\All Control Panel Items\Notification Area Icons" for that one icon (at least) to "Show Icon and Notifications".

Then reboot to release the profile, and log in as administrator. Copy that profile to the "C:\Users\Default" profile. You can do that either manually using Explorer, or the way we used to do it in "Control Panel\All Control Panel Items\System" "Advanced System Settings>Advanced>User Profiles>Copy to". It will be grayed out, but you can use the Windows Enabler to get around that.


Run this as admin:

Set-ItemProperty HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer EnableAutoTray 0

Notice the HKLM instead HKCU.

Verify effect with:

ps explorer | kill

It shows all icons for all profiles.


#this will grab all the SID on current user and apply across all.
Function Enable-Notifications
{
    Param
        (
        [parameter(Mandatory=$false)][string]$cpuName
        )


        if (Test-Connection $cpuName -Quiet)    
        {
Try
                {
                    $serviceName = "Remote Registry"  
                    Get-Service -ComputerName $cpuName -Name $serviceName | Start-Service
                }
                Catch
                {
                    Write-Host "Possible Error restarting $serviceName on $cpuName" -ForegroundColor Red
                }
                Try
                {
                    $root = [Microsoft.Win32.RegistryHive]::Users
                    $regKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($root, $cpuName)

                    $users = $regKey.GetSubKeyNames() | where { $_.Length -gt 10 -and $_.EndsWith("_Classes") -eq $false }
                    foreach ($usersid in $users)
                    {
                        $key = "$usersid\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer"
                        $regKey = $regKey.OpenSubKey($key, $true)
                        $regKey.SetValue("EnableAutoTray", "0", 'DWORD')
                    }
                    $ActiveUser = ([Environment]::UserDomainName + "\" + [Environment]::UserName)
                    $Time = Get-Date -format "MM-dd-yyyy @ HH:mm"
                    $WriteOut = "$ActiveUser enabled Notifcations on $cpuName at $Time"
                    $WriteOut >> "c:\scripts\Notification-Update-Enable.csv"
                    Write-Host "Enable Notifications on $cpuName" -ForegroundColor Green
                }       
                Catch
                {
                    $errormsg = $cpuName + ” is down/not responding.”
                    Write-Host $errorMsg -ForegroundColor Red
                    $errormsg >> "c:\scripts\Notification-Update-Enable_Off.csv"
                }
}
        else
        {
            Write-Host "$cpuName is Offline. Try again later." -ForegroundColor Red
            $errormsg >> "c:\scripts\Notification-Update-Enable_Off.csv"
        }
}