Skip to content

Instantly share code, notes, and snippets.

@skarllot
Last active March 20, 2026 00:47
Show Gist options
  • Select an option

  • Save skarllot/d7732d0cb87268967bb038af717fb122 to your computer and use it in GitHub Desktop.

Select an option

Save skarllot/d7732d0cb87268967bb038af717fb122 to your computer and use it in GitHub Desktop.
Sets the profile picture for a Microsoft Edge profile - irm https://tinyurl.com/Set-EdgeProfileImage | iex
<#
.SYNOPSIS
Sets the profile picture for a Microsoft Edge profile.
.DESCRIPTION
This script replaces the profile picture (Edge Profile Picture.png) for a chosen
Edge profile, including resizing the image to 424x424 px and updating the
Local State JSON so Edge renders the new picture.
The script:
- Checks if Edge is running (exits if it is)
- Prompts for the source image path
- Lists all Edge profiles and prompts for selection
- Creates automatic backups in your home directory
- Resizes the source image to 424x424 using high-quality bicubic interpolation
- Copies the resized image as the profile picture
- Updates Local State: use_gaia_picture, is_using_new_placeholder_avatar_icon,
gaia_picture_file_name
- Provides rollback instructions if needed
.EXAMPLE
.\Set-EdgeProfileImage.ps1
Runs the script fully interactively, prompting for the image path and profile.
.NOTES
Version: 1.1
IMPORTANT: Close Microsoft Edge completely before running this script.
Backups are created automatically in: $env:USERPROFILE\EdgeProfileImageBackup_[timestamp]\
#>
[CmdletBinding()]
param()
$ErrorActionPreference = 'Stop'
#region Helper Functions
function Write-ColorMessage {
param(
[string]$Message,
[ValidateSet('Success','Error','Info','Warning')]
[string]$Type = 'Info'
)
$color = switch ($Type) {
'Success' { 'Green' }
'Error' { 'Red' }
'Warning' { 'Yellow' }
'Info' { 'Cyan' }
}
Write-Host $Message -ForegroundColor $color
}
function Test-EdgeRunning {
$edgeProcesses = Get-Process -Name 'msedge' -ErrorAction SilentlyContinue
return ($null -ne $edgeProcesses)
}
function Get-EdgeUserDataPath {
return "$env:LOCALAPPDATA\Microsoft\Edge\User Data"
}
function Get-EdgeProfiles {
$userDataPath = Get-EdgeUserDataPath
$localStatePath = Join-Path $userDataPath 'Local State'
if (-not (Test-Path $localStatePath)) {
throw "Edge Local State file not found at: $localStatePath"
}
$utf8 = [System.Text.UTF8Encoding]::new($false)
$localState = [System.IO.File]::ReadAllText($localStatePath, $utf8) | ConvertFrom-Json
$profiles = @()
foreach ($profileKey in $localState.profile.info_cache.PSObject.Properties.Name) {
$profileData = $localState.profile.info_cache.$profileKey
$picturePath = Join-Path $userDataPath "$profileKey\Edge Profile Picture.png"
$hasPicture = Test-Path $picturePath
$profiles += [PSCustomObject]@{
Key = $profileKey
Name = $profileData.name
AccountEmail = $profileData.user_name
HasPicture = $hasPicture
}
}
return $profiles
}
function Show-ProfileList {
param([array]$Profiles)
Write-ColorMessage "`nAvailable Edge Profiles:" -Type Info
Write-Host ("=" * 80)
for ($i = 0; $i -lt $Profiles.Count; $i++) {
$profile = $Profiles[$i]
$pictureStatus = if ($profile.HasPicture) { '[Has Picture]' } else { '[No Picture]' }
$pictureColor = if ($profile.HasPicture) { 'Green' } else { 'Gray' }
Write-Host ("{0,3}. " -f ($i + 1)) -NoNewline
Write-Host ("{0,-20} " -f $profile.Key) -NoNewline -ForegroundColor White
Write-Host ("{0,-25} " -f $profile.Name) -NoNewline
Write-Host ("{0,-15}" -f $pictureStatus) -ForegroundColor $pictureColor
if ($profile.AccountEmail) {
Write-Host (" Account: {0}" -f $profile.AccountEmail) -ForegroundColor Gray
}
}
Write-Host ("=" * 80)
}
function New-BackupDirectory {
$timestamp = Get-Date -Format 'yyyyMMdd_HHmmss'
$backupPath = Join-Path $env:USERPROFILE "EdgeProfileImageBackup_$timestamp"
if (-not (Test-Path $backupPath)) {
New-Item -ItemType Directory -Path $backupPath -Force | Out-Null
}
return $backupPath
}
function Backup-ProfileFiles {
param(
[string]$ProfileKey,
[string]$BackupPath
)
$userDataPath = Get-EdgeUserDataPath
# Backup Local State
$localStatePath = Join-Path $userDataPath 'Local State'
$localStateBackup = Join-Path $BackupPath 'Local State'
Copy-Item $localStatePath $localStateBackup -Force
Write-ColorMessage " [✓] Backed up: Local State" -Type Success
# Backup existing profile picture (if present)
$picturePath = Join-Path $userDataPath "$ProfileKey\Edge Profile Picture.png"
if (Test-Path $picturePath) {
$profileBackupDir = Join-Path $BackupPath $ProfileKey
New-Item -ItemType Directory -Path $profileBackupDir -Force | Out-Null
$pictureBackup = Join-Path $profileBackupDir 'Edge Profile Picture.png'
Copy-Item $picturePath $pictureBackup -Force
Write-ColorMessage " [✓] Backed up: $ProfileKey\Edge Profile Picture.png" -Type Success
}
return $true
}
function Invoke-ImageResize {
param(
[string]$SourcePath,
[string]$DestPath
)
Add-Type -AssemblyName 'System.Drawing'
$src = $null
$dst = $null
$g = $null
try {
$src = [System.Drawing.Bitmap]::new($SourcePath)
$dst = [System.Drawing.Bitmap]::new(424, 424)
$g = [System.Drawing.Graphics]::FromImage($dst)
$g.InterpolationMode = [System.Drawing.Drawing2D.InterpolationMode]::HighQualityBicubic
$g.SmoothingMode = [System.Drawing.Drawing2D.SmoothingMode]::HighQuality
$g.PixelOffsetMode = [System.Drawing.Drawing2D.PixelOffsetMode]::HighQuality
$g.DrawImage($src, 0, 0, 424, 424)
$dst.Save($DestPath, [System.Drawing.Imaging.ImageFormat]::Png)
Write-ColorMessage " [✓] Image resized to 424x424 px" -Type Success
} catch {
Write-ColorMessage " [!] Resize failed ($($_.Exception.Message)); copying original instead" -Type Warning
Copy-Item $SourcePath $DestPath -Force
} finally {
if ($g) { $g.Dispose() }
if ($dst) { $dst.Dispose() }
if ($src) { $src.Dispose() }
}
}
function Set-ProfilePicture {
param(
[string]$ProfileKey,
[string]$ResizedImagePath
)
$userDataPath = Get-EdgeUserDataPath
$localStatePath = Join-Path $userDataPath 'Local State'
$destPicture = Join-Path $userDataPath "$ProfileKey\Edge Profile Picture.png"
# Copy resized image to profile directory
Copy-Item $ResizedImagePath $destPicture -Force
Write-ColorMessage " [✓] Profile picture written to: $destPicture" -Type Success
# Update Local State (UTF-8 no-BOM to preserve Unicode characters)
$utf8 = [System.Text.UTF8Encoding]::new($false)
$json = [System.IO.File]::ReadAllText($localStatePath, $utf8) | ConvertFrom-Json
$entry = $json.profile.info_cache.$ProfileKey
$entry.use_gaia_picture = $true
$entry.is_using_new_placeholder_avatar_icon = $false
if (-not ($entry.PSObject.Properties.Name -contains 'gaia_picture_file_name')) {
$entry | Add-Member -MemberType NoteProperty -Name 'gaia_picture_file_name' -Value 'Edge Profile Picture.png'
} else {
$entry.gaia_picture_file_name = 'Edge Profile Picture.png'
}
[System.IO.File]::WriteAllText($localStatePath, ($json | ConvertTo-Json -Depth 100 -Compress), $utf8)
Write-ColorMessage " [✓] Local State updated (use_gaia_picture, gaia_picture_file_name)" -Type Success
}
function Show-RollbackInstructions {
param(
[string]$BackupPath,
[string]$ProfileKey
)
Write-Host "`n"
Write-ColorMessage "=== ROLLBACK INSTRUCTIONS ===" -Type Warning
Write-Host "If you need to undo these changes, run the following commands in PowerShell:"
Write-Host ""
Write-Host " `$backupPath = '$BackupPath'" -ForegroundColor Gray
Write-Host " `$userDataPath = '$(Get-EdgeUserDataPath)'" -ForegroundColor Gray
Write-Host ""
Write-Host " # Close Edge first, then restore:" -ForegroundColor Gray
Write-Host " Copy-Item (Join-Path `$backupPath 'Local State') `$userDataPath -Force" -ForegroundColor Cyan
Write-Host " `$picBackup = Join-Path `$backupPath '$ProfileKey\Edge Profile Picture.png'" -ForegroundColor Cyan
Write-Host " if (Test-Path `$picBackup) { Copy-Item `$picBackup (Join-Path `$userDataPath '$ProfileKey') -Force }" -ForegroundColor Cyan
Write-Host ""
}
#endregion
#region Main Script
try {
Write-Host "`n"
Write-ColorMessage "╔═══════════════════════════════════════════════════════════════╗" -Type Info
Write-ColorMessage "║ Edge Profile Image Setter ║" -Type Info
Write-ColorMessage "╚═══════════════════════════════════════════════════════════════╝" -Type Info
Write-Host "`n"
# Step 1: Prompt for source image path
Write-ColorMessage "[1/7] Source Image" -Type Info
Write-Host "Enter the path to the image file (PNG, JPEG, BMP, GIF, or TIFF): " -NoNewline -ForegroundColor Yellow
$ImagePath = Read-Host
if ([string]::IsNullOrWhiteSpace($ImagePath)) {
Write-ColorMessage "[ERROR] No image path provided." -Type Error
exit 1
}
# Strip surrounding quotes the user may have pasted from Explorer
$ImagePath = $ImagePath.Trim('"').Trim("'")
if (-not (Test-Path $ImagePath)) {
Write-ColorMessage "[ERROR] Source image not found: $ImagePath" -Type Error
exit 1
}
$validExtensions = @('.png', '.jpg', '.jpeg', '.bmp', '.gif', '.tiff', '.tif')
$ext = [System.IO.Path]::GetExtension($ImagePath).ToLower()
if ($ext -notin $validExtensions) {
Write-ColorMessage "[ERROR] Unsupported image format '$ext'. Use: PNG, JPEG, BMP, GIF, TIFF" -Type Error
exit 1
}
Write-ColorMessage " [✓] Source image: $ImagePath" -Type Success
# Step 2 (2/7): Check if Edge is running
Write-ColorMessage "`n[2/7] Checking if Microsoft Edge is running..." -Type Info
if (Test-EdgeRunning) {
Write-ColorMessage "`n[ERROR] Microsoft Edge is currently running!" -Type Error
Write-Host "`nPlease close all Edge windows and try again." -ForegroundColor Yellow
Write-Host "To close Edge completely:"
Write-Host " 1. Close all Edge windows"
Write-Host " 2. Check system tray for Edge icon and quit it"
Write-Host " 3. Or run: Stop-Process -Name msedge -Force"
exit 1
}
Write-ColorMessage " [✓] Edge is not running" -Type Success
# Step 3 (3/7): Get and display profiles
Write-ColorMessage "`n[3/7] Loading Edge profiles..." -Type Info
$profiles = Get-EdgeProfiles
if ($profiles.Count -eq 0) {
Write-ColorMessage "[ERROR] No Edge profiles found!" -Type Error
exit 1
}
Write-ColorMessage " [✓] Found $($profiles.Count) profile(s)" -Type Success
# Step 4 (4/7): Select profile
Show-ProfileList -Profiles $profiles
Write-Host "`nEnter the number of the profile to update (or 'q' to quit): " -NoNewline -ForegroundColor Yellow
$selection = Read-Host
if ($selection -eq 'q') {
Write-ColorMessage "`nOperation cancelled by user." -Type Warning
exit 0
}
$index = [int]$selection - 1
if ($index -lt 0 -or $index -ge $profiles.Count) {
Write-ColorMessage "`n[ERROR] Invalid selection!" -Type Error
exit 1
}
$selectedProfile = $profiles[$index]
Write-Host "`n"
Write-ColorMessage "[5/7] Selected Profile:" -Type Info
Write-Host " Name: $($selectedProfile.Name)" -ForegroundColor White
Write-Host " Key: $($selectedProfile.Key)" -ForegroundColor Gray
Write-Host " Has Picture: $($selectedProfile.HasPicture)" -ForegroundColor $(if ($selectedProfile.HasPicture) { 'Green' } else { 'Gray' })
# Confirm
Write-Host "`nThis will replace the profile picture for '$($selectedProfile.Name)'."
Write-Host "Do you want to continue? (y/N): " -NoNewline -ForegroundColor Yellow
$confirm = Read-Host
if ($confirm -ne 'y') {
Write-ColorMessage "`nOperation cancelled by user." -Type Warning
exit 0
}
# Step 5 (6/7): Create backups
Write-ColorMessage "`n[6/7] Creating backups..." -Type Info
$backupPath = New-BackupDirectory
Write-ColorMessage " Backup location: $backupPath" -Type Info
Backup-ProfileFiles -ProfileKey $selectedProfile.Key -BackupPath $backupPath
# Step 6 (7/7): Apply image changes
Write-ColorMessage "`n[7/7] Applying image changes..." -Type Info
$tempResized = Join-Path $env:TEMP "EdgeProfilePicture_resized_$(Get-Date -Format 'yyyyMMddHHmmss').png"
try {
Invoke-ImageResize -SourcePath $ImagePath -DestPath $tempResized
Set-ProfilePicture -ProfileKey $selectedProfile.Key -ResizedImagePath $tempResized
} finally {
if (Test-Path $tempResized) { Remove-Item $tempResized -Force -ErrorAction SilentlyContinue }
}
# Verification
Write-ColorMessage "`nVerifying changes..." -Type Info
$userDataPath = Get-EdgeUserDataPath
$utf8 = [System.Text.UTF8Encoding]::new($false)
$localState = [System.IO.File]::ReadAllText((Join-Path $userDataPath 'Local State'), $utf8) | ConvertFrom-Json
$entry = $localState.profile.info_cache.($selectedProfile.Key)
if ($entry.use_gaia_picture -eq $true) {
Write-ColorMessage " [✓] use_gaia_picture = true" -Type Success
} else {
Write-ColorMessage " [!] use_gaia_picture is not true" -Type Warning
}
$picturePath = Join-Path $userDataPath "$($selectedProfile.Key)\Edge Profile Picture.png"
if (Test-Path $picturePath) {
Write-ColorMessage " [✓] Edge Profile Picture.png exists in profile directory" -Type Success
} else {
Write-ColorMessage " [!] Edge Profile Picture.png not found in profile directory" -Type Warning
}
# Success summary
Write-Host "`n"
Write-ColorMessage "╔═══════════════════════════════════════════════════════════════╗" -Type Success
Write-ColorMessage "║ SUCCESS! Profile image updated ║" -Type Success
Write-ColorMessage "╚═══════════════════════════════════════════════════════════════╝" -Type Success
Write-Host "`n"
Write-ColorMessage "Next steps:" -Type Info
Write-Host " 1. Open Microsoft Edge with the '$($selectedProfile.Name)' profile"
Write-Host " 2. Check the profile icon (top-right) or edge://settings/profiles"
Write-Host "`n"
Write-ColorMessage "Backup location: $backupPath" -Type Info
Show-RollbackInstructions -BackupPath $backupPath -ProfileKey $selectedProfile.Key
} catch {
Write-Host "`n"
Write-ColorMessage "╔═══════════════════════════════════════════════════════════════╗" -Type Error
Write-ColorMessage "║ ERROR OCCURRED ║" -Type Error
Write-ColorMessage "╚═══════════════════════════════════════════════════════════════╝" -Type Error
Write-Host "`n"
Write-ColorMessage "Error: $($_.Exception.Message)" -Type Error
Write-Host "`nStack Trace:" -ForegroundColor Gray
Write-Host $_.ScriptStackTrace -ForegroundColor Gray
if ($backupPath -and (Test-Path $backupPath)) {
Write-Host "`n"
Write-ColorMessage "Backups were created at: $backupPath" -Type Warning
Write-ColorMessage "You can use these to restore if needed." -Type Warning
}
exit 1
}
#endregion
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment