I'm attempting to use a PowerShell script to uninstall a VPN application (GlobalProtect) through Intune as a Win32 app. When I run the script manually, it works perfectly, but once uploaded to Intune, it fails with an error indicating that a specific registry path cannot be found: HKLM:SOFTWAREPalo Alto NetworksGlobalProtectSettingsabc.com. I'm confused about what might be causing this issue. Here's the script I'm using:
```powershell
# Define log file path
$logfile = "$env:ProgramDataGlobalProtect_Uninstall_Log.txt"
# Function to log messages
function Log-Message {
param([string]$message)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
Add-Content -Path $logfile -Value "$timestamp - $message"
}
# Start logging
Log-Message "Starting GlobalProtect uninstall script."
Log-Message "Running under architecture: $env:PROCESSOR_ARCHITECTURE"
# Define registry paths to check (64-bit + 32-bit views)
$regPaths = @(
"HKLM:SOFTWAREPalo Alto NetworksGlobalProtectSettingsabc.com",
"HKLM:SOFTWAREWow6432NodePalo Alto NetworksGlobalProtectSettingsabc.com"
)
$keyName = "Uninstall"
# Try each registry path
$foundPath = $false
foreach ($regPath in $regPaths) {
if (Test-Path $regPath) {
$foundPath = $true
Log-Message "Checking registry path: $regPath"
try {
$UninstallValue = Get-ItemProperty -Path $regPath -Name $keyName -ErrorAction Stop | Select-Object -ExpandProperty $keyName
Log-Message "Current Uninstall value: $UninstallValue"
if ($UninstallValue -eq 2) {
Set-ItemProperty -Path $regPath -Name $keyName -Value 0 -ErrorAction Stop
Log-Message "Changed Uninstall value from 2 to 0."
} else {
Log-Message "Uninstall value is not 2. No change made."
}
}
catch {
Log-Message "Error accessing or modifying registry at $regPath: $_"
exit 1
}
break
} else {
Log-Message "Registry path not found: $regPath"
}
}
if (-not $foundPath) {
Log-Message "No valid registry path found. Exiting script."
exit 1
}
# Attempt to uninstall GlobalProtect using WMI
try {
$gpApp = Get-WmiObject -Class Win32_Product | Where-Object { $_.Name -like "*GlobalProtect*" }
if ($gpApp) {
Log-Message "Found GlobalProtect: $($gpApp.Name)"
$result = $gpApp.Uninstall()
if ($result.ReturnValue -eq 0) {
Log-Message "GlobalProtect uninstalled successfully via WMI."
} else {
Log-Message "GlobalProtect uninstall failed with return code: $($result.ReturnValue)"
exit 1
}
} else {
Log-Message "GlobalProtect not found in installed products."
}
}
catch {
Log-Message "Error during WMI uninstall: $_"
exit 1
}
```
3 Answers
Just a heads up, PowerShell scripts executed as a Win32 app are running in a 32-bit environment by default. That means registry calls you make go to Wow6432Node, which is likely why you're not getting the results you expect. I usually run PowerShell onto Sysnative like this: %SystemRoot%sysnativeWindowsPowerShellv1.0powershell.exe. Check this out for further info: https://call4cloud.nl/sysnative-64-bit-ime-intune-syswow64-wow6432node/.
Have you considered just pushing the installation with specific parameters to uninstall instead? You can make it mandatory or optional based on user scope. It's just a thought; maybe I'm being naive here.
From my experience, when I run this locally, the script detects the HKLM:SoftwarePalo... path, but not the HKLM:SoftwareWow6432Node... path. There are a lot of references suggesting that when running from Intune, some HKLM:Software... paths actually redirect to HKLM:SoftwareWow6432Node due to 32/64-bit mismatches. You might want to test this by creating a 'Test' property in HKLM:SoftwareWow6432NodeMicrosoft and run a PowerShell query from Intune to check if it retrieves that property.
Thanks for the insight! I'll give that a shot.