With recent updates, the term "Member" in the system has been changed to "User." If you still see "Member" in some parts of this help documentation, please read it as "User." For more details on this change, please refer to this announcement.
The ID logged into the device (domain) is different from the local part (the left side of the @) of the email address registered in Josys.
Script Overview
This script runs with system privileges. It retrieves the user's SID from the user profile list on the device and writes the Josys Organization ID and USERNAME to the specified Chrome and Edge registry paths in each user's HKU.
Logs are generated only when an error occurs, and they are saved to the path specified in the $logFilePath variable (in this sample, C:\Windows\Temp\Set-BrowserExtensionPolicy_Error.log).
Required Modifications Before Use
Change YOUR_ORGANIZATION_KEY_HERE in $organizationKey = "YOUR_ORGANIZATION_KEY_HERE" to your actual organization ID.
If necessary, change the folder path where the log is saved in $logFilePath = "C:\Windows\Temp\Set-BrowserPolicy_DeviceIdentity.log".
How to Use
Copy the script below, paste it into Notepad or a similar text editor, and select "Save As." Set the file extension to .ps1 and select UTF-8 (with BOM) as the character encoding.
After saving, proceed with the setup by referring to the instructions on how to distribute software using SKYSEA Client View.
*Please register the same string that will be written to the registry as the USERNAME in the binding ID (IT Device ID) for each user (employee) in Josys.
<#
.SYNOPSIS
Writes 'DeviceIdentity' and 'OrganizationKey' to ALL users (Logged on OR Logged off).
Forcefully loads NTUSER.DAT if the user is not logged in.
#>
# --- Configuration Settings ---
# Set the OrganizationKey value here (Mandatory)
$organizationKey = "YOUR_ORGANIZATION_KEY_HERE" # Change this to your actual key
# Relative registry key paths (Chrome / Edge)
$chromeRelativePath = "SOFTWARE\Policies\Google\Chrome\3rdparty\extensions\moaklgcgokbgplldonjkoochhlefkbjf\policy"
$edgeRelativePath = "SOFTWARE\Policies\Microsoft\Edge\3rdparty\extensions\hjifncajikcdkhlofdjjlhcjoennmdfc\policy"
# Log File (Always write to this file for better troubleshooting)
$logFilePath = "C:\Windows\Temp\Set-BrowserPolicy_DeviceIdentity.log"
# ------------------------------
# --- Helper Functions ---
# Logging function (outputs to console and appends to file simultaneously)
function Write-Log {
param ([string]$Message, [string]$Type = "INFO")
$timestamp = Get-Date -Format "yyyy/MM/dd HH:mm:ss"
$logEntry = "[$timestamp] [$Type] $Message"
Write-Output $logEntry
$logEntry | Out-File -FilePath $logFilePath -Encoding UTF8 -Append -ErrorAction SilentlyContinue
}
# Common function for writing to the registry
function Set-RegistryValues {
param (
[string]$BasePath, # e.g. "Registry::HKEY_USERS\S-1-5-21-..." or "Registry::HKEY_USERS\Temp_Loaded_..."
[string]$IdentityVal,
[string]$OrgKey
)
# --- Chrome ---
$fullChromePath = "$BasePath\$chromeRelativePath"
try {
if (-not (Test-Path $fullChromePath)) {
New-Item -Path $fullChromePath -Force -ErrorAction Stop | Out-Null
Write-Log " Created Chrome Key."
}
New-ItemProperty -Path $fullChromePath -Name "DeviceIdentity" -Value $IdentityVal -PropertyType String -Force -ErrorAction Stop | Out-Null
New-ItemProperty -Path $fullChromePath -Name "OrganizationKey" -Value $OrgKey -PropertyType String -Force -ErrorAction Stop | Out-Null
Write-Log " [SUCCESS] Chrome policies set."
} catch {
Write-Log " [ERROR] Failed to set Chrome policies: $($_.Exception.Message)" "ERROR"
}
# --- Edge ---
$fullEdgePath = "$BasePath\$edgeRelativePath"
try {
if (-not (Test-Path $fullEdgePath)) {
New-Item -Path $fullEdgePath -Force -ErrorAction Stop | Out-Null
Write-Log " Created Edge Key."
}
New-ItemProperty -Path $fullEdgePath -Name "DeviceIdentity" -Value $IdentityVal -PropertyType String -Force -ErrorAction Stop | Out-Null
New-ItemProperty -Path $fullEdgePath -Name "OrganizationKey" -Value $OrgKey -PropertyType String -Force -ErrorAction Stop | Out-Null
Write-Log " [SUCCESS] Edge policies set."
} catch {
Write-Log " [ERROR] Failed to set Edge policies: $($_.Exception.Message)" "ERROR"
}
}
# --- Main Script ---
# Initialize Log
"Script Started: $(Get-Date)" | Out-File -FilePath $logFilePath -Encoding UTF8 -Force
# Check Org Key
if ([string]::IsNullOrWhiteSpace($organizationKey) -or $organizationKey -eq "YOUR_ORGANIZATION_KEY_HERE") {
Write-Log "OrganizationKey is not set correctly. Exiting." "ERROR"
exit 1
}
# Get User Profiles from Registry
$profileListPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList"
$profiles = Get-ChildItem -Path $profileListPath | Where-Object { $_.PSChildName -match "^S-1-5-21|^S-1-12-1" }
if (-not $profiles) { Write-Log "No user profiles found." "WARNING"; exit }
foreach ($profile in $profiles) {
$sid = $profile.PSChildName
# Get the actual path to the user profile (e.g., C:\Users\Name)
$profilePath = (Get-ItemProperty -Path $profile.PSPath -Name ProfileImagePath).ProfileImagePath
Write-Log "--------------------------------------------------"
Write-Log "Processing SID: $sid"
# Resolve Username and determine DeviceIdentity
$identityValue = $null
try {
$objSID = New-Object System.Security.Principal.SecurityIdentifier($sid)
$objUser = $objSID.Translate([System.Security.Principal.NTAccount])
$fullUserName = $objUser.Value # DOMAIN\User
# Extract local part (DeviceIdentity)
if ($fullUserName -like "*\*") {
$identityValue = $fullUserName.Split('\')[1]
} else {
$identityValue = $fullUserName
}
Write-Log "Target User: $fullUserName / DeviceIdentity: $identityValue"
} catch {
Write-Log "Could not resolve username from SID. Skipping." "WARNING"
continue
}
# Check if Hive is currently loaded (User is Logged On)
if (Test-Path "Registry::HKEY_USERS\$sid") {
Write-Log "State: User is LOGGED ON (Hive already loaded)."
# Write directly to HKEY_USERS\<SID>
Set-RegistryValues -BasePath "Registry::HKEY_USERS\$sid" -IdentityVal $identityValue -OrgKey $organizationKey
} else {
Write-Log "State: User is LOGGED OFF (Hive NOT loaded)."
# Prepare to Load Hive
$ntUserDat = "$profilePath\NTUSER.DAT"
if (-not (Test-Path $ntUserDat)) {
Write-Log "Critical: NTUSER.DAT not found at $ntUserDat. Skipping." "ERROR"
continue
}
$tempHiveName = "Temp_Load_$sid"
# Load Hive using reg.exe (More reliable than PowerShell provider for loading)
Write-Log "Attempting to load hive to HKEY_USERS\$tempHiveName..."
$regLoadArgs = "load", "HKU\$tempHiveName", "`"$ntUserDat`""
$p = Start-Process -FilePath "reg.exe" -ArgumentList $regLoadArgs -Wait -NoNewWindow -PassThru
if ($p.ExitCode -eq 0) {
Write-Log "Hive loaded successfully."
# Write to the temporary location
Set-RegistryValues -BasePath "Registry::HKEY_USERS\$tempHiveName" -IdentityVal $identityValue -OrgKey $organizationKey
# Force Garbage Collection to release file handles before unloading
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()
# Unload Hive
Write-Log "Unloading hive..."
$regUnloadArgs = "unload", "HKU\$tempHiveName"
Start-Process -FilePath "reg.exe" -ArgumentList $regUnloadArgs -Wait -NoNewWindow | Out-Null
} else {
Write-Log "Failed to load hive. Exit Code: $($p.ExitCode). EDR might be blocking 'reg load'." "ERROR"
}
}
}
Write-Log "Script Finished."