PSADT as a Intune Win32app says it already installed and skips it

The PrinterLogic Printer Installer Client app uses the same ProductCode GUID for all versions of their installers, but they do use different ProductVersion for each version. The PSADT works great when run by itself as admin. It stops processes, stops the spooler service, uninstalls any older version with Remove-MSIApplications, removes registry keys and files, starts the spooler service; and installs the new version.
However, when I wrap it as .intunewin file, and run the install from Intune the PSADT log file say:

[Installation] :: The MSI is already installed on this system. Skipping action [Install]ā€¦ Execute-MSI 9/12/2022 11:00:41 AM 30412 (0x76CC)

--------------------------------- my code ------------------------------------

Show-InstallationWelcome -CloseApps 'PrinterInstallerClientLauncher,PrinterInstallerClient,PrinterInstallerClientInterface,PrinterInstaller_MicrosoftMigrator' -Silent

IF (Test-Path -Path "HKLM:\SOFTWARE\PrinterLogic") {
Stop-ServiceAndDependencies -Name 'Spooler'
Remove-MSIApplications -Name 'Printer Installer Client' 
Remove-Folder -Path "$Env:ProgramFiles (x86)\Printer Properties Pro"
Remove-Folder -Path "$Env:windir\Temp\data"
Remove-Folder -Path "$Env:windir\Temp\PPP"
Start-Sleep -Seconds "2"
IF (Test-Path -Path 'HKLM:\SOFTWARE\PrinterLogic' ) {
Remove-RegistryKey -Key "HKLM:\SOFTWARE\PrinterLogic" -Recurse}
Start-ServiceAndDependencies -Name 'Spooler'
}

Execute-MSI -Action 'Install' -Path 'PrinterInstallerClient.msi' -AddParameters "HOMEURL=https://uaw.printercloud.com AUTHORIZATION_CODE=1fr0gqpk"

I now see that my 2nd IF is redundant, but it should work in Intune if it works by itself as local administrator?

Question: Are there any other parameters that I could use with Execute-MSI so it would also work with Intune?

Maybe try
Execute-MSI -Action Uninstall -Path '<ProductCodeGUID>' -ContinueOnError $False

Thank you for the suggestion. I need to use Remove-MSIApplications to remove different version, and some that I donā€™t know about. Also, when running in Intune it quits before getting to Remove-MSIApplions. But when I run it independently of Intune it works.

Stop-ServiceAndDependencies is a PSADT function so it should have logged what happened when it tried to stop the Spooler service. Maybe it canā€™t or needs more time. Check PSADTā€™s log file.

Also, is Printer Installer Client installed in the user profile or in Program Files?

Unfortunately, Stop-ServiceAndDependencies is not in the PSADT Log file.
I will compare the log when it works by itself, and when it fails within Intune. I can add more logging with Write-Log.

It is Installed in ā€˜C:\Program Files (x86)\Printer Properties Pro\Printer Installer Clientā€™

1 Like

Thank you @That-Annoying-Guy for giving me the clue to uncover a Bug (in either Intune or the PSADT) and get it working in Intune. Intune was never evaluating the IF statement because there is a bug where it fails to detect the existence of a Registry Key when ran from Intune as a Win32app (but works when run by itself), and never uninstalled the old version.

I modified the IF statement and discovered that testing for the existence of a Registry Key in Intune doesnā€™t work. However, testing for testing the existence of the File Path in Intune does work.

For example, this works:
IF (Test-Path -Path "C:\Program Files (x86)\Printer Properties Pro") {

While this fails which I believe is a bug in either Intune or the PSADT:
IF (Test-Path -Path "HKLM:\SOFTWARE\PrinterLogic") {

This code now works:

IF (Test-Path -Path "C:\Program Files (x86)\Printer Properties Pro") {
Stop-ServiceAndDependencies -Name 'Spooler'
Remove-MSIApplications -Name 'Printer Installer Client'
Remove-Folder -Path "$Env:ProgramFiles (x86)\Printer Properties Pro"
Remove-Folder -Path "$Env:windir\Temp\data"
Remove-Folder -Path "$Env:windir\Temp\PPP"
Remove-RegistryKey -Key "HKLM:\SOFTWARE\PrinterLogic" -Recurse
Start-ServiceAndDependencies -Name 'Spooler'
}

Execute-MSI -Action 'Install' -Path 'PrinterInstallerClient.msi' -AddParameters "HOMEURL=https://uaw.printercloud.com AUTHORIZATION_CODE=1fr0gqpk"  

I have a case open with Microsoft and I will continue to pursue it to determine if the bug is with Intuneā€¦

Or by chance @That-Annoying-Guy have you seen this behavior before?

The following will tell you ā€œhowā€ Microsoft is executing/bootstrapping the script on the endpoint.

Add it to your script somewhere and review your PSADT installation script log.

I somehow suspect you could be running into 32-bit process on 64-bit operating system which adds some complexity when dealing with paths and variables because of Windows File System Redirection. That is only if Win32Intune is in fact running as a 32-Bit process. The execution context will also be ā€œSYSTEMā€ and not a local administrator which is an entirely different can of worms.

#region Log Process Information
#Log process properties to the log for easier troubleshooting of how the process was launched
  $DateTimeLogFormat = 'dddd, MMMM dd, yyyy hh:mm:ss tt'

  $CurrentProcessProperties = [System.Diagnostics.Process]::GetCurrentProcess()
  $CurrentProcessAdvancedProperties = Get-CIMInstance -ClassName "Win32_Process" -Filter "ProcessID = `'$($CurrentProcessProperties.ID)`'"

  $LogMessage = "Process ID: $($CurrentProcessAdvancedProperties.ProcessId)"
  Write-Log -Message $LogMessage -Severity 2 -LogType CMTrace -Source "GetCurrentProcessInfo" -ContinueOnError:$True

  $LogMessage = "Is 64-Bit Process: $([System.Environment]::Is64BitProcess)"
  Write-Log -Message $LogMessage -Severity 2 -LogType CMTrace -Source "GetCurrentProcessInfo" -ContinueOnError:$True

  $LogMessage = "Process Command Line: $($CurrentProcessAdvancedProperties.CommandLine)"
  Write-Log -Message $LogMessage -Severity 2 -LogType CMTrace -Source "GetCurrentProcessInfo" -ContinueOnError:$True

  $LogMessage = "Process Execution Context: $([Security.Principal.WindowsIdentity]::GetCurrent().Name)"
  Write-Log -Message $LogMessage -Severity 2 -LogType CMTrace -Source "GetCurrentProcessInfo" -ContinueOnError:$True

  $LogMessage = "Is Process Elevated: $((Get-AdministrativePrivilege).ToString())"
  Write-Log -Message $LogMessage -Severity 2 -LogType CMTrace -Source "GetCurrentProcessInfo" -ContinueOnError:$True

  $LogMessage = "Process Start Time: $($CurrentProcessAdvancedProperties.CreationDate.ToString($DateTimeLogFormat))"
  Write-Log -Message $LogMessage -Severity 2 -LogType CMTrace -Source "GetCurrentProcessInfo" -ContinueOnError:$True
#endregion

Lastly,

This could be blowing up

"$Env:ProgramFiles (x86)\Printer Properties Pro" should be "$(${env:ProgramFiles(x86)})\Printer Properties Pro"

I wrote a little code block so that you can remove folders in a loop only if they exist! Keeps the editing down.

$FolderList = New-Object -TypeName 'System.Collections.Generic.List[System.IO.DirectoryInfo]'
  $FolderList.Add("$(${env:ProgramFiles(x86)})\Printer Properties Pro")
#$FolderList.Add("Add Another Folder Here")

ForEach ($Folder In $FolderList)
  {
      Switch ([System.IO.Directory]::Exists($Folder.FullName))
        {
            {($_ -eq $True)}
              {
                  Remove-Folder -Path ($Folder.FullName) -ContinueOnError:$True
              }

            Default
              {
                  ###Folder does not exist and does not require removal
              }
        }
  }

Also, Get-InstalledApplication is useful to check to see if the application is there before you attempt to remove it.

 [Regex]$SoftwareDetectionExpression = '(.*YourFirstApp.*)|(.*YourSecondApp.*)'
  
  $SoftwareDetectionList = Get-InstalledApplication -Name ($SoftwareDetectionExpression) -RegEx

  ForEach ($SoftwareDetection In $SoftwareDetectionList)
    {
        $SoftwareDetection

        <#
            Do stuff with the uninstall string or product code of your software
        
            Test Conditions

            Execute-MSI
            Execute-Process

            Welcome to dynamic software removal, no need to know every product code in advance!
        #>     
    }

Hope this helps!

PS - Sorry about the code formatting, I could not get it correct when pasting into the post.

1 Like

Hi @alphaeus, I think you are on to something with the 32-bit process on 64-bit operating system. When wrapped as a *.intunewin file and ran from Intune, Iā€™m not able to access this registry key to delete it or use it in Test-Path:
HKLM:\SOFTWARE\PrinterLogic

I have tried both:
Remove-RegistryKey -Key "HKLM:\SOFTWARE\PrinterLogic" -Recurse
and
Remove-Item -Path "HKLM:\SOFTWARE\PrinterLogic" -Recurse -Force -ErrorAction 'SilentlyContinue'

I shall add your code to the Deploy-Application.ps1 at the beginning of the
##_ <Perform Pre-Installation tasks here>
section and review the PSADT logfile.

Thank you for the suggestion.

@alphaeus Iā€™m getting an error thatā€™s causing the script to fail because this cmdlet doesnā€™t seem to exist:
Get-AdministrativePrivilege

The cmtrace log file says:

 Error Record:
-------------At C:\WINDOWS\IMECache\75f361cf-6a9f-4688-a6c1-34c4a9da2d3e_8\Deploy-Application.ps1:146 char:42
+ ... essage = "Is Process Elevated: $((Get-AdministrativePrivilege).ToStri ...

Iā€™m going to research it and see if I can add it in some how, or remark it outā€¦

yea, just comment that out.

1 Like

Yup, looks like Microsoft is doing some under the hood magic to jam everything inā€¦get used to it. I pasted the function you needed to get the process elevation status. Sorry, I forgot it the first time.

#region Function Get-AdministrativePrivilege
Function Get-AdministrativePrivilege
{
$Identity = [System.Security.Principal.WindowsIdentity]::GetCurrent()
$Principal = New-Object System.Security.Principal.WindowsPrincipal($Identity)
Write-Output -InputObject ($Principal.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator))
}
#endregion

1 Like

Thank you @alphaeus, I added the function, wrapped it as .intunewin file, and here is what the log said:
[Pre-Installation] :: Unable to delete registry key [Registry::HKEY_LOCAL_MACHINE\SOFTWARE\PrinterLogic] because it does not exist.

But the key does exist and its spelled correctly, very stranageā€¦

Other lines highlighed in yellow say:

[Pre-Installation] :: Process ID: 624
[Pre-Installation] :: Is 64-Bit Process: False
[Pre-Installation] :: Process Command Line: PowerShell.exe -ExecutionPolicy Bypass -File ".\Deploy-Application.ps1" -DeploymentType "Install" -DeployMode "Silent"
[Pre-Installation] :: Process Execution Context: NT AUTHORITY\SYSTEM

Just fyi, I used 3 back ticks ``` one line above, and one line below to help format the code :wink:

That is 64 bit process being false is the culprit!

Microsoft is launching powershell as a 32bit process on a 64 bit operating system, that completely changes the execution environment and explains why the process cannot ā€œseeā€ that registry path.

Does intune allow you to specify the command line?

If so, try explicity pointing to the native 64 bit powershell.

C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe

Try to variabalize the path if possible.

Lets start with that.

Right now based on your command line in the log, the path to powershell.exe is being resolved based on the architecture of the calling process.

Send me a pm, if you are comfortable with that, all of this will be easier talking over Zoom/Teams/Phone and take less time.

1 Like

I tried this in Intune:

%windir%\System32\WindowsPowershell\v1.0\powershell.exe -ExecutionPolicy Bypass -File ".\Deploy-Application.ps1" -DeploymentType "Install" -DeployMode "Silent"

But still got:

[Pre-Installation] :: Is 64-Bit Process: False
[Pre-Installation] :: Process Command Line: C:\WINDOWS\System32\WindowsPowershell\v1.0\powershell.exe -ExecutionPolicy Bypass -File ".\Deploy-Application.ps1" -DeploymentType "Install" -DeployMode "Silent"
[Pre-Installation] :: Process Execution Context: NT AUTHORITY\SYSTEM	GetCurrentProcessInfo	9/24/2022 12:16:00 AM	23000 (0x59D8)

[Pre-Installation] :: Unable to delete registry key [Registry::HKEY_LOCAL_MACHINE\SOFTWARE\PrinterLogic] because it does not exist.

Strangeā€¦

One more variation, the link above explains it.

Apparently, Microsoft knows about this and it is a
larger issue.

Try the following in Intune

ā€œ%systemroot%\sysnative\Remaining Path to powershell exeā€ Any Remaining Parameters

1 Like

Alphaeus, That Worked!!!
Thank you for your Outstanding Assistance with this little known feature sysnative to solve the WoW64 (Windows 32-bit on Windows 64-bit) system redirection challenges for the registry.

I swapped out System32 with sysnative in the command line at:

%windir%\sysnative\WindowsPowershell\v1.0\powershell.exe -ExecutionPolicy Bypass -File ".\Deploy-Application.ps1" -DeploymentType "Install" -DeployMode "Silent"

And everything worked as it should with the PSADT log file reading:

[Initialization] :: Is 64-Bit Process: True
[Initialization] :: Process Command Line: C:\WINDOWS\sysnative\WindowsPowershell\v1.0\powershell.exe -ExecutionPolicy Bypass -File ".\Deploy-Application.ps1" -DeploymentType "Uninstall" -DeployMode "Silent"
[Initialization] :: Process Execution Context: NT AUTHORITY\SYSTEM

I also found value in these posts:

best regards, Kurt

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.