Update script questions

This topic contains 3 replies, has 2 voices, and was last updated by Profile photo of Don Jones Don Jones 1 year, 9 months ago.

  • Author
    Posts
  • #22850
    Profile photo of ertuu85
    ertuu85
    Participant

    I'm looking to write a script that can install against a repository of Windows updates. It will be a mixture of .msu and .exe, which may have different switches for installs (/q vs /quiet etc).

    Below is a script I've used in the past and wanted to modify it. The $exit variable is later put into a switch that tells what the error code is.

    The .msu's seem to be pretty standard and I don't seem to run into issues with them, but the .exe's seem to have some different switches. Such as some have /q but missing /norestart and then fail due to parameter's being incorrect. Is there a better more thorough way to do it than I am below?

    Or is there a way to do like:

    patch.exe -> fails in the else statement because it does not hav ethe /norestart -> moves to different statement that only checks for /q

    Any advice would be greately appreciated.

    $from = "C:\Patches"  #put your file path here!
    
    $updates = @(Get-ChildItem -Path $from | where{$_.name -like '*.exe' -or $_.name -like '*.msu'} | foreach{$_.name})
    if ($updates.Count -ge 1 ) 
    {
    	foreach($update in $updates)
    	{
    		if($update -like "*.msu")
    		{
    			Write-Host "Processing update $update."
    			$exit = ((Start-Process -FilePath "$from\$update" -ArgumentList "/quiet /passive /norestart" -Wait -passthru).ExitCode)
    		}
    		else
    		{
    			Write-Host "Processing update $update."
    			$exit=((Start-Process -FilePath "$from\$update" -ArgumentList "/q /norestart" -Wait -passthru).ExitCode)
    		}
           }
    }
    
  • #22851
    Profile photo of Don Jones
    Don Jones
    Keymaster

    With EXEs you're really limited to what the package author came up with. Because they don't run under PowerShell (it shells out to Cmd.exe), you're even limited in what you can capture. So what you're doing in terms of grabbing the $exit is probably the best you can do. Sucks, right?

    BTW, Write-Host, ew. Consider Write-Verbose and save a puppy.

    You could certainly build out the logic you're suggesting. After you run the EXE, have another If construct that checks $exit and runs the command with only /q, grabbing its exit code. If there's only these couple of variations, that's probably the way to go. If you start getting into... "well, there's four ways to do this, and I'd like to try them all until one succeeds," it might be more elegant to use a slightly different approach.

  • #22858
    Profile photo of ertuu85
    ertuu85
    Participant

    Thanks for the response, I think I might have something figured out.

    Whats the real difference between write-host and write-verbose?

    I also just opened ps and tried a write-verbose -message "hi" and noticed it didnt write to screen...am I using it incorrectly?

  • #22860
    Profile photo of Don Jones
    Don Jones
    Keymaster

    Write-Host draws directly to the screen; it can't be captured or redirected. That's why it's generally a poor practice; if your script ran in a non-console host, you wouldn't necessarily be able to capture that output into, say, a log.

    The Verbose pipeline is better, but it's off by default. Your script can set $VerbosePreference='Continue' to enable it, although if you're using a [CmdletBinding()] Param block, your script gains an automatic -Verbose switch that enables verbose output. That's why it's kind of a part of best practices – use a Param() block, add [CmdletBinding()], use Write-Verbose, Write-Warning, etc.

You must be logged in to reply to this topic.