#requires -version 2 <# .SYNOPSIS The script is inspired by a blog article 'https://svdbusse.github.io/SemiAnnualChat/2019/09/14/User-Interactive-Win32-Intune-App-Deployment-with-PSAppDeployToolkit.html' which describes its idea and presents simpler code version. .DESCRIPTION The script is used for conditional deployment option interactive if requires the user's action (to save work and close interrupting processes) or noninteractive if user interaction is not needed to proceed. .PARAMETER -DeploymentType Specifies the deployment type Install|Uninstall|Repair Required? false Position? 0 Default value Install Accept pipeline input? false Accept wildcard characters? false .PARAMETER -ProcessToCheck Specifies the phrase used to search applications Required? true Position? 2 Default value Accept pipeline input? false Accept wildcard characters? .PARAMETER <CommonParameters> This cmdlet supports the common parameters: -Verbose, -Debug, -ErrorAction, -ErrorVariable, -WarningAction, -WarningVariable, -OutBuffer and -OutVariable. For more information, type "get-help about_commonparameters". .INPUTS DeploymentType .OUTPUTS .NOTES Version: 2.2 Author: Karol Kula Creation Date: 03.03.2024 Purpose/Change: Obtain exit codes from started processes. Version: 2.1 Author: Karol Kula Creation Date: 28.11.2023 Purpose/Change: Adding the possibility to input more than one process into the ProcessToCheck parameter. Version: 2.0 Author: Karol Kula Creation Date: 17.11.2023 Purpose/Change: Replacement of ServiceUI.exe with Psexec64.exe. I decided to include logging with Start-Transcript and more details with Write-Output Version: 1.2 Author: Karol Kula Creation Date: 11.10.2023 Purpose/Change: Fix formatting issues and, add string validation to the ProcessToCheck parameter. Insert the link reference that inspired me to create this script. Version: 1.0 Author: Karol Kula Creation Date: 11.10.2023 Purpose/Change: Initial script development .EXAMPLE powershell.exe -executionpolicy bypass -file .\Invoke64bitPS.ps1 -ScriptName "Condition.ps1" -ArgumentList "-ProcessToCheck 'chrome.exe'" -Runs as 64-bit process script Condition.ps1 to check if the process chrome.exe is running to start deploy (install) .EXAMPLE powershell.exe -executionpolicy bypass -file .\Invoke64bitPS.ps1 -ScriptName "Condition.ps1" -ArgumentList "-DeploymentType Uninstall -ProcessToCheck '7zFM.exe'" -Runs as 64-bit process script Condition.ps1 to check if the process 7zFM.exe is running to start deployment (uninstall) .EXAMPLE powershell.exe -executionpolicy bypass -file .\Invoke64bitPS.ps1 -ScriptName "Condition.ps1" -Arguments "-DeploymentType Uninstall -ProcessToCheck 'Acrobat.exe,AcroRd32.exe'" -Runs as 64-bit process script Condition.ps1 to check if the processes Acrobat.exe or AcroRd32.exe are running to start deployment (uninstall) #> [CmdletBinding()] Param ( [Parameter(Mandatory = $false)] [ValidateSet('Install', 'Uninstall', 'Repair')] [String]$DeploymentType = 'Install', [Parameter(Mandatory = $true)] [String]$ProcessToCheck ) $DateTimeStamp = $(Get-Date -format '_HH-mm_ddMMyyyy') Start-Transcript "C:\ProgramData\Microsoft\IntuneManagementExtension\Logs\Condition-$($ProcessToCheck.Split('.')[0])$DateTimeStamp.log" if ($ProcessToCheck -match ',') { Write-Output "There is more than one process to check" $ArrayOfProcesses = @() $ArrayOfProcesses += @($ProcessToCheck.Split(',')) } Else{ $ArrayOfProcesses = @($ProcessToCheck) } $ProcessNames = @() Foreach($item in $ArrayOfProcesses){ if ($item -match '"') { $item = $item.Replace('"', '') $ProcessNames += "'" + $item.replace(' ','') + "'" } Elseif ($item -match "'") { $item = $item.Replace("'", '') $ProcessNames += "'" + $item.replace(' ','') + "'" } Else { $ProcessNames += "'" + $item.replace(' ','') + "'" } } Write-Output "Current directory: $PSScriptRoot" if ($pwd -ne $PSScriptRoot) { Set-Location $PSScriptRoot } $LoggedOnUser = (Get-WmiObject -Class win32_computersystem).UserName $Is64bit = [Environment]::Is64BitProcess Write-Output "Is 64-bit process? $Is64bit" Write-Output $LoggedOnUser $DAppExe = Test-Path $PSScriptRoot\Deploy-Application.exe Write-Output "Is Deploy-Application present? $DAppExe" $ExplorerSessionID = (Get-Process explorer -IncludeUserName | Where-Object { $_.UserName -eq $LoggedOnUser } | Select-Object -Last 1).SessionID Write-Output "Session ID for explorer is: $ExplorerSessionID" $targetprocesses = @() Foreach ($ProcessName in $ProcessNames) { $targetprocesses += @(Get-WmiObject -Query "Select * FROM Win32_Process WHERE Name=$ProcessName" -ErrorAction SilentlyContinue) } if ($targetprocesses.Count -eq 0) { Try { Write-Output "No interrupting process is running. Starting to deploy your application without ServiceUI" if ($DeploymentType -ne 'Uninstall' -and $DeploymentType -ne 'Repair') { Write-Output "Trying to start deployment type install with Deploy-Application.exe in NonInteractive mode" $Process = Start-Process .\Deploy-Application.exe -ArgumentList '-DeployMode NonInteractive' -ErrorAction Stop -PassThru -Wait } Elseif ($DeploymentType -eq 'Uninstall'){ Write-Output "Trying to start deployment type uninstall with Deploy-Application.exe in NonInteractive mode" $Process = Start-Process .\Deploy-Application.exe -ArgumentList '-DeploymentType Uninstall -DeployMode NonInteractive' -ErrorAction Stop -PassThru -Wait } Else { Write-Output "Trying to start deployment type repair with Deploy-Application.exe in NonInteractive mode" $Process = Start-Process .\Deploy-Application.exe -ArgumentList '-DeploymentType Repair -DeployMode NonInteractive' -ErrorAction Stop -PassThru -Wait } } Catch { $ErrorMessage = $_.Exception.Message Write-Output $ErrorMessage } } else { Foreach ($targetprocess in $targetprocesses) { $ProcessOwner = $targetprocess.GetOwner().User $TargetProcessName = $targetprocess.Name Write-output "Interrupting process $TargetProcessName is running by $ProcessOwner, Starting to deploy your application with Psexec." } Try { if ($DeploymentType -ne 'Uninstall' -and $DeploymentType -ne 'Repair') { Write-Output "Trying to start deployment type install with Deploy-Application.exe in Interactive mode" $Process = .\Psexec64.exe -accepteula -si $ExplorerSessionID $PSScriptRoot\Deploy-Application.exe } Elseif ($DeploymentType -eq 'Uninstall') { Write-Output "Trying to start deployment type uninstall with Deploy-Application.exe in Interactive mode" $Process = .\Psexec64.exe -accepteula -si $ExplorerSessionID $PSScriptRoot\Deploy-Application.exe Uninstall } Else { Write-Output "Trying to start deployment type repair with Deploy-Application.exe in Interactive mode" $Process = .\Psexec64.exe -accepteula -si $ExplorerSessionID $PSScriptRoot\Deploy-Application.exe Repair } } Catch { $ErrorMessage = $_.Exception.Message Write-Output $ErrorMessage } } Write-Output "Install Exit Code = $($Process.ExitCode)" Stop-Transcript Exit $($Process.ExitCode)