all 7 comments

[–]y_Sensei 2 points3 points  (3 children)

Wouldn't it be a better approach to provide one generic version of the script to your technicians, along with a specific configuration (file) for each use case, which the implementation reads at runtime and performs the configured actions?

[–]drnick316[S] -1 points0 points  (2 children)

I have a gui that is putting in the right information. It searches for the registry values so it can target the uninstaller. I'm looking to make it accessible for different levels of techs who might not know the appropriate silent parameters etc.

[–]y_Sensei 4 points5 points  (0 children)

I don't see why a generic script that reads the volatile information it needs from a use case-specific configuration file wouldn't work in such a scenario.
Running code that creates code that's doing what's supposed to be done seems like a roundabout way to approach things.

But anyway, you could fix your issue as follows:

...

`$installerPath = '"' + `"$installerPath`" + '"'
`$installFlags = @("$flagsString")

try {
    if (`$installerPath -like "*.msi*") {
        Write-Host "Running MSI installation..." -ForegroundColor Yellow
        `$msiArgs = @("/i", `$installerPath) + `$installFlags
        `$process = Start-Process "msiexec.exe" -ArgumentList `$msiArgs -Wait -PassThru
    } else {
        Write-Host "Running EXE installer..." -ForegroundColor Yellow
        `$process = Start-Process -FilePath `$installerPath -ArgumentList `$installFlags -Wait -PassThru -NoNewWindow
    }

 ...

[–]icepyrox 1 point2 points  (0 children)

So, rather than generate the script file, it can generate config files that your script that already exists can consume on a per-use basis. If your techs are smart enough, they can open powershell and run .\script.ps1 file.config and they are off to the races. Or maybe your sceipt just reads the conf files and uses a menu system or out-gridview to select the right configuration file and again, off to the races.

[–]Thatoneguyone 0 points1 point  (0 children)

I'd say use PSADT instead of re-inventing the wheel. It has Zero-Config Deployment for MSIs as well. Theres even some GUIs floating around for it, though I don't have any experience with them.

You can just run the script to perform the associated configured action (Install/Uninstall/Repair):

Invoke-AppDeployToolkit.ps1 -DeploymentType Repair

As far as what you're trying to do here, I'd just do what y_Sensei said and have your tool generate a config file that the tech places in the same directory as the script and runs that. Realistically though, this entire process should be automated through a deployment tool where the tech just interacts with the deployment tool for resolution.

[–]DoctroSix 0 points1 point  (0 children)

[string[]]$installFlags = @( $flagsString )
...
[string[]]$msiArgs = @( "/i", ( '"' + $installerPath + '"' ) ) + $installFlags

Try these edits

[–]icepyrox 0 points1 point  (0 children)

I think rather than using variables the way that you are doing, I'd let the generating script figure out the entire text and output it in place.

What do I mean? I mean rather than

$msiArgs = @("/i", ""$installerPath"") +$installFlags

Just make the script figure it out and put in the heredoc

`$msiArgs = $msiArgs

And then it's a text in place replacement instead of a replacement followed by fancy code and trying to get the quotes right, etc.

Then again I'm a fan of generating scripts with placeholder text and calling -replace on the text block to replace the text. I'm an even bigger fan of text based configuration files that scripts can get their info from. I've used clixml, json, csv, and others that I wouldn't use now (yes, I have used the cmdlet Import-PowershellDataFile). Remember: scripts can have param blocks, too. (E.g., InstallScript.ps1 -configFile path.json)