PassThru not working when using SYSTEM account or script location issue?

This topic contains 3 replies, has 2 voices, and was last updated by Profile photo of Justin King Justin King 11 months ago.

  • Author
    Posts
  • #33456
    Profile photo of Jeff
    Jeff
    Participant

    I have a script that works completely fine when running as admin, locally on a PC. However, when running as SYSTEM (via SCCM package), The exit codes are not being returned from Start-Process. When it shows Exit Code: 0 on my machine, it shows Exit Code: and has various other failures for the installs (not actual powershell errors, but it does not seem to be working as it should. Here is an example of the code I have:

    Try {
        "Installing Flash ActiveX" | Out-File $log -Append -Force
        $InstallActiveX = start-process "msiexec.exe" `
                        -arg "/I install_flash_player_20_active_x.msi /qn /norestart" `
                        -Wait -ea stop -PassThru -NoNewWindow
        $ExitCode = $InstallActiveX.ExitCode | Out-String
        $ExitCode = $ExitCode.Trim()
    }
    Catch {
          "Error: $($_.Exception.Message)" | Out-File $log -Force -Append
          "Error Code: $ExitCode" | Out-File $log -Force -Append
    }
    Finally {
            "Exit Code: $ExitCode" | Out-File $log -Force -Append
    }
    

    The files get copied to their SCCM cached location and then the script runs and executes the files locally under the system account. Why is this behaving completely different then when I run it locally on my machine? Do I have to reference the path of the location for the script instead of just using

    start-process "msiexec.exe" -arg "/I install_flash_player_20_active_x.msi /qn /norestart"

    ?
    I have a feeling it is not even running the msi files.

    Here is the command line that is used to run the package: powershell.exe -nologo -noprofile -noninteractive -File .\FlashRemediation.ps1

  • #33457
    Profile photo of Justin King
    Justin King
    Participant

    I've got a powershell script for pretty much the exact same thing, the only difference is I actually call the current path up to make sure it can find the installer which may help you. Essential the path is always in the context of where the script is running this way:

    #Set Install Variables
    $Application = '\setup\awesomeinstaller.exe'
    $Arguments = '/silent  /Variable "blah blah" /otherstuff'
    
    #If PSVersion is too early, generate $PSScriptRoot variable
    If (!$PSScriptRoot) {
    	$PSSCriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent
        }
    
    #Try the Install and return results
    Try {
        $AppFullPath = $PSScriptRoot+'\'+$Application
        start-process -FilePath $AppFullPath -ArgumentList $Arguments -wait
        }
    Catch {
        Write-Error -Message $_
        Exit 1
        }
    Exit 0
    

    Been using it for a few years and just tweaking the top two variables per package.

  • #33458
    Profile photo of Jeff
    Jeff
    Participant

    Added

    $dir = Split-Path $MyInvocation.MyCommand.Path
    
    Try {
        "Installing Flash Plugin" | Out-File $log -Append -Force
        $InstallPlugin = start-process "msiexec.exe" -arg "/I $dir\install_flash_player_20_plugin.msi /qn /norestart" -Wait -ea stop -PassThru -NoNewWindow
        $ExitCode = $InstallPlugin.ExitCode | Out-String
        $ExitCode = $ExitCode.Trim()
    }
    Catch {
          "Error: $($_.Exception.Message)" | Out-File $log -Force -Append
          "Error Code: $ExitCode" | Out-File $log -Force -Append
    }
    Finally {
            "Exit Code: $ExitCode" | Out-File $log -Force -Append
    }
    

    So I basically added in the variable for $dir and added it to the path for the MSI. That look about right? Seems to be working locally at least. Weird part is, I have another uninstall that doesn't even use a local MSI, but just an uninstall string that is found in the registry and I still receive Exit Code: (null). It is not even trying to grab anything in the same directory as the script so I'm not sure why I would get a blank exit code for that as well (only with SCCM script package, not local):

     
    ForEach ($app in $FlashApps) {
    
            If ($app.UninstallString) {
                Try {
                    $uninstall = $app.UninstallString -Replace "msiexec.exe","" -Replace "/I","" -Replace "/X",""
                    $uninstall = $uninstall.Trim()
                    "FlashUtil32 or FlashUtil64 doesn't exist - Uninstalling $($app.DisplayName)" | Out-File $log -Force -Append
                    $UninstallActiveX = start-process "msiexec.exe" -arg "/X $uninstall /qn /norestart" -Wait -PassThru -ea stop -NoNewWindow
                    $ExitCode = $UninstallActiveX.ExitCode | Out-String
                    $ExitCode = $ExitCode.Trim()
                    }
                Catch {
                      "Error: $($_.Exception.Message)" | Out-File $log -Force -Append
                      "Error Code: $ExitCode" | Out-File $log -Force -Append
                }
                Finally {
                        "Exit Code: $ExitCode" | Out-File $log -Force -Append
                }
            }
        }
    
  • #33459
    Profile photo of Justin King
    Justin King
    Participant

    Well something of note when playing in the world of SCCM: just because SCCM expects an expect code 0, doesn't mean it will get one from the installer. That's why I deliberately end my install script with Exit 0 because at the end of the day: you can't trust everyone to write their .msi the same way.

    Also, II'd highly recommend you grab psexec so you can open up a command prompt in the system context for testing your scripts (as that's what SCCM will run under).

    We are kind of "beyond PS" honestly as you admited it runs fine in the user context. This reads more like understanding the ccmcache directory and context that the SCCM Agent runs under.

You must be logged in to reply to this topic.